在公差范围内,确定两个线段是否属于同一线段的最有效方法是什么?

时间:2012-07-10 17:29:45

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

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

编辑:我想这是一个简短的说法:我试图以有效的方式将类似的线段聚集在一起。

说我有分段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将在容差范围内。但是你必须确保两个线段具有相同的“方向”,这在笛卡尔坐标或极坐标中计算是微不足道的。

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

3 个答案:

答案 0 :(得分:2)

你的问题是双重的:你想要比较长度差异和角度差异。要计算长度差异,您需要取第一行的长度并将其除以第二行的长度。

要获得角度差异,您可以使用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()

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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