'how does copyTo in opencv c++ works?
I have gone through the below snippet and was wondering how copyTo() in opencv
function work.
// Make a copy
Mat faceWithGlassesNaive1 = faceImage.clone();
// Take the eye region from the image
Mat roiFace = faceWithGlassesNaive1(Range(150,250),Range(140,440));
// Replace the eye region with the sunglass image
glassBGR.copyTo(roiFace);
Does copyTo()
work on copyByreference
, so that any modifications done to roiface
gets reflected in faceWithGlassesNaive1
? Or Am i missing something ?. Need help .
- Below is the faceimage
Solution 1:[1]
From the docs:
Copies the matrix to another one.
The method copies the matrix data to another matrix. Before copying the data, the method invokes :
m.create(this->size(), this->type());
so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.
So your data will be copied and changes won't reflect back to the original image. If you want to get rid of the white pixels in the copy you can provide a mask (the syntax might be different, doing this from memory):
Mat glassGray;
cvtColor(glassBGR, glassGray, COLOR_BGR2GRAY);
glassBGR.copyTo(roiFace, glassGray != 255);
Your actual problem is that roiFace
is just an alias to the memory of faceWithGlassesNaive1
. So changes applied to roiFace
(for example, copying new data into it) will reflect back to faceWithGlassesNaive1
. copyTo
is not your problem in this case, but the creation of roiFace
.
From Mat::operator()():
[...] Similarly to all of the above, the operators are O(1) operations, that is, no matrix data is copied.
Solution 2:[2]
copyTo
function of opencv as the documentation says:
The method copies the matrix data to another matrix.
So you can not expect to achieve your task like that but you can simply achieve it as an approach like this:
The code:
#include <iostream>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat faceImage = imread("/ur/face/image/directory/elon.jpg");
Mat glassBGR = imread("/ur/glass/image/directory/glass.png");
resize(glassBGR,glassBGR,Size(300,100));
// check each pixel of glass and if its white(255,255,255) then change it with face image pixels
for(int i=0;i<glassBGR.cols;i++)
{
for(int j=0;j<glassBGR.rows;j++)
{
if(!(glassBGR.at<Vec3b>(j, i) == Vec3b(255,255,255)))
{
faceImage.at<Vec3b>(j+150,i+140) = glassBGR.at<Vec3b>(j, i);
}
}
}
imshow("result",faceImage);
waitKey(0);
}
Result:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |