Search code examples
pythonopencvimage-processingcontouredge-detection

How to connect the ends of edges in order to close the holes between them?


My task is to detect the cracks on the soil surface and calculate crack's total area. I used Canny edge detection for this purpose.

Input image

Input Image

Result

Here

My next step is to convert canny edges to contours since I want to filtrate the cracks using cv2.mean and calculate their area using cv2.contourArea functions. On this step, I faced the problem. When I used:

canny_cracks = cv2.Canny(gray, 100, 200)
contours, _ = cv2.findContours(canny_cracks, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

It does not convert properly because of the holes the ends of edges. See problem here

here

My question is how can I connect the ends of edges in order to close the hole between them?

Note: I used contours detection without applying Canny edges. The problem is that contours detection gives a lot of noise and doesn't detect all cracks well. Or maybe I do not know how to find contours as canny edges do.


Solution

  • You can use Morphological Close. This closes gaps between white pixels. If you input your Canny image in the script below, you can try for yourself.

    Result:

    enter image description here

    Code:

        import cv2
        import numpy as np  
    
        # function that handles trackbar changes
        def doClose(val):
                # create a kernel based on trackbar input
                kernel = np.ones((val,val))
                # do a morphologic close
                res = cv2.morphologyEx(img,cv2.MORPH_CLOSE, kernel)
                # display result
                cv2.imshow("Result", res)
    
        #load image as grayscale
        img = cv2.imread("KbMHp.png",0)
    
        # create window and add trackbar
        cv2.namedWindow('Result')
        cv2.createTrackbar('KernelSize','Result',0,15,doClose)
    
        # display image
        cv2.imshow("Result", img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()