14

I am using opencv and I want to create an image from a part of another image.

I didn't find a function that do that so I try to implement my Idea which consist of copying the image pixel by pixel but in vain I didn't get the result I am waiting for.

Any one has another Idea

Code:

#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

int main(int argc,char** argv) {
  IplImage * img =0;

  uchar *data;
  int i,j,k;
  int height,width,widthStep,nChannels;
  img=cvLoadImage(argv[1],3);
  height =img->height;
  width = img->width;
  widthStep= img->widthStep;
  nChannels = img->nChannels;
  data=(uchar*)img->imageData;
  IplImage* img1=cvCreateImage(cvSize(height/2,width/2),IPL_DEPTH_8U,nChannels);
  for(i=0;i<height/2;i++){
    for(j=0;j<width/2;j++){
      for(k=0;k<3;k++){
        img1->imageData[i*widthStep+j*nChannels]=data[i*widthStep+j*nChannels];
      }
    }
  }
  cvShowImage("image_Originale2",img1);
  cvWaitKey(0);
  cvReleaseImage(&img);
  return 0;
}
karlphillip
  • 92,053
  • 36
  • 243
  • 426
Wadii Slatnia
  • 183
  • 1
  • 4
  • 10

4 Answers4

34

You should use cv::Mat's copy constructor. It's much better than IplImage:

int x = 10,
    y = 20, 
    width = 200,
    height = 200;

Mat img1, img2;
img1 = imread("Lenna.png");
img2 = img1(Rect(x, y, width, height));
LihO
  • 41,190
  • 11
  • 99
  • 167
Froyo
  • 17,947
  • 8
  • 45
  • 73
  • 2
    It's not better by definition, it's different; legacy OpenCV versus the 'new' C++ api. Indeed, but old IplImage stuff will be depreciated in OpenCV 3, and I advise everyone who reads this to switch to the new cv::Mat style. – TimZaman Mar 02 '14 at 11:06
9

What you are trying to accomplish can be done by setting a ROI (Region of Interest) on that image and copying that portion defined by the ROI to a new image.

You can see a demo using IplImage on this post.

These posts show uses of ROI to solve different scenarios:

It's important to note that your code is using the C interface of OpenCV. The C++ interface offers cv::Mat, which is the equivalent of IplImage. In other words, what you are looking for is a C solution to the problem.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
5

Using copy constructor :

cv::Mat whole = ...; // from imread or anything else
cv::Mat part(
   whole,
   cv::Range( 20, 220 ), // rows
   cv::Range( 10, 210 ));// cols
Aerospace
  • 1,270
  • 12
  • 19
2

Look up the cvSetImageROI() function.

Sets an image Region Of Interest (ROI) for a given rectangle.

Bono
  • 4,757
  • 6
  • 48
  • 77
Boyko Perfanov
  • 3,007
  • 18
  • 34