Search code examples
python-3.xnumpyopencv3.0

Python and OpenCV: sort list of contours according to two criteria


In Python, I have a list of contours. every contour is a numpy array. every contour is a square as in the following image:

Color squares

every contour has cx and cy - which are the moment of the contour - the center of it.

I calculated also the mean rgb of every contour and added it to the list.

Debug - values

How can I sort the contours as you can see in the first images from 1-24 - from top left to bottom right - row by row using ONLY (cx,cy)?

My code:

    def find_contour_mean_color_value(self , img , width=None , height=None , full_square=False):

    contours = []

    for (i,cnt) in enumerate(self.all_detected_color_squares):
        mom = cv2.moments(cnt)
        (cx,cy) = int(mom['m10']/mom['m00']), int(mom['m01']/mom['m00'])

        if full_square == True:
            x,y,w,h = cv2.boundingRect(cnt)
            roi = img[y:y+h, x:x+w]

        else:
            #define needed square around the center as following
            center_square_width = width
            center_square_height = height

            x_1= int(cx-(center_square_width/2))
            y_1 = int(cy-(center_square_height/2))

            roi = img[y_1:y_1 + center_square_height , x_1:x_1 + center_square_width]



        color = cv2.mean(roi)
        (r,g,b) = (color[2] , color[1] , color[0])
        contours.append((self.all_detected_color_squares , (cx ,cy) , (r,g,b) ))


    self.all_detected_color_squares = np.array(contours)

How can we sort contours list as needed and described by the image and numbers?

I am sure that it is doable maybe using labmda but I am not able to do it.

For more details see:

shown Contours


Solution

  • This can be done this way:

        squares = sorted(detected_squares, key=lambda x: x[1][1])
        for i in range(self.cols_num):
            i = i*self.rows_num
            j = i + self.rows_num
            squares[i:j] = sorted(squares[i:j], key=lambda x: x[1][0])
    
    
        detected_squares = squares