Issue
I am playing around with the Mask RCNN (https://github.com/matterport/Mask_RCNN) segmentation program that is trained on the COCO data set. It detects persons (along with many other objects that I further neglect) in an image and returns one or multiple Person masks, i.e. Boolean Numpy arrays containing True values for all pixels that are classified as a ‘Person’ and False values for all other pixels:
So an inputted image (uint8 array of shape (3900,2922,3)) becomes a mask (Boolean array of shape (3900,2922)) or multiple masks when multiple persons are detected in the picture.
Now I can use this mask to cut the person out of the image with some simply Numpy array indexing:
mask3d = np.dstack([mask]*3)
cut_out_mask = np.invert(mask3d)
res = np.where(cut_out_mask, 0, image)
This returns the following image:
Since the masks that are returned by the Mask_RCNN program are quite tight, I would like to add a margin of a few pixels (let’s say 15px), so that I get something like this:
Which Numpy/ OpenCV functions can I leverage to cut out the mask from the original image (similar to np.where
), adding a margin of 15 pixels around the mask?
Solution
The function you are looking for is the cv2.filter2D()
.
I wrote a short demo for you:
import numpy as np
import cv2
First we create a demo mask, with contains a square in the middle:
mask = np.zeros((300, 300))
mask[100:200, 100:200] = 1
Then we create our kernel for the filter2D function:
kernel = np.ones((32, 32))
I used the size 32, to get the desired padding of 15 pixel.
paddedMask = cv2.filter2D(mask, 1, kernel)
Just for demoing I display the Image with the following code:
image = cv2.threshold(np.array(paddedMask, dtype=np.uint8), 1, 255, 1)[1]
cv2.imshow("Test", image)
cv2.imshow("Org", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
Hope it helps.
Answered By – MunsMan
Answer Checked By – Mildred Charles (BugsFixing Admin)