How to obtain boundary coordinates of binary mask with holes?

十年热恋 提交于 2019-12-14 01:53:01

问题


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:


回答1:


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.



来源:https://stackoverflow.com/questions/58885816/how-to-obtain-boundary-coordinates-of-binary-mask-with-holes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!