Skip to content Skip to sidebar Skip to footer

How Can I Sort Contours From Left To Right And Top To Bottom In A Consistent Manner

I am working on a problem that extracts rectangular boxes from image and sort those rectangular boxes sequentially. Code that I tried is: import cv2 import matplotlib.pyplot as plt

Solution 1:

It's the orientation – or: the rotation – of the paper, that decides, whether simply checking the (x, y) coordinates of the contours' bounding boxes is sufficient or not.

So, I'd simply stick to some good old comparison method, e.g. this earlier answer from me on the same issue implemented in C++. Unfortunately, using the old way using the cmp parameter in sorted was removed entirely in Python 3. Nevertheless, we can use cmp_to_key from the functools module to get that functionality mapped to a proper key function.

Now, first, let's create the comparison method:

defcontour_sort(a, b):

    br_a = cv2.boundingRect(a)
    br_b = cv2.boundingRect(b)

    ifabs(br_a[1] - br_b[1]) <= 15:
        return br_a[0] - br_b[0]

    return br_a[1] - br_b[1]

The abs(...) <= 15 (or any other proper threshold) is needed for the cases, where the right boxes are higher than the left boxes (i.e. the main problem).

Then, add this line to your imports:

from functools import cmp_to_key

Finally, replace the key function in your sorted call to that:

cnts = sorted(cnts, key=cmp_to_key(contour_sort))

Doing so, I can extract the correct order for all the given images.

If someone can provide a simple key function without the need of a comparison method, I'd be very interested in that! I couldn't find one myself.

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
OpenCV:        4.5.1
----------------------------------------

Post a Comment for "How Can I Sort Contours From Left To Right And Top To Bottom In A Consistent Manner"