Search code examples
pythonfunctionopencvreturn-value

Python proper placement of function return statement


I have a function draw_square_contours which gets passed an image of a Rubik's cube (processed through openCV) and a contours array obtained with function cv2.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE). draw_square_contours returns three RGB values which I use in a later function to determine the name of the colour for each cube.

def draw_square_contours(contours, copy):
    contours = contours[0] if len(contours) == 2 else contours[1]

    for c in contours:
        # obtain the bounding rectangle coordinates for each square
        x, y, w, h = cv2.boundingRect(c)

        # Extract mean colour for each region
        region = copy[y:y + h, x:x + w]
        r, g, b = numpy.mean(region, axis=(0, 1))

        # These are the measurements for the squares we want drawn over the image
        if 62 > h > 48 and 62 > w > 48:
            cv2.rectangle(copy, (x, y), (x + w, y + h), (36, 255, 12), 2)

        return r, g, b

Expected behaviour: cv2.rectangle() draws square over each of the 9 cubes in the image and returns to caller the 3 returned RGB values.

Actual behaviour: When the function is called with any return statement, cv2.rectangle does not draw the squares over the 9 cubes in the image.

Where would be the correct placement of the return statement be so that the function completes all its iterations and returns to the caller the derived r, g, b values?

Thanks for any insight!


Solution

  • The return statement will cause the function call to exit so the function will end in the first iteration. You could return a list of the return values after the loop like this:

    def draw_square_contours(contours, copy):
        contours = contours[0] if len(contours) == 2 else contours[1]
        return_vals = []
        for c in contours:
            # obtain the bounding rectangle coordinates for each square
            x, y, w, h = cv2.boundingRect(c)
    
            # Extract mean colour for each region
            region = copy[y:y + h, x:x + w]
            r, g, b = numpy.mean(region, axis=(0, 1))
    
            # These are the measurements for the squares we want drawn over the image
            if 62 > h > 48 and 62 > w > 48:
                cv2.rectangle(copy, (x, y), (x + w, y + h), (36, 255, 12), 2)
    
            return_vals.append((r, g, b))
        return return_vals