【发布时间】:2012-11-26 23:44:17
【问题描述】:
我有白色背景和简单形状的图像(每张图像都有一个形状)。我想确定某个点 (x,y) 是否在形状内。如何使用 opencv 做到这一点?
【问题讨论】:
标签: image opencv image-processing computer-vision detection
我有白色背景和简单形状的图像(每张图像都有一个形状)。我想确定某个点 (x,y) 是否在形状内。如何使用 opencv 做到这一点?
【问题讨论】:
标签: image opencv image-processing computer-vision detection
使用pointPolygonTest 函数。 Here's教程。
【讨论】:
要确定一个点是在形状的内部、外部还是边缘,您可以使用cv2.pointPolygonTest() 检查该点是否在轮廓内。该函数返回+1、-1 或0,分别指示一个点是在轮廓内部、外部还是在轮廓上。假设我们已经有了形状的轮廓,我们可以简单地将轮廓和(x,y) 点传递给函数。
result = cv2.pointPolygonTest(contour, (x,y), False)
在函数中,第三个参数是measureDist。如果是True,它会找到图像中的点与轮廓之间的最短距离。如果False,它会查找该点是在轮廓内部、外部还是在轮廓上。由于我们不想找到距离,我们将measureDist 参数设置为False
这是一个找到正方形轮廓然后检查点是否在轮廓内的示例
测试图片
找到轮廓和检查点后的图像
结果
点1:-1.0
point2: 1.0
point3: 0.0
因此point1在外面,point2在里面,point3在轮廓上
import cv2
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray, 120, 255, 1)
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
point1 = (25, 50)
point2 = (200, 250)
point3 = (200, 350)
# Perform check if point is inside contour/shape
for c in cnts:
cv2.drawContours(image, [c], -1, (36, 255, 12), 2)
result1 = cv2.pointPolygonTest(c, point1, False)
result2 = cv2.pointPolygonTest(c, point2, False)
result3 = cv2.pointPolygonTest(c, point3, False)
# Draw points
cv2.circle(image, point1, 8, (100, 100, 255), -1)
cv2.putText(image, 'point1', (point1[0] -10, point1[1] -20), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), lineType=cv2.LINE_AA)
cv2.circle(image, point2, 8, (200, 100, 55), -1)
cv2.putText(image, 'point2', (point2[0] -10, point2[1] -20), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), lineType=cv2.LINE_AA)
cv2.circle(image, point3, 8, (150, 50, 155), -1)
cv2.putText(image, 'point3', (point3[0] -10, point3[1] -20), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), lineType=cv2.LINE_AA)
print('point1:', result1)
print('point2:', result2)
print('point3:', result3)
cv2.imshow('image', image)
cv2.waitKey()
【讨论】:
如果你想访问凸包内的所有点,你可以做遮罩
我首先用 cv2.fillPoly() 在黑框上绘制我的凸包白色来解决这个问题
black_frame = np.zeros_like(your_frame).astype(np.uint8)
cv2.fillPoly(black_frame , [hull], (255, 255, 255))
mask = black_frame == 255
targetROI = your_frame * mask
black_frame = np.zeros_like(your_frame).astype(np.uint8)
cv2.fillPoly(black_frame , [hull], (255, 255, 255))
mask = black_frame == 255
targetROI = your_frame * mask
【讨论】: