python - 如何用两点画一条线,然后用opencv,python画线直到到达轮廓点?

标签 python opencv line draw opencv-contour

我正在使用opencv和python进行编程,我试图在两个我知道它们坐标的点之间绘制一条线,然后让该线完成,直到到达轮廓的尽头,如下图所示。在我的情况下,轮廓实际上是像脸,但在此我提供了一个圆圈用于说明。因此,我试图实现的目标是使头部的边缘与直线和轮廓线相交。有没有办法从两个点画一条线,然后让线完成绘图直到到达轮廓?
enter image description here

最佳答案

我可以想到一个简单的方法,它不涉及增量更新图像:在一个空白图像上,绘制一条从第一点向第二点方向延伸的长线,然后将得到的图像与绘制(填充)的单个轮廓的图像。这将使线条停在轮廓的末端。然后,您可以使用该蒙版绘制线条,如果需要线条的坐标,则可以获取最小/最大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)

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

Line breaking at contour

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

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

关于python - 如何用两点画一条线,然后用opencv,python画线直到到达轮廓点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47246540/

相关文章:

python - 将多列附加到数据框

OpenCV 从鼠标回调函数返回值

iphone - 如何消除 iPhone 上常见的 HTML 电子邮件中的白线

android - 使用 Processing 和 Opencv 进行 android 开发?

c++ - Opencv C++ 人脸检测代码不起作用

html - 水平线的 HR 标签不起作用

android - 去掉 TabWidget 下的那一行

python - Google Calendar API 仅获取日历的第一个事件

python - Configparser 和带 % 的字符串

Python邮件发送TypeError : Expected string or buffer