【问题标题】:How to find intersections in binary image lines?如何在二值图像行中找到交点?
【发布时间】:2011-07-12 11:13:59
【问题描述】:

我有一个如下图所示的带有曲线的二进制图像,但我想知道如果它们被延长,我如何找到它们相交的位置。

那么你能给我一些建议吗:

  • 沿同一方向延伸线端点,
  • 如何找到路口?

我曾考虑使用霍夫变换来查找线,然后是相交,但在某些图像中,我的线端点并不完全笔直。有没有办法只在它的末尾找到线的方向,而不是在整条线上,因为它是一个二进制图像?

感谢您的帮助

【问题讨论】:

  • 您可以采纳下面给出的好建议,但如果您告诉我们更多有关您的全球性问题的信息,可能会发现比直接找到这些交叉点更好的整体解决方案。

标签: matlab image-processing computer-vision


【解决方案1】:

应用膨胀然后腐蚀将扩展您的端点,如下所示:

(*Code in Mathematica*)
Erosion[Dilation[i, 10], 10]

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

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

【讨论】:

  • 当所有要填充的空白都具有相似的已知大小时,这应该可以很好地工作。在其他情况下,可能需要自适应增长的端点。一种想法是在片段的局部方向上迭代地扩展端点处的片段。
  • @Matthias Yours 是个好主意,我认为它可以从 scale 的概念中受益(这不是一件小事)。
【解决方案2】:

我认为你应该看看Hough transform。它根据二进制表示(通常是边缘检测器的输出)计算线方程。一旦你有了这个,计算交叉点就是小菜一碟。

【讨论】:

  • +1 但是,缺点是霍夫变换将寻找(并假设)直线。 OP 似乎正在寻找某种样条近似(?)到相当任意的曲线,这自然有点困难。
  • 在给定 Hough 变换输出的情况下,展示如何计算交点会很好。
  • 霍夫变换不适用于我的应用程序,因为我的大部分线条比我提供的示例图像弯曲得多
  • 我在我的问题中添加了另外几个例子
【解决方案3】:

您可以尝试拟合三个对应的曲线,然后显式求解两个交点的方程。

存在一些已建立的曲线拟合模型。

【讨论】:

    【解决方案4】:

    这是我使用霍夫变换得出的结论:

    %# 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
    

    【讨论】:

    • 谢谢,但是有更多曲线的图像呢?比如我加的第二个i.stack.imgur.com/NaHiI.jpg
    • 我的解决方案针对第一张图片进行了微调。您可以尝试为其他人使用霍夫变换的参数,但我认为morphological operations 可能更适合一般情况(类似于@belisarius 解决方案)...
    【解决方案5】:

    只需看看你的线条,它们或多或少都是直线(不是凹凸曲线)在我看来,有一种更简单、更明显的方法,因为你知道三条线的任一端点。你总是可以通过分别求解 x 和 y 得到交集。

    http://zonalandeducation.com/mmts/intersections/intersectionOfTwoLines1/intersectionOfTwoLines1.html

    祝你好运

    【讨论】:

      【解决方案6】:

      使用 OpenCV 库中的 findContours 函数将轮廓填充到 std::vector<std::vector<cv::Point> > 中,然后对于不相交的任何两个轮廓(我稍后会解释相交的情况)执行以下操作: 第一个轮廓是二维点 A1 A2 ...的序列。一个和第二个轮廓是 B1,B2,..,Bm,固定一些 i > 0 && i 0 && j

      【讨论】:

        猜你喜欢
        • 2021-11-22
        • 2019-12-14
        • 1970-01-01
        • 2021-12-11
        • 2019-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多