Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blurring a Rect within a screenshot

I'm developing an Android app which uses a background Service to programmatically capture a screenshot of whatever is on the screen currently. I obtain the screenshot as a Bitmap.

Next, I successfully imported OpenCV into my Android project.

What I need to do now is blur a subset of this image, i.e. not the entire image itself, but a [rectangular] area or sub-region within the image. I have an array of Rect objects representing the rectangular regions that I need to blur within the screenshot.

I've been looking around for a tutorial on doing this with OpenCV in Java, and I haven't found a clear answer. The Mat and Imgproc classes are obviously the ones of interest, and there's the Mat.submat() method, but I've been unable to find a clear, straightforward tutorial on getting this done.

I've googled a lot, and none of the examples I've found are complete. I need to do this in Java, within the Android runtime.

What I need is: Bitmap >>> Mat >>> Imgproc>>> Rect >>> Bitmap with ROI blurred.

Any experienced OpenCV devs out here, can you point me in the right direction? This is the only thing I'm stuck at.

Related:

Gaussian blurring with OpenCV: only blurring a subregion of an image?.

How to blur a rectagle with OpenCv.

How to blur some portion of Image in Android?.

like image 481
Y.S Avatar asked Jan 29 '20 12:01

Y.S


2 Answers

The C++ code to achieve this task is shared below with comments and sample images:

// load an input image
Mat img = imread("C:\\elon_tusk.png");

img:

enter image description here

// extract subimage
Rect roi(113, 87, 100, 50);
Mat subimg = img(roi);

subimg:

enter image description here

// blur the subimage
Mat blurred_subimage;
GaussianBlur(subimg, blurred_subimage, Size(0, 0), 5, 5);

blurred_subimage:

enter image description here

// copy the blurred subimage back to the original image
blurred_subimage.copyTo(img(roi));

img:

enter image description here

Android equivalent:

Mat img = Imgcodecs.imread("elon_tusk.png");
Rect roi = new Rect(113, 87, 100, 50);
Mat subimage = img.submat(roi).clone();
Imgproc.GaussianBlur(subimg, subimg, new Size(0,0), 5, 5);
subimg.copyTo(img.submat(roi));
like image 92
karlphillip Avatar answered Sep 25 '22 18:09

karlphillip


You could just implement your own helper function, let's call it roi (region of interest). Since images in opencv are numpy ndarrays, you can do something like this:

def roi(image: np.ndarray, region: QRect) -> np.ndarray:
    a1 = region.upperLeft().x()
    b1 = region.bottomRight().y()
    a2 = region.upperLeft().x()
    b2 = region.bottomRight().y()
    return image[a1:a2, b1:b2]

And just use this helper function to extract the subregions of the image that you are interested, blur them and put the result back on the original picture.

like image 25
kalzso Avatar answered Sep 24 '22 18:09

kalzso