我想做的基本上是对图像进行模糊处理,然后将其与原图融合,以便只有原始图像中的特定区域会受到模糊处理(即面部应该被模糊处理)。
我的主要想法是遮盖我想要模糊处理的原始部分,然后将原始副本模糊处理并“合并”它们。
在一定程度上,这也起作用了。
我的图片:
(1)原始图像
(2)包含需要模糊处理的部分的原始图像
(3)模糊图像
创建这些图像的我的C++代码:
我的主要想法是遮盖我想要模糊处理的原始部分,然后将原始副本模糊处理并“合并”它们。
在一定程度上,这也起作用了。
我的图片:
(1)原始图像
![原始图像](https://istack.dev59.com/w0opt.webp)
![包含需要模糊处理的部分的原始图像](https://istack.dev59.com/OmMcv.webp)
![模糊图像](https://istack.dev59.com/23044.webp)
int main(void) {
cv::Mat srcImage = cv::imread(path);
srcImage.convertTo(srcImage, CV_32FC3, 1.0/255.0);
Mat _mask;
Mat img_gray;
cv::Scalar white = cv::Scalar(255, 255, 255);
cv::Scalar black = cv::Scalar(0, 0, 0);
cv::cvtColor(srcImage, img_gray, cv::COLOR_BGR2GRAY);
img_gray.convertTo(_mask, CV_32FC1);
// face
cv::circle(_mask, cv::Point(430, 350), 200, black, -1, 8, 0);
// eyes
cv::circle(_mask, cv::Point(502, 260), 27, white, -1, 8, 0);
cv::circle(_mask, cv::Point(390, 260), 27, white, -1, 8, 0);
// mouth
cv::ellipse(_mask, cv::Point(440, 390), cv::Point(60, 25), 0, 0, 360, white, -1, 8, 0);
cv::threshold(1.0-_mask, _mask, 0.9, 1.0, cv::THRESH_BINARY_INV);
cv::GaussianBlur(_mask,_mask,Size(21,21),11.0);
cv::Mat res;
cv::Mat bg = Mat(srcImage.size(), CV_32FC3);
bg = cv::Scalar(1.0, 1.0 ,1.0);
vector<Mat> ch_img(3);
vector<Mat> ch_bg(3);
cv::split(srcImage, ch_img);
cv::split(bg, ch_bg);
ch_img[0] = ch_img[0].mul(_mask) + ch_bg[0].mul(1.0 - _mask);
ch_img[1] = ch_img[1].mul(_mask) + ch_bg[1].mul(1.0 - _mask);
ch_img[2] = ch_img[2].mul(_mask) + ch_bg[2].mul(1.0 - _mask);
cv::merge(ch_img, res);
cv::merge(ch_bg, bg);
// original but with white mask
res.convertTo(res, CV_8UC3, 255.0);
imwrite("original_with_mask.jpg", res);
// blur original image
cv::Mat blurredImage;
bilateralFilter(srcImage, blurredImage, 10, 20, 5);
GaussianBlur(srcImage, blurredImage, Size(19, 19), 0, 0);
blurredImage.convertTo(blurredImage, CV_8UC3, 255.0);
imwrite("blurred.jpg", blurredImage);
cv::Mat maskedImage;
maskedImage = Mat(srcImage.size(), CV_32FC3);
// now combine blurred image and original using mask
// this fails
cv::bitwise_and(blurredImage, _mask, maskedImage);
cv::imwrite("masked.jpg", maskedImage);
}
我的问题是,cv::bitwise_and(blurredImage, _mask, maskedImage);
在执行时出现了失败。
OpenCV Error: Sizes of input arguments do not match (The operation is neither 'array op array' (where arrays have the same size and type), nor 'array op scalar', nor 'scalar op array') in binary_op
可能是因为_mask
是一张单通道图像,而blurredImage
和maskedImage
都是三通道图像。
我该如何合并这些图像,使得图像(2)中的当前白色区域使用带有“柔和”边缘的透明蒙版进行模糊处理?