Ask Your Question

Blurring non-rectangular region of an image, then downsample whole image

asked 2016-03-04 06:32:58 -0500

Finfa811 gravatar image


I am using OpenCV3 to blur and downsample an image, I just want to blur the region inside the area defined by a binary mask like:

enter image description here

After that region is blurred, I would like to downsample the image without blurring the whole image again, so pyrDown is not useful for me.

Any idea?

edit retag flag offensive close merge delete


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

LBerger gravatar imageLBerger ( 2016-03-04 06:49:03 -0500 )edit

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.

Finfa811 gravatar imageFinfa811 ( 2016-03-04 07:59:21 -0500 )edit


  1. blur your image
  2. Erode your mask A with a size equal to kernel size and copy all pixel inside this new mask B
  3. write your own code to blur pixel inside A-B
LBerger gravatar imageLBerger ( 2016-03-04 08:06:33 -0500 )edit

You must blur the whole image, and then replace pixels in original image if they also belong to the mask.

Pedro Batista gravatar imagePedro Batista ( 2016-03-04 08:52:54 -0500 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2016-03-07 04:34:45 -0500

Finfa811 gravatar image

updated 2016-03-07 04:44:51 -0500

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
edit flag offensive delete link more

answered 2016-03-04 09:10:27 -0500

LBerger gravatar image

updated 2016-03-04 09:21:50 -0500

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;


    // 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);

    mdBlur.convertTo(mc, CV_8U);
    imshow("Blur with mask", mc);
    imwrite("testBlur.png", mc);

edit flag offensive delete link more


That works fine, however, another guy gave me another tricky solution which simpliflies all the process. I post it below.

Finfa811 gravatar imageFinfa811 ( 2016-03-07 04:28:01 -0500 )edit

Question Tools

1 follower


Asked: 2016-03-04 06:32:58 -0500

Seen: 3,309 times

Last updated: Mar 07 '16