The Python Oracle

Cut mask out of image with certain pixel margin numpy opencv

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 5 Looping

--

Chapters
00:00 Cut Mask Out Of Image With Certain Pixel Margin Numpy Opencv
01:15 Accepted Answer Score 1
01:54 Answer 2 Score 2
02:24 Answer 3 Score 4
03:23 Thank you

--

Full question
https://stackoverflow.com/questions/6049...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #image #numpy #opencv #imageprocessing

#avk47



ANSWER 1

Score 4


One method to do this is to use cv2.dilate to increase the surface area of the mask. Depending on your mask shape, you can create varying structuring element shapes and sizes with cv2.getStructuringElement.

For instance, if your mask shape is rectangular you might want to use cv2.MORPH_RECT or if your mask shape is circular you can use cv2.MORPH_ELLIPSE. In addition, you can change the kernel size and the number of iterations to dilate. After dilating the mask, you can use cv2.bitwise_and to get your result. Here's a minimum reproducible example:

Original image

Mask

Dilate

Bitwise-and for result

import cv2

# Load image and mask
image = cv2.imread('1.png')
mask = cv2.imread('mask.png')

# Create structuring element, dilate and bitwise-and
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,25))
dilate = cv2.dilate(mask, kernel, iterations=3)
result = cv2.bitwise_and(image, dilate)

cv2.imshow('dilate', dilate)
cv2.imshow('result', result)
cv2.waitKey()



ANSWER 2

Score 2


You may use cv2.dilate morphological operation for widening the mask:

new_mask = cv2.dilate(mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (50,50)))

Sample code that loads a mask and widens the mask:

import cv2

# Read the mask from a file (for testing).
mask = cv2.imread("sample_mask.png", cv2.IMREAD_GRAYSCALE);

new_mask = cv2.dilate(mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (50,50)))

# Display mask and new_mask
cv2.imshow('mask', mask)
cv2.imshow('new_mask', new_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

mask:
enter image description here

new_mask:
enter image description here




ACCEPTED ANSWER

Score 1


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.