【问题标题】:How to identify if the centroid point touches a line or not?如何识别质心点是否接触线?
【发布时间】:2020-06-28 07:01:17
【问题描述】:

我正在使用基于线路交叉检测的入侵检测算法。我已经使用方程 y = mx+c 开发了一个基本算法,但是当人接近线时,它会显示一些错误的检测。我需要一些建议,让它成为一个完美的触线算法。

【问题讨论】:

  • 在你的例子中,你想知道红点是否在绿线的左边吗?或者如果红点恰好是绿线的一个点?如果是第二种选择,您可能不得不考虑一个细长的矩形和非常小的圆形。
  • 感谢Gustavo的评论,我想知道红点是否正好是绿线上的一个点。你能解释一下怎么做吗

标签: python-3.x opencv deep-learning computer-vision intrusion-detection


【解决方案1】:

让线从点l0 到点l1。然后让质心为点p1。设向量l 是从l0l1pl0p1 的向量。然后您可以使用here 中描述的点积找到从点p1 到直线的距离。

您可能希望找到从您的点到线段的距离,然后根据该距离评估该点是否在线段上。如here 所述,这可以以类似的方式完成,但有更多的逻辑。

下面给出了使用numpy 的python 实现。它可以轻松扩展以处理N 质心,使您能够并行跟踪不同的对象。它通过将点投影到线段上并找到从该点到质心的距离来工作。

import numpy as np

def distance_from_line_segment_points_to_point(l0, l1, p1):
    l0 = np.array(l0)
    l1 = np.array(l1)
    p1 = np.array(p1)

    l_vec = l1 - l0
    p_vec = p1 - l0

    if (l0 == l1).all():
        return np.linalg.norm(p_vec)

    l_norm = np.linalg.norm(l_vec)
    l_unit = l_vec / l_norm

    t = np.dot(l_unit, p_vec)
    if t >= l_norm:
        p_proj = l1
    elif t <= 0:
        p_proj = l0
    else:
        p_proj = l0 + t * l_unit
    return np.linalg.norm(p1 - p_proj)

print(distance_from_line_segment_points_to_point([0, 0], [0, 0], [1, 1]))  # sqrt(2), 1.4
print(distance_from_line_segment_points_to_point([0, 0], [1, 0], [1, 1]))  # 1
print(distance_from_line_segment_points_to_point([0, 0], [1, 1], [0, 1]))  # sqrt(2)/2, 0.707

【讨论】:

    【解决方案2】:

    如果您的直线有起点和终点[x1, y1][x2, y2],那么直线方程为:

    y - y1 = m * (x - x1),其中m = (y2 - y1)/(x2-x1)

    然后您可以检查一个点是否属于线,替换xy,并检查另一个是否与线方程匹配。

    在 Pyhton 中:

    # the two points that define the line
    p1 = [1, 6]
    p2 = [3, 2]
    
    # extract x's and y's, just for an easy code reading
    x1, y1 = p1
    x2, y2 = p2
    
    m = (y2-y1)/(x2-x1)
    
    # your centroid
    centroid = [2,4]
    x3, y3 = centroid
    
    # check if centroid belongs to the line
    if (m * (x3-x1) + y1) == y3:
        print("Centroid belongs to line")
    
    

    但可能...

    ...计算红点与直线 (distance from a point to a line) 之间的距离,然后检查它是否足够近(即距离小于某个值),您将获得更好的结果。

    在 Python 中:

    # points that define the line
    p1 = [1, 6]
    p2 = [3, 2]
    x1, y1 = p1
    x2, y2 = p2
    
    centroid = [2,4]
    x3, y3 = centroid
    
    # distance from centroid to line
    import math # to calculate square root
    dist = abs((y2-y1)*x3 - (x2-x1)*y3 + x2*y1 - y2*x1)/math.sqrt((y2-y1)**2 + (x2-x1)**2)
    
    if dist < some_value:
        print("Near enough")
    

    【讨论】:

    • 如果您使用第一种解决方案,最好在它之前检查线条是否垂直(即if x1 == x2)。将此视为特殊情况,只需检查您的质心 x 是否也等于x1x2(即if x3 == x1)。
    • 其实我使用的是第二种方案。我理解这个案例,我正在测试它。我认为对于垂直线和水平线也显示相同的问题,对吗?除以零
    • 使用上面的代码,只有当行是垂直的时候才会出现除以零。
    • 另外,如果你想用它来处理实时视频的帧,也许你可以通过not使用sqrt来提高性能。相反,您可以使用平方长度。
    • 是的,Gustavo,我现在正在使用它。我也是这么想的。我非常感谢您提供即时解决方案。太感谢了。让我现在检查一下,我会在最终结果后回复您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多