【问题标题】:What is the most efficient way to determine if two line segments are part of the same segment, within a tolerance?在公差范围内确定两条线段是否属于同一段的最有效方法是什么?
【发布时间】:2012-07-10 05:56:54
【问题描述】:

编辑:更改了标题。我对这两个段是否相同不太感兴趣,而是如果它们彼此共线,则在一定的公差范围内。如果是这样,那么这些线应该聚集在一起作为一个单独的段。

编辑:我想一个简短的说法:我正在尝试以一种有效的方式将相似的线段聚集在一起。

假设我有线段 f (fx0, fy0)(fx1, fy1)g (gx0, gy0)(gx1, gy1)

这些来自诸如计算机视觉算法边缘检测器之类的东西,在某些情况下,两条线基本相同,但由于像素公差而被视为两条不同的线。

有几种情况

  • fg 共享完全相同的端点,例如:f = (0,0), (10,10) g = (0,0), (10,10)
  • fg 共享大致相同的端点,并且长度大致相同,例如:f = (0,0.01), (9.95,10) g = (0,0), (10,10)
  • fg 的子集,这意味着它的端点落在g 段内,并与g 段共享相同的斜率。想象一条粗略的线,笔在其中来回移动以使其变粗。例如:f = (4.00, 4.02), (9.01, 9.02) g = (0,0), (10,10)

以下内容将视为相同:

  • fg在一定的tolerance以上有斜率差
  • fg 可能具有相同的斜率,但相隔超过 tolerance 的距离,即平行线
  • fg 在同一平面和同一坡度上,但根本不重叠...即虚线内的一组线段。

判断它们是否相同的最简单方法是gx1 - fx1 <= tolerance(对其他三个点重复),但在某些情况下,f 行可能比g 行短(同样,因为像素差异和/或照片扫描不佳)。

那么将两个线段转换成极坐标并比较角度会更好吗?在这种情况下,两个 rho 将在容差范围内。但是你必须确保两条线段具有相同的“方向”,这在笛卡尔坐标或极坐标中计算是微不足道的。

所以这很容易找到一种方法,但我只是想知道是否有一种更清洁的方法,基于我早已忘记的线性代数?

【问题讨论】:

  • 我认为你需要更清楚。指定线段需要四个数字,用于线的开始和结束的坐标,而您似乎为每条线指定了两个。另外,您是否认为从 (0,0) 到 (1,1) 的线与从 (0,0) 到 (10,10) 的线“相同”?显然它们都在同一个方向,但一个比另一个长得多。
  • 哎呀,好电话。我添加了一些明确的术语和通过/失败的情况。谢谢。是的,我会认为 (0,0) 到 (1,1) (或轻微的变化,例如 [0, 0] 到 [1, 1.02])与 (0,0) 到 (10,10) 相同),出于本练习的目的。

标签: ruby math opencv computer-vision cluster-analysis


【解决方案1】:

您的问题有两个方面:您想比较长度差异和角度差异。要计算长度差,您需要将第一行的长度除以第二行的长度。

要获取角度差异,您可以使用atan,或者我最喜欢的:

angle = acos(abs((u dot v)/(u.length * v.length)))

希望这会有所帮助。很抱歉之前的回答有误。

旧答案:

这里有一个想法:为什么不将两条线段的起点和终点的差异与其中一条线的总长度进行比较?然后你的差异函数看起来像:

def difference(Line l1, Line l2):
    # Distance between first point on first line and first point on second line
    first_point_diff = (Line(l1.x1, l2.x1, l1.y1, l2.y1).length())

    # Distance between first point on first line and first point on second line
    second_point_diff = (Line(l1.x2, l2.x2, l1.y2, l2.y2).length())

    return (first_point_diff + second_point_diff)/l1.length()

此函数将返回两行之间的“差异”作为第一行总长度的一部分。

【讨论】:

  • 我认为比较角度的想法更安全,因为可能存在 y2-y1 = 0 的情况。atan2(y, x) 会处理这种情况。
【解决方案2】:

你能用坐标来定义线条的方程吗?如果是这样,那么您可以在方程组中使用这两个方程,求解系统,并找出线是否相交以及相交的位置。如果这些线根本不相交,但它们之间的距离非常小,或者在公差范围内,您可以将它们视为一条线。

【讨论】:

  • 在十字路口的情况下,如果坡度不同,那将是一个问题,如果它们不同足够......然后我想可能会有一个else分支,如果斜率相同,看看两点之间的距离?但是哪两点,在一个线段只是另一个线段的一小部分的情况下?我可以设想通过/失败的条件,但我不知道它是否有效,与一些矩阵运算相比,它会给我一个单一的值来判断公差?
【解决方案3】:

如果您只想查看它们是否在同一个方向上,您不能只考虑点积除以幅度吗?越接近 1,两条线之间的对齐越接近。

【讨论】:

    猜你喜欢
    • 2011-03-17
    • 2021-10-03
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    • 2012-08-02
    相关资源
    最近更新 更多