Ask Your Question

How to replace a certain ROI with another image?

asked 2013-04-04 01:45:02 -0500

wytmoon gravatar image

updated 2013-04-04 04:15:04 -0500


I am making a simple app that was built from the face detection sample of the OpenCv4Android SDK. Basically my goal is to overlay or replace the detected face with another image like a smiley or a face of a dog, etc.

I tried to use copyTo(Mat dest) where dest is a submat of the entire image (basically the detected face region) and the Mat from which copyTo is called is the image to overlay or replace. This doesn't work though.

Can someone provide alternatives? Or maybe my understanding of copyTo is wrong? Hoping for some advice. Thanks and best regards,

CODE THAT I USE - for clarity -

Mat capturedImage = Highgui.imread(<path/to/captured/image>) 
Mat selectedArea = capturedImage.submat(mDetectedFace) //mDetectedFace is a Rect object 
Mat replaceImage = Highgui.imread(<path/to/replacement/image>)

Highgui.imwrite(<path/to/save/directory>, capturedImage)
edit retag flag offensive close merge delete


do you want to superimpose an image over the face?

pocahentez gravatar imagepocahentez ( 2013-04-04 04:35:03 -0500 )edit

@pocahentez did you even read the other posts? I think it is very clear that he wants to segment the face and replace it with another image. This could be seen as superimposing yes.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-04 04:40:19 -0500 )edit

you can be inspired from this project :
this project allows to detect the eyes and insert images of fire there. it's not a java code.

pocahentez gravatar imagepocahentez ( 2013-04-04 05:11:54 -0500 )edit

How to find the mDetected rect object from the detected face... please anyone help to solve it.

Asha gravatar imageAsha ( 2015-01-31 10:50:02 -0500 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2013-04-04 01:49:31 -0500

Basically the answers to my own question will solve your problem. You have to be sure that you use the copyTo statements correctly.

Basically you need to do the following:

blue_channel.copyTo( result_channel( Rect(0, 0, cols, rows) ) );
green_channel.copyTo( result_channel( Rect(cols, 0, cols, rows) ) );
red_channel.copyTo( result_channel( Rect(cols*2, 0, cols, rows) ) );

Where the blue/green/red channels would be your image that you want to place over the face. The result image is the frame you grab and the rect region of interest is the bounding box your algorithm dumps.

However, this is the C++ interface that is used. Hope this suits your problem.

edit flag offensive delete link more



Thanks for the quick reply Steven but I think that's what I have been doing.

 Mat capturedImage = Highgui.imread(&lt;path/to/captured/image&gt;)
 Mat selectedArea = capturedImage.submat(mDetectedFace) //mDetectedFace is a Rect object
 Mat replaceImage = Highgui.imread(&lt;path/to/replacement/image&gt;)

 Highgui.imwrite(&lt;path/to/save/directory&gt;, capturedImage)

But nothing happens. The picture is as it is. The replacement image was not copied to the selected area.

wytmoon gravatar imagewytmoon ( 2013-04-04 03:59:24 -0500 )edit

First thing, I added your code to your original post. Please do this also if you make changes. You can format code much better in a main post.

You are still using my suggestions wrong. Please try this code, which should do what you want.

   replaceImage.copyTo( capturedImage( mDetectedFace ) );

You cannot create a ROI first than copy to that only. It won't work that way since you just shifting points, but not copying the data. My new suggestion should work. So you can than remove the selectedArea matrix.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-04 04:18:48 -0500 )edit

Thanks for the posting advice. This may sound pretty stubborn of me but wouldn't your code snippet above be the same as

 replaceImage.copyTo( capturedImage.submat( mDetectedFace ) );

I'm saying this because in Java I can't do

 capturedImage( mDetectedFace );

By the way, how do I insert preformatted code snippets in a comment? Sorry if this fact should be a dead give a way already.

wytmoon gravatar imagewytmoon ( 2013-04-04 18:59:43 -0500 )edit

Adding code into a comment is making sure you have a blank line before and after, then position each rule about 5 spaces in front of it. This should do the trick, but again, comments not really for code blocking. I am not familiar with the Java OpenCV implementation, neighter with the function submat. But probably the submat function does call internally the code i did present. Basically Java openCV is created out of openCV wrappers. If a function is not available, create a pull request and try to create a personal wrapper for it?

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-05 00:56:25 -0500 )edit

answered 2013-04-08 00:44:30 -0500

wytmoon gravatar image

updated 2013-04-08 00:45:04 -0500

I did it! Found a similar topic in this discussion thread.

Basically my original code above should work. The reason it didn't was because of size constraints. It turns out that the image I am trying to overlay is bigger than my background image. So I used Imgproc.resize(Mat, Mat, Size) to make it smaller.

Thanks again to everyone who answered!
Big thanks to Steven for being so prompt and understanding! :)

edit flag offensive delete link more


It seemed obvious to me that your image shouldn't be larger than the ROI, but glad you found it. You are welcome, helping is our job here :). Please mark a answer as the solution, so that people know this topic is solved.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-04-08 02:11:47 -0500 )edit

Question Tools

1 follower


Asked: 2013-04-04 01:45:02 -0500

Seen: 21,464 times

Last updated: Apr 08 '13