14

I have two images, the first one smaller than the other. I need to copy the second image on the first image. To do so, I need to set the ROI on the first one, copy the second image onto the first one and then reset the ROI.

However I am using the C++ interface so I have no idea how to do this. In C I could have used cvSetImageROI but this doesn't work on the C++ interface.

So basically whats the C++ alternative to cvSetImageROI?

//output is a pointer to the mat whom I want the second image (colourMiniBinMask) copied upon
Rect ROI (478, 359, 160, 120);

Mat imageROI (*output, ROI);

colourMiniBinMask.copyTo (imageROI);

imshow ("Gravity", *output);
fdh
  • 5,256
  • 13
  • 58
  • 101
  • 3
    See http://stackoverflow.com/questions/7041181/equivalent-to-cvsetimageroi-in-the-opencv-c-interface – Tyler Hyndman Nov 21 '11 at 02:07
  • I tried that already. I don't get any errors, but the image I set the ROI on isn't affected - it stays the same. I am just getting a copy of that portion of the image rather than access to it. (I think). – fdh Nov 21 '11 at 22:11
  • copyTo function will recreate the content if src and dst matrices' format does not match (i.e. src=BGR, dst=BGRA). If this is the case "imageROI.data" will be reallocated and you'll see that the address of the pointer will be changed. On the other hand, header of imageROI will stay the same. Use mixChannels, merge or cvtColor functions on such cases. – vahapt Jul 08 '12 at 20:25

2 Answers2

17

I think you have something wrong. If the first one is smaller than the other one and you want to copy the second image in the first one, you don't need an ROI. You can just resize the second image in copy it into the first one.

However if you want to copy the first one in the second one, I think this code should work:

cv::Rect roi = cv::Rect((img2.cols - img1.cols)/2,(img2.rows - img1.rows)/2,img1.cols,img1.rows);

cv::Mat roiImg;
roiImg = img2(roi);

img1.copyTo(roiImg);
Showpath
  • 678
  • 1
  • 8
  • 18
  • 4
    or shorter: Mat roiImg(img2, roi); – Ben Nov 22 '11 at 14:08
  • Sorry I mean the second image is smaller than the first and I want to copy the second to the first. I tried out your code, but it doesn't work. Image 1 (the image I whose ROI I want changed) is not changed at all. I included my code in my question above. Any other suggestions? – fdh Nov 23 '11 at 00:20
3

This is the code I used. I think the comments explain it.

/* ROI by creating mask for the parallelogram */
Mat mask = cvCreateMat(480, 640, CV_8UC1);
// Create black image with the same size as the original
for(int i=0; i<mask.cols; i++)
   for(int j=0; j<mask.rows; j++)
       mask.at<uchar>(Point(i,j)) = 0;

// Create Polygon from vertices
vector<Point> approxedRectangle;
approxPolyDP(rectangleVertices, approxedRectangle, 1.0, true);

// Fill polygon white
fillConvexPoly(mask, &approxedRectangle[0], approxedRectangle.size(), 255, 8, 0);                 

// Create new image for result storage
Mat imageDest = cvCreateMat(480, 640, CV_8UC3);

// Cut out ROI and store it in imageDest
image->copyTo(imageDest, mask);

I also wrote about this and put some pictures here.

Pieter-Jan
  • 450
  • 5
  • 9