如何用opencv从两点画一条线,然后让线完成绘制,直到到达一个等高线点,python?

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

我能想到一个不涉及增量更新图像的简单方法:在一张空白图像上,画一条从第一点向第二点方向延伸的长线,然后以及绘制(填充)单个轮廓图像的结果图像。这将在轮廓的末端停止线。然后,您可以使用该掩码绘制线条,或者如果您想要线条的坐标,则获取 minimum/maximum 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,找到它们前进的方向并找到距离该距离很远的点,然后在新的空白图像上画那条线(这里我用了距离p11000像素的距离):

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 中的行迭代器 class 的问题