Ask Your Question
0

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

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

Finfa811 gravatar image

Hello,

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

Comments

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

blur(src,dst...
dst(mask).copyTo(pyr(mask))
LBerger gravatar imageLBerger ( 2016-03-04 06:49:03 -0600 )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 -0600 )edit

So

  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 -0600 )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 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
0

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

Finfa811 gravatar image

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

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
1

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

LBerger gravatar image

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

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

}
edit flag offensive delete link more

Comments

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 -0600 )edit

Question Tools

1 follower

Stats

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

Seen: 3,770 times

Last updated: Mar 07 '16