'Join lines to create closed contours using OpenCV

I have the following image: enter image description here

And I would like to join all of these "green" linear pixels to create a bounding box contour - is this something that is possible with opencv?

Thanks



Solution 1:[1]

I cleaned up the given image and used the following as input:

Input image

enter image description here

Performing threshold and finding contours:

th = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(th , cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]

Now the fun part!

  • For each contour, find the extreme points. These are the top-most, bottom-most, right-most and left-most points of the contour.
  • Compare the distance between every extreme point of a contour with those of every other contour
  • Draw a line between points with the least Euclidean distance.

Code:

for i in range(len(cnts)):
    min_dist = max(img.shape[0], img.shape[1])
    cl = []
    
    ci = cnts[i]
    ci_left = tuple(ci[ci[:, :, 0].argmin()][0])
    ci_right = tuple(ci[ci[:, :, 0].argmax()][0])
    ci_top = tuple(ci[ci[:, :, 1].argmin()][0])
    ci_bottom = tuple(ci[ci[:, :, 1].argmax()][0])
    ci_list = [ci_bottom, ci_left, ci_right, ci_top]
    
    for j in range(i + 1, len(cnts)):
        cj = cnts[j]
        cj_left = tuple(cj[cj[:, :, 0].argmin()][0])
        cj_right = tuple(cj[cj[:, :, 0].argmax()][0])
        cj_top = tuple(cj[cj[:, :, 1].argmin()][0])
        cj_bottom = tuple(cj[cj[:, :, 1].argmax()][0])
        cj_list = [cj_bottom, cj_left, cj_right, cj_top]
        
        for pt1 in ci_list:
            for pt2 in cj_list:
                dist = int(np.linalg.norm(np.array(pt1) - np.array(pt2)))     #dist = sqrt( (x2 - x1)**2 + (y2 - y1)**2 )
                if dist < min_dist:
                    min_dist = dist             
                    cl = []
                    cl.append([pt1, pt2, min_dist])
    if len(cl) > 0:
        cv2.line(img1, cl[0][0], cl[0][1], (255, 255, 255), thickness = 5)

Output image:

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeru Luke