The faster solution is:
cv::cvtColor(mask, mask, cv::COLOR_GRAY2BGR);
cv::Mat roi;
cv::blur(image & mask,roi,cv::Size(3,3));//Or whatever blurring you want
cv::Mat Result=(image & (~mask)) + roi;
cv::resize(result,result,cv::Size(New_Width,New_height)); // Or whatever downsampling you want
May be like this
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
Mat m = imread("c:/lib/opencv/samples/data/lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat mask=Mat::zeros(m.size(), CV_8UC1),maskBlur,mc;
// mask is a disk
circle(mask, Point(200, 200), 100, Scalar(255),-1);
Mat negMask;
// neg mask
bitwise_not(mask, negMask);
circle(mask, Point(200, 200), 100, Scalar(255), -1);
Mat md,mdBlur,mdint;
m.copyTo(md);
// All pixels outside mask set to 0
md.setTo(0, negMask);
imshow("mask image", md);
// Convert image to int
md.convertTo(mdint, CV_32S);
Size fxy(5, 5);
blur(mdint, mdBlur, fxy);
mdBlur = mdBlur;
mask.convertTo(maskBlur, CV_32S);
blur(maskBlur, maskBlur, fxy);
Mat mskB;
mskB.setTo(1, negMask);
divide(mdBlur,maskBlur/255,mdBlur);
mdBlur.convertTo(mc, CV_8U);
resize(mc,mc,Size(),0.5,0.5);
imshow("Blur with mask", mc);
imwrite("testBlur.png", mc);
waitKey();
}
Asked: 2016-03-04 06:32:58 -0600
Seen: 3,770 times
Last updated: Mar 07 '16
If you don't want to use pyrDown you have to use resize
I don't think it's possible to blur using a mask. You will have to blur all your image and copy using mask
With those solutions some pixels from the background will be blurred into the edges of the mask... That is exactly what I want to avoid. I don't want to blur all my image first, but doing a selective blurring inside the region defined by the mask.
So
You must blur the whole image, and then replace pixels in original image if they also belong to the mask.