我使用 Python OpenCV 来骨架化图像,如下所示:
我想找到骨架的分支点
我不知道该怎么做。有什么想法吗?
最佳答案
这个问题已经很老了,但是如果其他人偶然发现了这个问题,并且希望得到一个不依赖于额外包并使用简单形态学操作的答案,您可能会发现以下内容很有帮助。
这个想法只是应用命中或未命中变换来搜索满足分支点条件的像素。骨架中的分支点是连接到三个或四个其他像素的像素。给定一个适当的结构元素列表 selems
,您可以优雅地在一个输出图像中组合几个命中或未命中的变换,如下所示。
import numpy as np
import scipy.ndimage as ndi
branches = np.zeros_like(skeleton, dtype=bool)
for selem in selems:
branches |= ndi.binary_hit_or_miss(skeleton, selem)
这是非常节省空间的,因为您直接将每个转换的结果添加到同一个结果数组中。现在的问题是如何创建结构元素列表。一种解决方案如下。
selems = list()
selems.append(np.array([[0, 1, 0], [1, 1, 1], [0, 0, 0]]))
selems.append(np.array([[1, 0, 1], [0, 1, 0], [1, 0, 0]]))
selems.append(np.array([[1, 0, 1], [0, 1, 0], [0, 1, 0]]))
selems.append(np.array([[0, 1, 0], [1, 1, 0], [0, 0, 1]]))
selems.append(np.array([[0, 0, 1], [1, 1, 1], [0, 1, 0]]))
selems = [np.rot90(selems[i], k=j) for i in range(5) for j in range(4)]
selems.append(np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]))
selems.append(np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]]))
最后两行仅在您还想检测具有四个分支的分支点时才需要。如果您只对三个分支感兴趣,则可以省略最后两行。
那么完整的解决方案就是
import numpy as np
import scipy.ndimage as ndi
selems = list()
selems.append(np.array([[0, 1, 0], [1, 1, 1], [0, 0, 0]]))
selems.append(np.array([[1, 0, 1], [0, 1, 0], [1, 0, 0]]))
selems.append(np.array([[1, 0, 1], [0, 1, 0], [0, 1, 0]]))
selems.append(np.array([[0, 1, 0], [1, 1, 0], [0, 0, 1]]))
selems.append(np.array([[0, 0, 1], [1, 1, 1], [0, 1, 0]]))
selems = [np.rot90(selems[i], k=j) for i in range(5) for j in range(4)]
selems.append(np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]))
selems.append(np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]]))
branches = np.zeros_like(skeleton, dtype=bool)
for selem in selems:
branches |= ndi.binary_hit_or_miss(skeleton, selem)
同样,您可以使用以下结构元素列表搜索端点。
selems = list()
selems.append(np.array([[0, 1, 0], [0, 1, 0], [0, 0, 0]]))
selems.append(np.array([[1, 0, 0], [0, 1, 0], [0, 0, 0]]))
selems = [np.rot90(selems[i], k=j) for i in range(2) for j in range(4)]
关于python - 如何从二进制骨架化图像中找到分支点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43037692/