如何获得带孔的二元掩模的边界坐标? [英] How to obtain boundary coordinates of binary mask with holes?

查看:104
本文介绍了如何获得带孔的二元掩模的边界坐标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下图像:

我想获取一个列表,其中每个斑点的外轮廓和​​内轮廓的坐标为(x, y)(我们将其称为斑点A和B).

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()

(x, y)坐标列表A和B中绘制蓝色和红色的所需输出图像:

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()

当然,可以使用NumPy优化获取属于同一斑点的所有轮廓,但是在这里循环感觉最直观.我忽略了所有其他内容(skimage,Matplotlib),因为它们在这里似乎并不相关.如我所说,(x, y)坐标已经存储在contours中.

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.

希望有帮助!

我尚未验证,如果OpenCV始终连续获取属于一个最外部轮廓的所有轮廓,或者例如(例如)随后存储了给定层次结构级别的所有轮廓.因此,对于更复杂的层次结构,应事先进行测试,或者应从一开始就使用使用NumPy进行的索引查找.

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.

这篇关于如何获得带孔的二元掩模的边界坐标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆