【问题标题】:Drawing a line given the angle and a point on the line在给定角度和线上的一个点的情况下绘制一条线
【发布时间】:2017-08-04 06:48:16
【问题描述】:

在我的图像中,我有一个三角形(代表一个箭头)。该箭头定义了在同一图像中进一步搜索的方向和区域。例如,如果我有一个在 x 轴上旋转 30 度的三角形,并且它的尖端位于图像中的 (250,150) 处。我想在三角形的尖端找到并画一条法线,如下图所示。

在上图中,我有三角形中蓝线的角度,法线要绘制到该角度。三角形的尖端也是已知的,它是法线上唯一已知的点。

下面给出了我的 python 函数代码。这段代码画了一条线,穿过尖端但不一定是 NORMAL 到蓝线。

def draw_intercepts(img,triangle):
    tip=triangle["tip"]
    x1=tip[0]
    y1=tip[1]
    arrow_angle=triangle["arrow_angle"]
    y_intercept=int(y1+((1/np.tan(arrow_angle))*x1))
    x_intercept=int(x1+(np.tan(arrow_angle)*y1))
    cv2.line(img,(x_intercept,0),(0,y_intercept),[0,0,255],3,cv2.LINE_AA)

此代码是按照对这篇文章的回答编写的: https://math.stackexchange.com/questions/2381119/how-to-find-slope-x-and-y-intercepts-given-angle-to-the-normal-vector-and-a-poi

注意: 我按照建议更新了代码:

def draw_intercepts(img,triangle):
    tip=triangle["tip"]
    x1=tip[0]
    y1=tip[1]
    arrow_angle=triangle["arrow_angle"]
    arrow_angle_rad=np.radians(arrow_angle)
    y_intercept=int(y1+((1/np.tan(arrow_angle_rad))*x1))
    x_intercept=int(x1+(np.tan(arrow_angle_rad)*y1))
    cv2.line(img, (x_intercept, 0), (0, y_intercept), [0, 0, 255], 3, cv2.LINE_AA)

这解决了问题。 现在,当 arrow_angle 位于第一或第三象限时,这条线可以完美绘制,例如0

【问题讨论】:

  • 您在使用np.tan()之前是否将角度转换为弧度?
  • 不,我提供了以度为单位的角度。让我试试看。
  • np.radians()可以帮助你。
  • 现在可以用了吗?
  • 感谢@Gribouillis,我已经更新了相关代码。是的,它部分起作用。它在第 1 和第 3 象限中有效,但在第 2 和第 4 象限中表现出未知行为。

标签: python image opencv geometry augmented-reality


【解决方案1】:

请注意,“在截距段中”使用的线方程不是通用的 - 不适用于水平线和垂直线。对于拦截进近情况 0、Pi/2、Pi、3*Pi/2 或 -Pi/2 必须分别处理。

如果你arrow_angle 是蓝线:

c = -Sin(arrow_angle)
s = Cos(arrow_angle)

如果你arrow_angle是红线:

c = Cos(arrow_angle)
s = Sin(arrow_angle)

然后通过点画线

 (x1 - c * 4096, y1  - s * 4096) and (x1 + c * 4096, y1  + s * 4096)

(我使用了与屏幕尺寸相当的任意大常数)

【讨论】:

  • @Gribouillis 但是使用非一般方程进行点查找是错误的方式 - 它可能导致错误/异常。
  • 是的,这是真的。你的公式看起来不错,但我没有 opencv 经验,为什么是 4096 ?您也可以计算所有情况下的截距。
  • @Gribouillis 因为 OP 没有指定红线的长度,他只是使用了一些大常数来确保红线会跨越整个屏幕
  • @MBo 你是对的。当在无穷远处发现其中一个截距时,我也遇到了水平线或垂直线的问题。好吧,我有蓝线的“arrow_angle”,我想用它来画红线。你的答案是否代表相同的场景?
  • @Gribouillis 4096 是任意值。 OpenCV 将剪线:The line is clipped by the image boundaries 如果直线垂直(Pi/2),则与垂直轴没有截距,水平线(角度 0/Pi)与水平轴没有截距。使用拦截方法,这些情况必须分开处理(作者不这样做)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多