简体   繁体   English

如何用两点画一条线,然后用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?

I am using opencv and python for programming and I am trying to draw a line between two points that I know their coordinates, and then let the line complete until it reaches the end of the contour as shown in the image bellow. 我正在使用opencv和python进行编程,并且尝试在知道其坐标的两个点之间绘制一条线,然后完成该线直到其到达轮廓的尽头,如下图所示。 The contour in my case is actually of an image face, but I have provided a circle here for explanation. 在我的情况下,轮廓实际上是像脸,但是我在这里提供了一个圆圈用于说明。 So what I am trying to achieve is to get the edge of the head at that point intersecting with the line and contour. 因此,我试图实现的目标是使头部的边缘与直线和轮廓线相交。 Is there a way to draw a line from two points and then let the line complete drawing until reaching the contour? 有没有办法从两个点画一条线,然后让线完成绘图直到到达轮廓? 在此处输入图片说明

I can think of one easy method off the top of my head that doesn't involve incrementally updating the image: on one blank image, draw a long line extending from point one in the direction of point two, and then AND the resulting image with the an image of the single contour drawn (filled). 我可以想到一种简单的方法,它不涉及增量更新图像:在一个空白图像上,绘制一条从第一点向第二点方向延伸的长线,然后将得到的图像与绘制(填充)的单个轮廓的图像。 This will stop the line at the end of the contour. 这将使线条停在轮廓的末端。 Then you can either use that mask to draw the line, or get the minimum/maximum x, y coords if you want the coordinates of the line. 然后,您可以使用该蒙版绘制线条,或者如果需要线条的坐标,则获得最小/最大x,y坐标。

To walk through an example, first we'll find the contour and draw it on a blank image: 为了遍历一个示例,首先我们将找到轮廓并将其绘制在空白图像上:

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

Then, if we have the points p1 and p2 , find the direction they're heading in and find a point far off in that distance and draw that line on a new blank image (here I used a distance of 1000 pixels from p1 ): 然后,如果我们有点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)

Then simply cv2.bitwise_and() the two images together 然后简单地将两个图像cv2.bitwise_and()

contour_line_img = cv2.bitwise_and(line_img, contour_img)

Here is an image showing the points, the line extending past the contour, and the line breaking off at the contour. 这是一张图像,显示了这些点,延伸经过轮廓的线以及在轮廓处断开的线。

轮廓断线

Edit: Note that this will only work if your contours are convex. 编辑:请注意,这仅在轮廓为凸形时才有效。 If there is any concavity and the line goes through that concave part, it will continue to draw on the other side of it. 如果有任何凹陷,并且线穿过该凹入部分,它将继续在其另一侧上绘制。 For eg in Silencer's answer, if both points were inside one of the ear and pointed towards the other ear, you'd want the contour to stop once it hit an edge, but mine will continue to draw on the other ear. 例如,在Silencer的答案中,如果两个点都在一只耳朵的内部并且指向另一只耳朵,则您希望轮廓在碰到边缘时停止,但是我的耳朵会继续在另一只耳朵上绘制。 I think an iterative method like Silencer's is the best for the general case, but I like the simplicity of this method if you know you have convex contours or if your points will be in a place to not have this issue. 我认为像Silencer's这样的迭代方法最适合一般情况,但如果您知道轮廓凸或如果要放置的点不存在此问题,则我喜欢这种方法的简单性。

Edit2: Someone else on Stack answered their own question about the Line Iterator class in Python by creating one: openCV 3.0 python LineIterator Edit2:堆栈上的其他人通过创建一个来回答关于Python中的Line Iterator类的问题: openCV 3.0 python LineIterator

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM