copying non-rectangular roi opencv

MMH picture MMH · Feb 28, 2014 · Viewed 13.7k times · Source

I want to copy a part of an image which is not rectangle with C++ opencv. The corner points of the part is known in the image. I want to paste it in a another image in exact location. Can anybody please help me?

The source image and the destination image are of same size.

here is an example of source image, I know p1,p2,p3,p4 and I want to copy that part to a new image.enter image description here

I already have a destination image. For example the below image is destination image, and I want to paste only the marked part of the source image to the destination image. How can I do it?enter image description here

And the final output should look something like this one.enter image description here

Thanks,

Answer

Haris picture Haris · Feb 28, 2014
  1. First create a mask image using your four co-ordinates.

  2. Now using Mat::copyTo() copy your balck image to source here you can use above mask.

Allocate black image and mask as source size

Mat src=imread("img.png",1);
Mat black(src.rows, src.cols, src.type(), cv::Scalar::all(0));
Mat mask(src.rows, src.cols, CV_8UC1, cv::Scalar(0));

Now create mask image using drawContours, here you should use CV_FILLED for contour thickness.

Like

   vector< vector<Point> >  co_ordinates;
   co_ordinates.push_back(vector<Point>());
   co_ordinates[0].push_back(P1);
   co_ordinates[0].push_back(P2);
   co_ordinates[0].push_back(P3);
   co_ordinates[0].push_back(P4);
   drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

Finally copy black image to source using above mask

black.copyTo(src,mask);  

See below result,

enter image description here

Edit :

Based on your comment below here is the steps you need to follow

  1. First create Mask image as described above

  2. Copy the the source image to new Mat dst1 using the mask.

  3. Invert your mask and copy destination image to a new Mat dst2

  4. For final result just add up dest1 and dest2 to new Mat.

    Suppose you already created mask as above

    Copy source to new Mat

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

Now invert Mask and copy destination image to new Mat

Mat dst2;
bitwise_not(mask,mask);
dst.copyTo(dst2,mask);

Get final result by adding both

Mat result=dest1+dest2;

In case your both image are of different size then you can use following code

Here you should use image ROI for copy, create mask etc..

![Mat src=imread("src.png",1);
Mat dst=imread("dest.jpg",1);
int new_w=0;
int new_h=0;
if(src.cols>dst.cols)
 new_w=dst.cols;
else
 new_w=src.cols;

if(src.rows>dst.rows)
 new_h=dst.rows;
else
 new_h=src.rows;

Rect rectROI(0,0,new_w,new_h);
Mat mask(new_h, new_w, CV_8UC1, cv::Scalar(0));

Point P1(107,41);
Point P2(507,61);
Point P3(495,280);
Point P4(110,253);
vector< vector<Point> >  co_ordinates;
co_ordinates.push_back(vector<Point>());

co_ordinates\[0\].push_back(P1);
co_ordinates\[0\].push_back(P2);
co_ordinates\[0\].push_back(P3);
co_ordinates\[0\].push_back(P4);
drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

Mat srcROI=src(rectROI);
Mat dstROI=dst(rectROI);
Mat dst1;
Mat dst2;

srcROI.copyTo(dst1,mask);
imwrite("dst1.jpg",dst1);

bitwise_not(mask,mask);
dstROI.copyTo(dst2,mask);

dstROI.setTo(0);
dstROI=dst1+dst2;
imshow("final result",dst);][4]

enter image description here