OpenCV Python 如何找到图像中点与轮廓之间的最短距离?
我们可以使用 cv2.pointPolygonTest() 计算图像上一个点与轮廓之间的最短距离,将轮廓点坐标和点坐标作为参数传递给它。在使用 cv2.pointPolygonTest() 之前,我们需要计算图像中的轮廓。我们可以按照以下步骤来找到给定点与图像中对象轮廓之间的最短距离-
- 导入所需的库。在以下所有Python示例中,所需的Python库是 OpenCV 。确保已经安装它。
-
使用 cv2.imread() 读取输入图像。使用这种方法读取的RGB图像的格式为BGR。可选地,将读取的BGR图像分配给img。
-
现在,使用下面的 cv2.cvtColor() 函数将此BGR图像转换为灰度图像。可选地将转换后的灰度图像分配给 gray。
-
对灰度图像应用阈值处理,将其转换为二进制图像。调整第二个参数( threshValue )以获得更好的二进制图像。
-
在二进制图像中查找轮廓。
-
将第一个轮廓选择为 cnt ,或循环遍历所有轮廓。
-
使用 cv2.pointPolygonTest() 函数计算所选轮廓中点和点之间的最短距离。将所需参数传递给此函数。要计算点( 250,250 ) 与轮廓 cnt 之间的最短距离,我们使用以下代码段:
-
打印输入图像中点和对象轮廓之间计算出的最短距离。
-
在图像中绘制点和检测到的轮廓,以便更好地可视化。
让我们通过一些Python示例来了解如何找到给定点与图像中对象轮廓之间的最短距离。
示例
在此Python程序中,我们在输入图像上取了两个点(250,250)和(350,250)。我们计算输入图像中点和轮廓之间的最短距离。输入图像只有一个对象轮廓。我们还在图像上绘制轮廓和点,以便更清楚地了解。
import cv2
img = cv2.imread('four-point-star.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,150,255,0)
contours,hierarchy = cv2.findContours(thresh,
cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print("Number of contours detected:", len(contours))
cnt = contours[0]
dist1 = cv2.pointPolygonTest(cnt,(250,250),True)
print('Shortest distance of Point 1 from contour:', dist1)
dist2 = cv2.pointPolygonTest(cnt,(350,250),True)
print('Shortest distance of Point 2 from contour:', dist2)
cv2.circle(img, (250,250), 4, (0, 0, 255), -1)
cv2.putText(img, "Point 1", (255,255),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
cv2.circle(img, (350,250), 4, (0, 0, 255), -1)
cv2.putText(img, "Point 2", (355,255),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
cv2.drawContours(img, [cnt], -1, (0,255,255), 3)
while True:
cv2.imshow("Extreme Points", img)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
我们将使用这张图片作为程序的 输入文件 –

输出
当您运行上述程序时,它将产生以下输出 –
然后我们会得到以下窗口,显示轮廓和两个点 –

在上述输出图像中,轮廓用黄色绘制,两个点用红色绘制。点1和轮廓之间的最短距离为负数,表明该点在轮廓外部。点2和轮廓之间的最短距离为正数,表明该点在轮廓内部。如果最短距离为零,这意味着该点位于轮廓边界上
示例
在这个Python程序中,我们在输入图像上取了一个点(350,250)。我们检测输入图像中的所有对象轮廓。该图像有三个轮廓。我们计算点与输入图像中轮廓之间的最短距离。我们还在图像上绘制轮廓和点,以便更清楚地理解。
import cv2
img = cv2.imread('convexhull.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,100,255,0)
contours,hierarchy = cv2.findContours(thresh,
cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print("检测到的轮廓数量:", len(contours))
for i, cnt in enumerate(contours):
M = cv2.moments(cnt)
x1, y1 = cnt[0,0]
img1 = cv2.drawContours(img, [cnt], -1, (0,255,255), 3)
cv2.putText(img, f'轮廓:{i+1}', (x1, y1),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
dist = cv2.pointPolygonTest(cnt,(350,250),True)
print(f'点(350,250)到轮廓 {i+1} 的最短距离:', dist)
cv2.circle(img, (350,250), 4, (0, , 0), -1)
cv2.imshow("Shapes", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
我们将使用这张图片作为程序的 输入文件 –

结果
当您运行上面的程序时,它将产生以下输出 –
我们得到以下窗口显示轮廓和点 –

在上述输出图像中,轮廓用黄色绘制,点用红色绘制。点和每个轮廓之间的最短距离为负数,表明点在每个轮廓之外。点与轮廓3之间的绝对距离最小,与其他距离相比距离最近。因此,该点距轮廓3最近。