OpenCV, trying to get maximum and minium of multiple contours

Viewed 152

So I am trying to get Max top and lowest points in multiple contours. It works when I want to find a the top and bottompoint for the biggest contour:

c = max(contours, key=cv.contourArea)
extTop = tuple(contours[-1][contours[-1][:, :, 1].argmin()][0])
extBot = tuple(contours[-1][contours[-1][:, :, 1].argmax()][0])

Now I try to get the top and bottom point of all the contours together but it doesnt work:

extTop = tuple(contours[contours[:, :, 1].argmin()][0])
extBot = tuple(contours[contours[:, :, 1].argmax()][0])

it gives:

extTop = tuple(contours[contours[:, :, 1].argmin()][0])

TypeError: tuple indices must be integers or slices, not tuple

Anyone knows a solution? I am prety new to coding so it might be a stupid question, but I have been trying for more than a day now.

Edit: tried this first, also didnt work:

c = max(contours, key=cv.contourArea)
extTop = tuple(contours[-1][contours[-1][:, :, 1].argmin()][0])
extBot = tuple(contours[-1][contours[-1][:, :, 1].argmax()][0])
2 Answers

In order to get the top and bottom point of each contour, you need to iterate through the tuple containing all the contours.

In the following, we pick one contour c from the collection of contours. Draw the top and bottom most point:

for c in contours:
  top_point = tuple(c[c[:,:,1].argmin()][0])
  bottom_point = tuple(c[c[:,:,1].argmax()][0])
  img = cv2.circle(img, top_point, 6, (255, 255, 0), -1)
  img = cv2.circle(img, bottom_point, 6, (0, 255, 255), -1)

UPDATE:

The following snippet finds the top-most and bottom-most (Y-coordinate) among ALL contours in the image:

# initialize an array
cc = np.array([[0, 0]], dtype=int)

# iterate through every contour
for i, c in enumerate(contours):
    # reshape array storing contour boundary points
    c_modified = c.reshape(len(contours[i]), 2)
    # concatenate with initialized array
    cc = np.concatenate((cc, c_modified), axis = 0)

# avoiding first element in the initialized array
new_cc = cc[1:]

new_cc now contains the boundary coordinates of ALL contours.

Use np.max() and np.min() functions to get desired values:

bottom_most = np.max(new_cc[:,1])
top_most = np.min(new_cc[:,1])

Edit: Change this:

extTop = tuple(contours[-1][contours[-1][:, :, 1].argmin()][0])
extBot = tuple(contours[-1][contours[-1][:, :, 1].argmax()][0])
     

to:

extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])
Related