Achille G
Achille G

Reputation: 817

Dilate in only one direction

I have an issue using erode and dilate, I'm not sure I understand how to properly use the parameters.

I have this picture:

enter image description here

Using this piece of code:

def dilate_and_erode(self):

        img = self.img

        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        _, thresh = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        
        
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
        res = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel)
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
        
        dilated = cv2.dilate(res, kernel)
        
        eroded=cv2.erode(dilated,kernel)

        img_contours = cv2.findContours(eroded, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_SIMPLE)[-2]
        img_contours = sorted(img_contours, key=cv2.contourArea)

        ctr = []
        for i in img_contours:
            if cv2.contourArea(i) > 100:
                ctr.append(i)

        mask = np.zeros(img.shape[:2], np.uint8)
        cv2.drawContours(mask, ctr,-1, 255, -1)
        new_img = cv2.bitwise_and(img, img, mask=mask)

        cv2.imshow("Original Image", img)
        cv2.imshow("New image", new_img)
        cv2.imshow("Mask", mask)
        cv2.waitKey(0)

I get this :

enter image description here

Which is not exactly what I want, I'd like to remove the black noise in the top of the picture

enter image description here

Any advices would be greatly appreciated !

Upvotes: 1

Views: 1059

Answers (1)

Rotem
Rotem

Reputation: 32084

It's not difficult to implement dilation in one direction using for loops, but it's a bit boring...

Suggested solution:
Move the image up by one pixel, take the maximum of image and "moved image"; repeat the process few times.

The suggested solution is inefficient in terms of complexity, but since loops in Python are so slow, its going to be faster than using nested for loops.

Here is a code sample:

import cv2
import numpy as np

new_img = cv2.imread('new_image.png')

for i in range(15):
    new_img[0:-1, :, :] = np.maximum(new_img[0:-1, :, :], new_img[1:, :, :])

Result (new_img):
enter image description here

Upvotes: 3

Related Questions