Home > database >  Use python opencv dilation with a mask
Use python opencv dilation with a mask

Time:06-10

From what I have seen in the documentation, I can't use opencv dilate function with a mask.

Any idea how to achieve this?

I mean, I would like to do a dilate operation only within a ROI on an image.

Thank you very much in advance.

CodePudding user response:

Follow the following steps to get your results:

  • Extract your ROI from the image. This will give you a new image of only the ROI.
  • Perform your dilation operation on the extracted image of the ROI.
  • Replace the ROI region of the original image with this dilated image.

Following can be the possible code. Here the image is Img, and ROI is given my rectangle [x, y, w, h].

ROI_Img = Img[y:y h, x:x w].copy()
Kernel = np.ones((3, 3), dtype=uint8)
ROI_Img_Dilated = cv2.dilate(ROI_Img, Kernel, iterations=1)
Img[y:y h, x:x w] = ROI_Img_Dilated.copy()

CodePudding user response:

As of now, there are no functions available to perform selective morphological operations.

I have outlined a naïve approach below along with the code:

Input image:

enter image description here

Code:

img = cv2.imread('hand_drawn_contours.jpg',1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# binarize the image
th = cv2.threshold(gray,0,255,cv2.THRESH_BINARY cv2.THRESH_OTSU)[1]

# finding contours
contours, hierarchy = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

We will perform dilation only for the first contour present in contours. Consider the following to be our ROI:

enter image description here

# create a blank mask
mask = np.zeros((img.shape[0], img.shape[1]), np.uint8)
# draw selected ROI to form the mask
mask = cv2.drawContours(mask,contours,1,255, -1)

enter image description here

When performing morphology the shape of the ROI either increases or decreases. To maintain the same shape; the same morphology operation must be performed on the mask also:

# dilate both the image and the mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
dilate_th = cv2.dilate(th, kernel, iterations=1)
dilate_mask = cv2.dilate(mask, kernel, iterations=1)

# using the dilated mask, retain the dilated ROI
im1 = cv2.bitwise_and(dilate_th, dilate_th, mask = dilate_mask)

enter image description here

Now to preserve the other contours as is, invert the mask to retain them

dilate_mask_inv = cv2.bitwise_not(dilate_mask)
im2 = cv2.bitwise_and(th, th, mask = dilate_mask_inv)

enter image description here

res = cv2.add(im1, im2)

enter image description here

  • Related