如何在二进制图像线条中找到交点?

6
我有一张二进制图像,其中有曲线,如下所示,但我想知道如果它们被延伸,它们在哪里相交。
那么,你能给我一些关于以下问题的建议吗:
  • 延长线的端点,使其朝同一个方向
  • 如何找到相交点?
我考虑使用霍夫变换来找到直线,然后再找到相交点,但在某些图像中,我的线段端点不完全是直的。有没有一种方法只在线段末端找到它的方向,而不是整个线段,因为它是一个二进制图像?
感谢您的帮助

2
您可以采纳下面的建议,但如果您告诉我们更多关于您的全局问题,可能会发现比直接查找这些交集更好的整体解决方案。 - static_rtti
6个回答

4
应用膨胀和侵蚀操作将会延伸你的端点,效果如下:
(*Code in Mathematica*)
Erosion[Dilation[i, 10], 10]

这里输入图片描述

一个完整的解决方案可能是这样的:

r = Dilation[MorphologicalBranchPoints[
   Thinning[Binarize@Erosion[Dilation[i, 10], 10], 10]] // Colorize, 3]
ImageAdd[i, r]

enter image description here


1
当所有要填补的空隙大小相似且已知时,这应该能够比较好地工作。在其他情况下,可能需要自适应增长端点。一种想法是迭代地沿段的本地方向延伸端点以扩展段。 - Matthias Odisio
@Matthias,你的想法很好,我认为它可以从“规模”的概念中受益(这不是一件简单的事情)。 - Dr. belisarius

4

我认为你应该看一下霍夫变换。它可以从二进制表示(通常是边缘检测器的输出)中计算出直线方程。一旦你有了这些方程,计算相交点就像解决简单的难题一样容易。


+1 但是,Hough变换的缺点是它只能寻找(并假设)直线。OP似乎正在寻找某种样条近似(?)而不是相对任意曲线,这自然会更加困难。 - Joe Kington
展示如何计算霍夫变换输出的交点会很好。 - Alceu Costa
霍夫变换在我的应用中无法工作,因为我的大多数线条比我提供的示例图像更弯曲。 - Alex
1
我在我的问题中添加了另外几个例子。 - Alex

3
你可以尝试拟合三个相应的曲线,然后显式地求解方程得到两个交点。
有一些已经建立的曲线拟合模型。

2

使用霍夫变换,我得出了以下结果:

%# read and binarize image
I = imread('http://i.stack.imgur.com/XlxmL.jpg');
BW = im2bw(rgb2gray(I));

%# hough transform, detect peaks, then get lines segments
[H T R] = hough(BW, 'Theta',-10:10);   %# specific theta range
P  = houghpeaks(H, 5);
lines = houghlines(BW, T, R, P);

%# overlay detected lines over image
figure, imshow(BW), hold on
for k = 1:length(lines)
    xy = [lines(k).point1; lines(k).point2];
    plot(xy(:,1), xy(:,2), 'g.-', 'LineWidth',2);
end

%# find endpoints (intersections) and show them
xy = [vertcat(lines.point1);vertcat(lines.point2)];
[~,idx1] = min(xy(:,2));
[~,idx2] = max(xy(:,2));
xy = xy([idx1;idx2],:);     %# intersection points
plot(xy(:,1),xy(:,2), 'ro', 'LineWidth',3, 'MarkerSize',12)
hold off

screenshot


谢谢,但是如果图片有更多的曲线怎么办?比如我添加的第二个图片http://i.stack.imgur.com/NaHiI.jpg - Alex
我的解决方案是针对第一张图进行了微调。你可以尝试调整霍夫变换的参数来处理其他图片,但我认为形态学操作在一般情况下可能更适合(类似于@belisarius的解决方案)... - Amro

1

0
将轮廓填充到std :: vector >中,使用OpenCV库的findContours函数,然后对于任何不相交的两个轮廓(相交情况稍后解释),执行以下操作: 第一个轮廓是2D点A1 A2 .... An的序列,第二个轮廓是B1、B2、..、Bm,固定某些i > 0 && i < n,j > 0 && j < m,并使用(A1,...,Ai)进行外推以找到第一个轮廓的第一个端点的延伸,然后外推(An-i,...,An)以找到第一个轮廓的第二个端点的延伸:对于第二个轮廓(B1,...,Bj)和(Bm-j,...,Bm)也是如此: 现在,您可以将轮廓延伸到图像边界并检查它们是否相交。 我希望您知道如何在2D空间中找到线段的交点。 您必须对所有[Ai Ai + 1]和[Bj Bj + 1] i = 1,...,n-1和j = 1,...,m-1使用此功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接