Filtering contours

In previous sections, we have seen how to calculate the size of a detected contour. The size of a detected contour can be calculated based on image moments or using the OpenCV function cv2.contourArea(). In this example, we are going to sort the detected contours based on the computed size for each one.

Therefore, the sort_contours_size() function is key:

def sort_contours_size(cnts):
""" Sort contours based on the size"""

cnts_sizes = [cv2.contourArea(contour) for contour in cnts]
(cnts_sizes, cnts) = zip(*sorted(zip(cnts_sizes, cnts)))
return cnts_sizes, cnts

Before explaining the code of this function, we are going to introduce some key points. The * operator can be used in conjunction with zip() to unzip the list:

coordinate = ['x', 'y', 'z']
value = [5, 4, 3]
result = zip(coordinate, value)
print(list(result))
c, v = zip(*zip(coordinate, value))
print('c =', c)
print('v =', v)

The output is as follows:

[('x', 5), ('y', 4), ('z', 3)]
c = ('x', 'y', 'z')
v = (5, 4, 3)

Let's incorporate the sorted function:

coordinate = ['x', 'y', 'z']
value = [5, 4, 3]
print(sorted(zip(value, coordinate)))
c, v = zip(*sorted(zip(value, coordinate)))
print('c =', c)
print('v =', v)

The output is as follows:

[(3, 'z'), (4, 'y'), (5, 'x')]
c = (3, 4, 5)
v = ('z', 'y', 'x')

Therefore, the sort_contours_size() function sorts the contours based on the size. Also, the script outputs the ordering number in the center of the contour. The output of contours_sort_size.py can be seen in the next screenshot:

As you can see, in the upper part of the screenshot the original image is shown, while in the bottom part of the screenshot the original image has been modified to include the ordering number in the center of each contour.