Question

I would like to replace a part of the image with my image in Opencv

I used

cvGetPerspectiveMatrix() with a warpmatrix and using cvAnd() and cvOr()

but could not get it to work

This is the code that is currently displaying the image and a white polygon for the replacement image. I would like to replace the white polygon for a pic with any dimension to be scaled and replaced with the region pointed.

While the code is in javacv I could convert it to java even if c code is posted

grabber.start();
while(isDisp() && (image=grabber.grab())!=null){
  if (dst_corners !=  null) {// corners of the image to be replaced
  CvPoint points = new CvPoint((byte) 0,dst_corners,0,dst_corners.length);
  cvFillConvexPoly(image,points, 4, CvScalar.WHITE, 1, 0);//white polygon covering the replacement image 
  }
correspondFrame.showImage(image);
}

Any pointers to this will be very helpful.

Update:

I used warpmatrix with this code and I get a black spot for the overlay image

cvSetImageROI(image, cvRect(x1,y1, overlay.width(), overlay.height()));
CvPoint2D32f p = new CvPoint2D32f(4);
CvPoint2D32f q = new CvPoint2D32f(4);

q.position(0).x(0);
q.position(0).y(0);
q.position(1).x((float) overlay.width());
q.position(1).y(0);
q.position(2).x((float) overlay.width());
q.position(2).y((float) overlay.height());
q.position(3).x(0);
q.position(3).y((float) overlay.height());

p.position(0).x((int)Math.round(dst_corners[0]);
p.position(0).y((int)Math.round(dst_corners[1]));
p.position(1).x((int)Math.round(dst_corners[2]));
p.position(1).y((int)Math.round(dst_corners[3]));
p.position(3).x((int)Math.round(dst_corners[4]));
p.position(3).y((int)Math.round(dst_corners[5]));
p.position(2).x((int)Math.round(dst_corners[6]));
p.position(2).y((int)Math.round(dst_corners[7]));

cvGetPerspectiveTransform(q, p, warp_matrix);

cvWarpPerspective(overlay, image, warp_matrix);

I get a black spot for the overlay image and even though the original image is a polygon with 4 vertices the overlay image is set as a rectangle. I believe this is because of the ROI. Could anyone please tell me how to fit the image as is and also why I am getting a black spot instead of the overlay image.

Was it helpful?

Solution

I think cvWarpPerspective(link) is what you are looking for.

So instead of doing

CvPoint points = new CvPoint((byte) 0,dst_corners,0,dst_corners.length);
cvFillConvexPoly(image,points, 4, CvScalar.WHITE, 1, 0);//white polygon covering the replacement image

Try

cvWarpPerspective(yourimage, image, M, image.size(), INTER_CUBIC, BORDER_TRANSPARENT);

Where M is the matrix you get from cvGetPerspectiveMatrix

OTHER TIPS

One way to do it is to scale the pic to the white polygon size and then copy it to the grabbed image setting its Region of Interest (here is a link explaining the ROI). Your code should look like this:

resize(pic, resizedImage, resizedImage.size(), 0, 0, interpolation); //resizedImage should have the points size
cvSetImageROI(image, cvRect(the points coordinates));
cvCopy(resizedImage,image);
cvResetImageROI(image);

I hope that helps.

Best regards, Daniel

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top