如何使用 Python 和 DLib 找到线的左侧或右侧的点?
Posted
技术标签:
【中文标题】如何使用 Python 和 DLib 找到线的左侧或右侧的点?【英文标题】:how to find a point is on left or right side of line using Python and DLib? 【发布时间】:2020-11-02 23:47:49 【问题描述】:我正在尝试在 Dlib/OpenCV/Numpy/Scipy 中查找现有 API,以找出一个点在线的左侧或右侧。
import dlib
a = dlib.point(0, 0)
b = dlib.point(20, 20)
line = dlib.line(a, b)
dlib.distance_to_line(line, dlib.point((-50, 4))) # provides absolute distance.
寻找解决方案
一个简单的 API,告诉它在一行的左侧/右侧。
example
dlib.where_is_the_point(line, dlib.point((-50, 4)) # if returns negative means left side.
我目前的解决方案
我写了一个数学来找到一个点是左侧还是右侧。所以下面的函数返回一个d
,基于d
的符号我可以判断它是左还是右。一种硬编码的方式,不喜欢下面的解决方案。
def where_it_is(self, target: Point):
d = (target.x - self.p1[0]) * (self.p2[1] - self.p1[1]) - (target.y - self.p1[1]) * (self.p2[0] - self.p1[0])
return d
【问题讨论】:
【参考方案1】:我希望您在 Math StackExchange 上参考这一点:https://math.stackexchange.com/questions/274712/calculate-on-which-side-of-a-straight-line-is-a-given-point-located。简单来说,假设你有三个点:一个表示线开始的点,一个表示线结束的点和一个查询点,你可以计算这三个点之间的叉积并检查符号结果。事实上,Stack Overflow 上的这个答案使用它来确定一个点是否在一条线的左侧:How to tell whether a point is to the right or left side of a line。
我们可以使用此行为来帮助定义一个点是在左侧还是右侧,并且可以根据您使用 Python 和 DLib 的事实进行调整。因此,如果叉积的符号为正,则该点位于线的左侧。如果符号为负,则该点位于该线的右侧。如果叉积为 0,则该点在直线上共线。由于数值不精确,与 0 进行精确比较是非常危险的,因为在大多数情况下,很少会得到精确的 0,因此与精确的 0 进行比较可能会给您错误的结果。因此,您需要查看该值是否小于一个小的阈值,例如1e-9
用于共线检查。
对于您的示例行,请注意它本质上是y = x
,因此我们绝对可以定义应该出现在该行左侧和右侧的众所周知的点。
因此:
def where_it_is(line, point):
aX = line.p1.x
aY = line.p1.y
bX = line.p2.x
bY = line.p2.y
cX = point.x
cY = point.y
val = ((bX - aX)*(cY - aY) - (bY - aY)*(cX - aX))
thresh = 1e-9
if val >= thresh:
return "left"
elif val <= -thresh:
return "right"
else:
return "point is on the line"
测试一下:
import dlib
a = dlib.point(0, 0)
b = dlib.point(20, 20)
line = dlib.line(a, b)
pt1 = dlib.point(2, -2) # Should appear on the right
pt2 = dlib.point(5, 10) # Should appear on the left
pt3 = dlib.point(2, 2) # Point should be collinear
print(where_it_is(line, pt1))
print(where_it_is(line, pt2))
print(where_it_is(line, pt3))
我已将点定义为在线的左侧、右侧和共线。我们得到:
In [40]: %paste
print(where_it_is(line, pt1))
print(where_it_is(line, pt2))
print(where_it_is(line, pt3))
## -- End pasted text --
right
left
point is on the line
【讨论】:
谢谢,我无法理解为什么我们需要阈值以及如何确定阈值,因为我试图在边缘设备(如 Nano、TX2)上运行此代码。是否有任何经验法则或者我们可以使用1e-9
作为标准值?
阈值是因为浮点精度。具体来说,与完全零进行比较是非常危险的,因此您通常使用一个小的常数来代替。这里没有规则,但它通常是一个很小的值,您预计不会对您的计算产生重大影响。 1e-9 只是我选择的一个值。以上是关于如何使用 Python 和 DLib 找到线的左侧或右侧的点?的主要内容,如果未能解决你的问题,请参考以下文章