C++ OpenCV:创建透明遮罩?
我目前正在做的是将人脸图像加载到垫子中,设置每只眼睛的中心点X和Y坐标,在每只眼睛周围创建一个圆,将ROI设置为眼睛周围的圆(使用Rect并设置遮罩),并降低眼睛图像中的红色值 我的问题是将矫正后的眼睛(红色较低)重新合并到原始图像上,因为矫正后的眼睛有一个黑色面具。我不知道如何摆脱黑色面具 我目前被一些OpenCV代码所困扰,这让我走到了这一步: 原始图像: 带黑色面罩的抽取眼睛: 矫正眼: 显示我的问题的当前结果: 这是我的帖子的延续: 我的理解是,你们不能创建一个圆形的ROI,所以我选择了矩形ROI和黑色蒙版。一个普通的Rect是不够的C++ OpenCV:创建透明遮罩?,c++,opencv,mask,mat,roi,C++,Opencv,Mask,Mat,Roi,我目前正在做的是将人脸图像加载到垫子中,设置每只眼睛的中心点X和Y坐标,在每只眼睛周围创建一个圆,将ROI设置为眼睛周围的圆(使用Rect并设置遮罩),并降低眼睛图像中的红色值 我的问题是将矫正后的眼睛(红色较低)重新合并到原始图像上,因为矫正后的眼睛有一个黑色面具。我不知道如何摆脱黑色面具 我目前被一些OpenCV代码所困扰,这让我走到了这一步: 原始图像: 带黑色面罩的抽取眼睛: 矫正眼: 显示我的问题的当前结果: 这是我的帖子的延续: 我的理解是,你们不能创建一个圆形的ROI,所以
任何建议都将不胜感激!!谢谢。您可以使用遮罩的roi图像来测试像素,但在真实图像中写入:
cv::Mat plotImage;
int半径=15;
浮动阈值=1.8;
plotImage=cv::imread(“C:/temp/debug.jpg”,cv::imread\u COLOR);
cv::Point leftEye(person.GetLeftEyePoint().X,person.GetLeftEyePoint().Y);
cv::Point rightEye(person.GetRightEyePoint().X,person.GetRightEyePoint().Y);
//获取包含圆的矩形
cv::Rect r(左眼x半径、左眼y半径、半径*2、半径*2);
//获取图像ROI
cv::Mat roi(绘图图像,r);
//做一个同样大小的黑色面具
cv::Mat掩码(roi.size()、roi.type()、cv::Scalar::all(0));
//里面有一个白色的圆圈
cv::圆(遮罩,cv::点(半径,半径),半径,cv::标量::全部(255),-1);
//结合roi和掩码
cv::Mat croppedEye=投资回报率和遮罩;
//在croppedEye上进行红眼检测/清除
整数计数=0;
对于(int y=0;y请查看此帖子。
if(imageMask.at(xx,yy)[0]<10)
//这意味着如果一个通道中的遮罩颜色小于10,则替换原始图像
{
//复制到(y,x)上的原始图像放置xx,yy遮罩的像素
原始图像在(y,x)[0]=图像掩模在(xx,yy)[0];
原始图像在(y,x)[1]=图像掩模在(xx,yy)[1];
原始图像在(y,x)[2]=图像掩模在(xx,yy)[2];
}
hehe,感觉对你目前的麻烦有点负责。;)如果你检查了croppedEye图像(带面具,以去除皮肤部分),但写下/纠正cloneRoi(甚至roi,你不必写回去)并将其用于copyTo()?嘿@berak!不,你帮了我这么多!我明白你现在说的了!!这就是我目前所做的(快速更改代码):我认为他发生了轻微的事故。。。哈。可能用错了眼睛,我现在会检查。是的,我用错了眼睛,呵呵。)很高兴,玩得很开心;)
cv::Mat plotImage;
int radius = 15;
float threshold = 1.8;
plotImage = cv::imread("C:/temp/debug.jpg", cv::IMREAD_COLOR);
cv::Point leftEye(person.GetLeftEyePoint().X, person.GetLeftEyePoint().Y);
cv::Point rightEye(person.GetRightEyePoint().X, person.GetRightEyePoint().Y);
//get the Rect containing the circle
cv::Rect r(leftEye.x-radius, leftEye.y-radius, radius*2, radius*2);
//obtain the image ROI
cv::Mat roi(plotImage, r);
//make a black mask, same size
cv::Mat mask(roi.size(), roi.type(), cv::Scalar::all(0));
//with a white filled circle in it
cv::circle(mask, cv::Point(radius, radius), radius, cv::Scalar::all(255), -1);
//combine roi & mask
cv::Mat croppedEye = roi&mask;
//conduct red eye detection/removal on croppedEye
int count = 0;
for(int y=0;y<croppedEye.rows;y++)
{
for(int x=0;x<croppedEye.cols;x++)
{
double b = croppedEye.at<cv::Vec3b>(y, x)[0];
double g = croppedEye.at<cv::Vec3b>(y, x)[1];
double r = croppedEye.at<cv::Vec3b>(y, x)[2];
double redIntensity = r / ((g + b) / 2);
//currently causes issues with non-red-eye images
if (redIntensity >= threshold)
{
double newRedValue = (g + b) / 2;
cv::Vec3b pixelColor(newRedValue,g,b);
//
// here's the trick now, just write back to the original image ;)
//
roi.at<cv::Vec3b>(cv::Point(x,y)) = pixelColor;
count++;
}
}
}
cv::imwrite("C:\\temp\\test.jpg", plotImage);
if (imageMask.at<Vec3b>(xx,yy)[0] < 10)
// This mean If the color of mask in one channel is < 10 replace the original Image
{
// Copy to original image on (y,x) places the pixel of xx,yy mask
OriginalImage.at<Vec3b>(y,x)[0] = imageMask .at<Vec3b>(xx,yy)[0];
OriginalImage.at<Vec3b>(y,x)[1] = imageMask .at<Vec3b>(xx,yy)[1];
OriginalImage.at<Vec3b>(y,x)[2] = imageMask .at<Vec3b>(xx,yy)[2];
}