3

Ok sorry for asking pretty much the same question again but I've tried many methods and I still can't do what I'm trying to do and I'm not even sure it's possible with opencv alone. I have rotated an image and I want to copy it inside another image. The problem is that no matter what way I crop this rotated image it always copies inside this second image with a non rotated square around it. As can be seen in the image below.(Forget the white part thats ok). I just want to remove the striped part. I believe my problem is with my ROI that I copy the image to as this ROI is a rect and not a RotatedRect. As can be seen in the code below.

cv::Rect roi(Pt1.x, Pt1.y, ImageAd.cols, ImageAd.rows);
ImageAd.copyTo(ImageABC(roi));

But I can't copyTo with a rotatedRect like in the code below...

cv::RotatedRect roi(cent, sizeroi, angled);
ImageAd.copyTo(ImageABC(roi));

So is there a way of doing what I want in opencv? Thanks!

enter image description here

After using method below with masks I get this image which as seen is cut off by the roi in which I use to say where in the image I want to copy my rotated image. Basically now that I've masked the image, how can I select where to put this masked image into my second image. At the moment I use a rect but that won't work as my image is no longer a rect but a rotated rect. Look at the code to see how I wrongly do it at the moment (it cuts off and if I make the rect bigger an exception is thrown).

cv::Rect roi(Pt1.x, Pt1.y, creditcardimg.cols, creditcardimg.rows); 
        creditcardimg.copyTo(imagetocopyto(roi),mask);

enter image description here

enter image description here

OneTwo
  • 2,291
  • 6
  • 33
  • 55
  • 1
    do you want to copy from or to a rotated rect? The idea of using the mask is: 1. source is the rotated image. 2. rotated rect builds the roi inside that rotated image. 3. create a mask that looks like the rotated rect. 4. copy only using that mask. 5. result is an image where only the pixel in the rotated rect are visible with black background. – Micka Apr 01 '14 at 14:02
  • Kind of both because after working out the mask for the image I want to copy, I also want to place this image (only the mask bits) into another image. Now the issue is how can I specify in copyTo the coordinates of where I want to place this rotated and masked image. If I use a rect roi it will just be placed inside another non rotated rectangle which doesn't really help. – OneTwo Apr 01 '14 at 14:40
  • What was wrong with [this solution](http://stackoverflow.com/questions/22662971/insert-a-rotated-and-skewed-image-into-a-detected-rectangle-in-another-image-wit/22681411#22681411) to your previous question ? – BConic Apr 01 '14 at 15:37
  • My destination corners are detected and do not form a perfect rectangle. So I will not have corresponding corners to insert into getPerspectiveTransform. – OneTwo Apr 01 '14 at 15:41
  • @Fionn I still dont get whether you want to rotate the rect while copying or whether you want to copy as it is, but only the roi (which is a rotated rect) – Micka Apr 01 '14 at 16:35

1 Answers1

5

Instead of ROI you can use mask to copy,

  1. First create mask using rotated rect.

  2. Copy your source image to destination image using this mask

See below C++ code

Your rotated rect and I calculated manually.

RotatedRect rRect = RotatedRect(Point2f(140,115),Size2f(115,80),192);

Create mask using draw contour.

   Point2f vertices[4];
   rRect.points(vertices);
   Mat mask(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
   vector< vector<Point> >  co_ordinates;
   co_ordinates.push_back(vector<Point>());
   co_ordinates[0].push_back(vertices[0]);
   co_ordinates[0].push_back(vertices[1]);
   co_ordinates[0].push_back(vertices[2]);
   co_ordinates[0].push_back(vertices[3]);
   drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

Finally copy source to destination using above mask.

    Mat dst;
    src.copyTo(dst,mask);

enter image description here enter image description here

Haris
  • 13,645
  • 12
  • 90
  • 121
  • Ok thanks, so I create a mask containing only the points inside the rotatedRect and then I use `Mat::copyTo(OutputArray m, InputArray mask)` to copy to the image? – OneTwo Apr 01 '14 at 13:19
  • Thanks but it doesn't work. The output image doesn't contain any of the pixels from the image I want to copy to. As in the pic above. – OneTwo Apr 01 '14 at 13:50
  • Ok so I do exactly as you do above except instead of having an empty dst as you do I have an another image in which to copy this rotated image to. So your mask does work (I tried using just an empty dst) but in order to copy to this image I need to specify where to copy to. So before I just used a rect roi as in my code above. So after working out the correct mask I run this code `cv::Rect roi(Pt1.x, Pt1.y, creditcardimg.cols, creditcardimg.rows); creditcardimg.copyTo(imagetocopyto(roi),mask);` But this doesn't work probably because the roi is a rectangle and not a rotated rectangle – OneTwo Apr 01 '14 at 14:34
  • So you need to align your mask first, according to destination position you had right ? – Haris Apr 01 '14 at 15:15
  • @Fionn Also see the answer here http://stackoverflow.com/questions/22315904/blending-does-not-remove-seams-in-opencv/22318347#22318347 where I used some offset to align mask correctly using ROI. – Haris Apr 01 '14 at 15:21
  • I don't think the problem is about aligning the mask, it's about inserting these pixels selected by the mask (which form a rotated rectangle) into an image at a given point Pt1. The only way, as far as I can see, of doing this is to maskedpixelsimage.copyTo(dstImage(Rectangle ROI)), but this won't work as the maskedpixelImage isn't a rectangle and so certain parts of it will be cut of when they lie outside this roi. (As in the image above, don't mind the badly masked part thats a different problem I can fix, just look where it is cut of only in a small way). – OneTwo Apr 01 '14 at 15:24
  • I think better to post your original images. – Haris Apr 01 '14 at 16:22
  • @Fionn you can use cv::boundingRect function to get a 'bb' in the mask image. Create another rect of same size and wanted location in dst img and call 'img(bb).copyTo(dst(otherbb), mask(bb))' - sorry for no formatting on smartphone... – Micka Apr 01 '14 at 16:40