1

I'm trying to find a contour that will cover the "morphed" image below (rightmost):

enter image description here

Note that this code gives 11 or 12 contours and doesn't provide the biggest box that can cover all the white pixels:

cnts = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
print('Found {} coutours'.format(len(cnts)))

So I created some functions to manually traverse the image pixels:

image_height = morphed.shape[0]
image_width = morphed.shape[1]

def find_top_pixel():
    for h in range(image_height):
        for w in range(image_width):
            if morphed[h, w] > 0:
                return h

    return 0
          
def find_bottom_pixel():
    for h in range(image_height):
        for w in range(image_width):
            if morphed[-h, -w] > 0:
                return image_height - h

    return image_height


def find_left_pixel():
    for w in range(image_width):
        for h in range(image_height):       
            if morphed[h, w] > 0:
                return w

    return 0

def find_right_pixel():
    for w in range(image_width):
        for h in range(image_height):       
            if morphed[-h, -w] > 0:
                return image_width - w                

    return image_width

padding = 10
top_left = (find_left_pixel() - padding, find_top_pixel() - padding)
bottom_right = (find_right_pixel() + padding, find_bottom_pixel() + padding)

print('top_left: {}'.format(top_left))
print('bottom_right: {}'.format(bottom_right))

And I was able to achieve my goal to have this:

enter image description here

Is there an optimized way? I feel that there might be a succinct Python syntax or even an opencv property or method.

firnnauriel
  • 2,047
  • 7
  • 27
  • 44
  • 2
    get all white pixels coordinates [(see here)](https://stackoverflow.com/q/43632498/5008845) and compute their bounding box [(see here)](https://stackoverflow.com/a/40509387/5008845) – Miki Sep 23 '20 at 15:02
  • thanks! i was able to convert it to 13 lines now. – firnnauriel Sep 23 '20 at 15:53

1 Answers1

1

Thanks to Miki's reply, I was able to simplify my implementation:

morphed_white_pixels = np.argwhere(morphed == 255)

min_y = min(morphed_white_pixels[:, 1])
max_y = max(morphed_white_pixels[:, 1])
min_x = min(morphed_white_pixels[:, 0])
max_x = max(morphed_white_pixels[:, 0])

padding = 10
top_left = (min_y - padding, min_x - padding)
bottom_right = (max_y + padding, max_x + padding)

print('top_left: {}'.format(top_left))
print('bottom_right: {}'.format(bottom_right))
firnnauriel
  • 2,047
  • 7
  • 27
  • 44