【问题标题】:How to draw a line from two points and then let the line complete drawing until reaching a contour point with opencv, python?如何从两点画一条线,然后让线完成绘制,直到用opencv,python到达轮廓点?
【发布时间】:2017-11-12 07:33:08
【问题描述】:

我正在使用 opencv 和 python 进行编程,我试图在我知道它们的坐标的两个点之间画一条线,然后让这条线完成,直到它到达轮廓的末端,如下图所示。在我的例子中,轮廓实际上是一个图像面,但我在这里提供了一个圆圈来进行解释。所以我想要实现的是让头部的边缘在那个点与线和轮廓相交。有没有办法从两点画一条线,然后让线完成绘制直到到达轮廓?

【问题讨论】:

  • 你可以使用 openCV 的 LineIterator 跟踪一条线的所有像素,直到你碰到一个轮廓像素。但不确定 Python api 中是否存在 LineIterator...
  • 是的,我认为它存在于 python 中
  • @Micka 邪恶的,不知道 OpenCV 有这样的功能! Stack 上的某个人实际上为 Python 创建了自己的函数版本:stackoverflow.com/questions/32328179/…
  • 谢谢,我也去看看这个。
  • 但请注意,在特殊情况下,您必须选择 4-connected line drawing/traversal(而不是 8-connected)以免错过轮廓像素。

标签: python opencv line draw opencv-contour


【解决方案1】:

我能想到一种不涉及增量更新图像的简单方法:在一张空白图像上,从第一点向第二点的方向画一条长线,然后将生成的图像与绘制(填充)的单个轮廓的图像。这将在轮廓末端停止线条。然后,您可以使用该蒙版来绘制线条,或者如果您想要线条的坐标,则可以获取最小/最大 x、y 坐标。

通过一个示例,首先我们将找到轮廓并将其绘制在空白图像上:

contours = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[1]
contour_img = np.zeros_like(img)
cv2.fillPoly(contour_img, contours, 255)

然后,如果我们有点 p1p2,找到它们前进的方向并在该距离内找到一个远离该点的点,然后在新的空白图像上绘制该线(这里我使用了距离p1 的 1000 像素):

p1 = (250, 250)
p2 = (235, 210)

theta = np.arctan2(p1[1]-p2[1], p1[0]-p2[0])
endpt_x = int(p1[0] - 1000*np.cos(theta))
endpt_y = int(p1[1] - 1000*np.sin(theta))

line_img = np.zeros_like(img)
cv2.line(line_img, (p1[0], p1[1]), (endpt_x, endpt_y), 255, 2)

然后只需cv2.bitwise_and()两张图片一起

contour_line_img = cv2.bitwise_and(line_img, contour_img)

这是一张图像,显示了点、延伸超出轮廓的线以及在轮廓处断开的线。

编辑:请注意,这仅在您的轮廓是凸形的情况下才有效。如果有任何凹陷,并且线穿过那个凹​​陷部分,它将继续在它的另一侧绘制。例如在 Silencer 的回答中,如果两个点都在一只耳朵内并指向另一只耳朵,你会希望轮廓在碰到边缘时停止,但我的会继续在另一只耳朵上画。我认为像 Silencer 这样的迭代方法最适合一般情况,但如果您知道自己有凸轮廓,或者如果您的点位于不存在此问题的地方,我喜欢这种方法的简单性。

Edit2:Stack 上的其他人通过创建一个来回答他们自己关于 Python 中 Line Iterator 类的问题:openCV 3.0 python LineIterator

【讨论】:

  • 代码确实可以,但是为什么你设置的值1000是图片宽度和高度的近似值?
  • @Neda'a 是的,它只是行的长度(以像素为单位),您可以使用任何长的长度。图像的对角线是图像中可能的最长线,因此通常使用它可能是一个很好的值,以确保线延伸到图像的末端。因为我只是在画线,所以线是否超出图像边界并不重要——它只会将它画到图像的边缘。
  • @Neda'a 确保将其中一个答案标记为已接受的解决方案,如果它们适合您的话。另请参阅我对您的 OP 关于 Python 中的 Line Iterator 方法的评论。
猜你喜欢
  • 2021-06-29
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 2018-03-15
  • 2020-07-04
  • 2020-07-06
相关资源
最近更新 更多