原文地址:http://answers.opencv.org/question/160599/img-img1mask-img21-mask-how-do-that/
Hello,
I would like merge two color images with an image mask.
img1 and img2 are color image with 3 channelsmask is grey image with 1 channel
for merge the two image with the mask I do a loop for each pixel.
float c1,c2;
for(int j = 0; j < img1.rows ; j++ ){
for(int i = 0; i < img1.cols ; i++ ){
c1 = (greyGoodScale.at<uchar>(j, i))/255.0;
c2 = 1-c1;
img.at<Vec3b>(j, i)[0] = c2*img1.at<Vec3b>(j, i)[0] + c1*img2.at<Vec3b>(j, i)[0];
img.at<Vec3b>(j, i)[1] = c2*img1.at<Vec3b>(j, i)[1] + c1*img2.at<Vec3b>(j, i)[1];
img.at<Vec3b>(j, i)[2] = c2*img1.at<Vec3b>(j, i)[2] + c1*img2.at<Vec3b>(j, i)[2];
}
}
OK, it's work but my image is 720x500 and i have 70ms of processing time is TOO LONG, I need to be real time.I can't do process on GPU.
Is a way to reduce processing time ?
thank.christopheopenCV 3.x
有用的回答:
1
const uchar *scale = &greyGoodScale.at<uchar>(j, 0);
uchar *imgdata = &img.at<uchar>(j, 0);
const uchar *imgdata1 = &img1.at<uchar>(j, 0);
const uchar *imgdata2 = &img2.at<uchar>(j, 0);
for(int i = 0; i < img1.cols ; i++ ){
c1 = scale[i]/255.0;
c2 = 1-c1;
int pos = 3*i;
for (int k = 0; k < 3; k++){
imgdata[pos + k] = c2*imgdata1[pos + k] + c1*imgdata2[pos + k];
}
}
is one a the best solution with 16ms of processing time.
Now I would like divide the loop into 4 threads. My code is ok :
std::thread t1(firstQuarter...
..
std::thread t4(fourthQuarter...
t1.join;
...
t4.join;
but time is exactly same of one thread even time is upper.It's just classic access array memory and for the out image they don't need mutex because each thread have a quarter aof the image. How free array matrix for multithread for this easy case ?
2
Mat img1 = imread("f:/lib/opencv/samples/data/lena.jpg", IMREAD_COLOR);
Mat img2 = imread("f:/lib/opencv/samples/data/orange.jpg", IMREAD_COLOR);
Mat img3,img4;
Mat mask1(img1.rows, img1.cols, CV_8UC1, Scalar(0));
circle(mask1, Point(200, 200), 100, Scalar(92), -1);
Mat mask2=255-mask1;
Mat mask2c,mask1c;
vector<Mat> pMask = { mask1,mask1,mask1 };
merge(pMask, mask1c);
pMask.clear(); pMask.push_back(mask2); pMask.push_back(mask2); pMask.push_back(mask2);
merge(pMask, mask2c);
multiply(img1, mask1c, img3, 1.0 / 255, CV_32F);
multiply(img2, mask2c, img4, 1.0 / 255, CV_32F);
img4 =img3+img4;
img4.convertTo(img3,CV_8U);
imshow("test", img3);
waitKey();