How to use OpenCV to sort object contours

1 Introduction

In the process of image processing, we often encounter some operations related to the object contour, such as calculating the perimeter area of the target contour. We can easily obtain the contour of each target by directly using the findContours function of Opencv, but after visualization, the order is disordered, as shown on the left side of the figure below:


This section aims to sort the object contours from top to bottom or from left to right, so as to achieve the visual results on the right side of the figure above

Stop gossiping and let's get started 😃

Two chestnuts

2.1 reading images

First, let's read the image and get its edge detection diagram. The code is as follows:

image = cv2.imread(args['image'])
accumEdged = np.zeros(image.shape[:2], dtype='uint8')
for chan in cv2.split(image):
	chan = cv2.medianBlur(chan, 11)
    edged = cv2.Canny(chan, 50, 200)
    accumEdged = cv2.bitwise_or(accumEdged, edged)
cv2.imshow('edge map', accumEdged)

The operation results are as follows:

The original image is on the left and the edge detection image is on the right

2.2 obtaining contours

The API for finding image contour in opencv Python is: findContours function, which receives binary image as input and can output object outer contour, inner and outer contour, etc

The code is as follows:

cnts = cv2.findContours(accumEdged.copy(), cv2.RETR_EXTERNAL,  cv2.CHAIN_APPROX_SIMPLE)
cnts = grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]
orig = image.copy()
# unsorted
for (i, c) in enumerate(cnts):
    orig = draw_contour(orig, c, i)
cv2.imshow('Unsorted', orig)
cv2.imwrite("./Unsorted.jpg", orig)

The operation results are as follows:

It should be noted that in opencv2 In version x, the function findContours returns two values. The function declaration is as follows:

contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

However, in versions above OpenCV3, the declaration form of this function is as follows:

image, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

So in order to fit the two patterns, we implement the function grab_contours to select the corresponding subscript position of the return contour according to different versions. The code is as follows:

def grab_contours(cnts):
    # if the length the contours tuple returned by cv2.findContours
    # is '2' then we are using either OpenCV v2.4, v4-beta, or
    # v4-official
    if len(cnts) == 2:
        cnts = cnts[0]

    # if the length of the contours tuple is '3' then we are using
    # either OpenCV v3, v4-pre, or v4-alpha
    elif len(cnts) == 3:
        cnts = cnts[1]

    return cnts

2.3 contour sorting

Through the above steps, we get the contours of all objects in the image. Next, we define the function sort_ The contours function is used to sort the contours. This function accepts the method parameter to sort the contours in different order, such as from left to right or from right to left

The code is as follows:

def sort_contours(cnts, method='left-to-right'):
    # initialize the reverse flag and sort index
    reverse = False
    i = 0
    # handle if sort in reverse
    if method == 'right-to-left' or method == 'bottom-to-top':
        reverse = True
    # handle if sort against y rather than x of the bounding box
    if method == 'bottom-to-top' or method == 'top-to-bottom':
        i = 1

    boundingBoxes = [cv2.boundingRect(c) for c in cnts]
    (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes), key=lambda b: b[1][i], reverse=reverse))
    return (cnts, boundingBoxes)

The core idea of the above code is to first find the external rectangular box of each contour, and then sort the external boxes according to x or y coordinates to realize the sorting of contours

The calling code is as follows:

# sorted
(cnts, boundingboxes) = sort_contours(cnts, method=args['method'])
for (i, c) in enumerate(cnts):
    image = draw_contour(image, c, i)
cv2.imshow('Sorted', image)
cv2.waitKey(0)

The operation results are as follows:

2.4 other results

Using the above code, we can also sort from left to right, as shown below:

3 Summary

In this paper, OpenCV is used to sort the object contour in the specified order, and a complete code example is given

Have you failed?


Pay attention to the official account of AI algorithm and get more AI algorithm information.


reference resources

Pay attention to the official account and reply to contour, and you can get the complete code.

Keywords: Python OpenCV Computer Vision image processing

Added by sbarros on Fri, 17 Dec 2021 18:27:55 +0200