找到形状的线条

时间:2015-09-22 03:07:12

标签: computer-vision hough-transform

我有一个二进制图像,我正在寻找一种可靠的方法来查找形状和拓扑中的线条(线条如何连接)。

我已经在matlab中进行了实验(尽管我要求的是使用哪种方法)。

我尝试在二进制图像上使用骨架化,然后使用霍夫变换,有时工作但不是一个强大的解决方案。我在边界干扰中挣扎。

有没有人能指出我在这里使用哪种方法(以及以什么顺序)。

Start (binary image) End result I want

Binary file for testing

2 个答案:

答案 0 :(得分:2)

坦率地说,我一直在监视这个问题一段时间,希望看到有用的答案。任务本身似乎并不复杂(而且我会尝试证明这一点),但优雅的解决方案仍然离我很远。

前段时间我解决了类似的任务,它确实看起来像我的基本本土解决方案,您的初始示例很容易追溯:

enter image description here

它只是一个简单的扫描(1),垂直和水平线识别(2)以及更复杂区域的进一步分析(3)。对所有区域进行分析(3),找到交叉点并对其进行优化并不难(4)。

结果非常粗糙,但它证实了这种方法的可行性。

我明白这与Matlab有点远,但我只想强调几个重要时刻:

  • 骨架化可能会破坏初始几何
  • 对骨架的进一步分析似乎有点棘手且不可靠
  • 具有一定的增强品质,您可以通过更简单的方法追踪图像
BTW,在我的方法中,可以并行执行不同的操作。扫描步骤是可调节的,即使扫描次数减少,结果也相当不错:

enter image description here

通过更多步骤,可以更精确地识别交叉点:

enter image description here

我得出结论,使用初始图像提供的所有信息非常重要。所有简化等都将消除有价值的facts增加任务的整体复杂性。

<强>更新

如果数字没有大部分垂直和水平线,这种方法会起作用吗?

这些步骤非常独立,因此没有严格要求有垂直或水平线。当然,识别交叉点并进行一些额外的调整以提高准确性是一项更复杂的任务。

enter image description here

很容易看到形状开始和结束时垂直线引入了一些重大错误。非常直接的优化为我们提供了更好的结果:

enter image description here

答案 1 :(得分:0)

这确实是一个棘手的问题,从二进制图像到图形(即拓扑)。从根本上讲,涉及从像素和2D图像数据的离散世界,到节点和连接的抽象数据结构......

但是什么可以提供“粘合剂”?我担心这是一个悬而未决的问题,需要对视觉数据进行复杂的解释。

幸运的是,其他人在python中共享了一个很好的尝试:http://planet.lengrand.fr/?post_id=267

(这显然假设一个完整的python安装NetworkX和任何其他依赖项。我通过一些调用,例如> brew install opencv; pip install networkx; brew install graph-tool; brew install graphviz在Mac上用自制软件做了这个。下面的ipython笔记本也使用了http://scikit-image.orghttp://mahotas.readthedocs.org/en/latest/ - 非常令人兴奋的计算机视觉和图像处理代码鸡尾酒!最后:你当然需要安装ipython ......)

以下是一个示例(首先从上面加载下载的笔记本中的所有内容 - 所有内容均来自:> ipython —pylab):

%run C8Skeleton_to_graph-01.ipynb

import scipy.io as sio # Need this to load matlab files...

mat = sio.loadmat('bw.mat')

img = np.zeros((30,70),np.uint8) # Buffered image border

img[5:25,5:65] = mat['BW'] # Insert matrix data into middle

skeleton = mh.thin(img) # Do skeletonization... 

graph = nx.MultiGraph() # Graph we’ll create

C8_Skeleton_To_Graph_01(graph, skeleton) # Do it!

figure(1)
subplot(211)
plt.imshow(img,plt.get_cmap('gray'), vmin=0, vmax=1, origin='upper');
subplot(212)
plt.imshow(skeleton,plt.get_cmap('gray'), vmin=0, vmax=1, origin='upper');

figure(2)
nx.draw(graph)

显示原始提供的Matlab数据的骨架化(边缘周围有缓冲区):

Skeletonization the original data.

结果如下图所示:

enter image description here

请注意,图形拓扑和布局与细化图像的结构相对应 - 包括最后创建的“杂散”。这是一个持续的问题/研究领域,采用这种方法......

编辑:但可以通过删除图中的杂散弧(导致度数== 1的叶节点)来解决。 e.g。

remove = [node for node,degree in graph.degree().items() if degree == 1]

graph.remove_nodes_from(remove)

nx.draw(graph)

Trimmed graph