简体   繁体   中英

How to obtain boundary coordinates of binary mask with holes?

I have the following image:

测试图像

I would like to obtain a list with (x, y) -coordinates of the outer and inner contour for each blob (let's call them blob A and B).

import cv2
from skimage import measure

blob = cv2.imread('blob.png', 0)
contours, hier = cv2.findContours(blob, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
labels = measure.label(blob)
props = measure.regionprops(labels)

for ii in range(0,len(props))
xy = props[ii].coords

plt.figure(figsize=(18, 16))
plt.imshow(blob, cmap='gray')
plt.plot(xy[:, 0], xy[:,1])
plt.show()

Desired output image where blue and red are drawn from the (x, y) coordinate list A and B:

期望的输出

You get the (x, y) -coordinates directly from cv2.findContours . To identify the single blobs, have a look at the hierarchy hier . The fourth index tells you, to which outer (or parent) contour a possible inner (or child) contour is related. Most outer contours have an index of -1 , all other have non-negative values. So, for plotting/drawing, a naive approach would be, while iterating the contours, to increase a blob counter every time you see a -1 , and draw all contours with the same color until the next -1 shows.

import cv2
from skimage import io         # Only needed for web grabbing images, use cv2.imread for local images

# Read image; find contours with hierarchy
blob = io.imread('https://i.stack.imgur.com/Ga5Pe.png')
contours, hier = cv2.findContours(blob, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Define sufficient enough colors for blobs
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]

# Draw all contours, and their children, with different colors
out = cv2.cvtColor(blob, cv2.COLOR_GRAY2BGR)
k = -1
for i, cnt in enumerate(contours):
    if (hier[0, i, 3] == -1):
        k += 1
    cv2.drawContours(out, [cnt], -1, colors[k], 2)

cv2.imshow('out', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出

Of course, obtaining all contours belonging to the same blob can be optimized using NumPy, but looping feels most intuitive here. I omitted all the other stuff (skimage, Matplotlib), since they didn't seem relevant here. As I said, the (x, y) -coordinates are already stored in contours .

Hope that helps!


EDIT: I haven't validated, if OpenCV always obtains all contours belonging to one most outer contour continously, or if - for example - all contours for a given hierarchy level are stored subsequently. So, for more complicated hierarchies, this should be tested beforehand, or the mentioned index finding using NumPy should be used right from the start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM