opencv基础53-图像轮廓06-判断像素点与轮廓的关系(轮廓内,轮廓上,轮廓外)cv2.pointPolygonTest()

点到轮廓的距离

在 OpenCV 中,函数 cv2.pointPolygonTest()被用来计算点到多边形(轮廓)的最短距离(也

就是垂线距离),这个计算过程又称点和多边形的关系测试。该函数的语法格式为:

retval = cv2.pointPolygonTest( contour, pt, measureDist )

式中的返回值为 retval,与参数 measureDist 的值有关。

式中的参数如下:

  • contour 为轮廓。
  • pt 为待判定的点。
  • measureDist 为布尔型值,表示距离的判定方式。
  • 当值为 True 时,表示计算点到轮廓的距离。如果点在轮廓的外部,返回值为负数;如果点在轮廓上,返回值为 0;如果点在轮廓内部,返回值为正数。
  • 当值为 False 时,不计算距离,只返回"-1"、"0"和"1"中的一个值,表示点相对于轮廓的位置关系。如果点在轮廓的外部,返回值为"-1";如果点在轮廓上,返回值为"0";如果点在轮廓内部,返回值为"1"。

示例:使用函数 cv2.pointPolygonTest()计算点到轮廓的最短距离。

使用函数 cv2.pointPolygonTest()计算点到轮廓的最短距离,需要将参数 measureDist 的值设置为 True。

代码如下:

cpp 复制代码
import cv2
#----------------原始图像-------------------------
o = cv2.imread('cs.bmp')
cv2.imshow("original",o)
#----------------获取凸包------------------------
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,
 cv2.RETR_LIST,
 cv2.CHAIN_APPROX_SIMPLE)
hull = cv2.convexHull(contours[0])

cv2.polylines(o, [hull], True, (0, 255, 0), 2)
#----------------内部点 A 到轮廓的距离-------------------------
distA = cv2.pointPolygonTest(hull, (300, 150), True)
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(o,'A',(300,150), font, 1,(0,255,0),2)
print("distA=",distA)
#----------------外部点 B 到轮廓的距离-------------------------
distB = cv2.pointPolygonTest(hull, (300, 250), True)
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(o,'B',(300,250), font, 1,(0,255,0),2)
print("distB=",distB)
#------------正好处于轮廓上的点 C 到轮廓的距离-----------------
distC = cv2.pointPolygonTest(hull, (423, 112), True)
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(o,'C',(423,112), font, 1,(0,255,0),2)
print("distC=",distC)

#----------------显示-------------------------
cv2.imshow("result1",o)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

同时,程序还会显示如下的结果:

cpp 复制代码
distA= 16.891650862259112
distB= -81.17585848021565
distC= -0.0

从以上结果可以看出,

  • A 点算出来的距离为"16.891650862259112",是一个正数,说明 A 点在轮廓内部。
  • B 点算出来的距离为"-81.17585848021565",是一个负数,说明 B 点在轮廓外部。
  • C 点算出来的距离为"-0.0",说明 C 点在轮廓上。

在实际使用中,如果想获取位于轮廓上的点,可以通过打印轮廓点集的方式获取。例如,本例中可以通过语句"print(hull)"获取轮廓上的点。在获取轮廓上的点以后,可以将其用作函数 cv2.pointPolygonTest()的参数,以测试函数返回值是否为零。

示例2:使用函数 cv2.pointPolygonTest()判断点与轮廓的关系。

代码如下:

cpp 复制代码
import cv2
#----------------原始图像-------------------------
o = cv2.imread('cs.bmp')
cv2.imshow("original",o)
#----------------获取凸包------------------------
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,
 cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
hull = cv2.convexHull(contours[0])
image = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)
cv2.polylines(image, [hull], True, (0, 255, 0), 2)
#----------------内部点 A 与轮廓的关系-------------------------
distA = cv2.pointPolygonTest(hull, (300, 150),False)
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(image,'A',(300,150), font, 1,(0,255,0),3)
print("distA=",distA)
#----------------外部点 B 与轮廓的关系-------------------------
distB = cv2.pointPolygonTest(hull, (300, 250), False)
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(image,'B',(300,250), font, 1,(0,255,0),3)
print("distB=",distB)
#----------------边缘线上的点 C 与轮廓的关系----------------------
distC = cv2.pointPolygonTest(hull, (423, 112),False)
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(image,'C',(423,112), font, 1,(0,255,0),3)

print("distC=",distC)
#----------------显示-------------------------
cv2.imshow("result",image)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

同时,程序还会显示如下的运行结果:

cpp 复制代码
distA= 1.0
distB= -1.0
distC= 0.0

从以上结果可以看出,

  • A 点算出来的关系值为"1",说明该点在轮廓的内部。
  • B 点算出来的关系值为"-1",说明该点在轮廓的外部。
  • C 点算出来的关系值为零值,说明该点在轮廓上。

在实际应用中,我们可以拿这个方法去判断模板检测的像素点是否在一个指定的ROI区域内,具体应用示例我们后续在实战篇中讲解并代码示例。

相关推荐
落雨盛夏2 小时前
深度学习|李哥考研4图片分类比较详细说明
人工智能·深度学习·分类
臭东西的学习笔记6 小时前
论文学习——机器学习引导的蛋白质工程
人工智能·学习·机器学习
Rabbit_QL6 小时前
【水印添加工具】从零设计一个工程级 Python 图片水印工具:WaterMask 架构与实现
开发语言·python
大王小生6 小时前
说说CSV文件和C#解析csv文件的几种方式
人工智能·c#·csv·csvhelper·csvreader
m0_462605226 小时前
第G3周:CGAN入门|生成手势图像
人工智能
bubiyoushang8886 小时前
基于LSTM神经网络的短期风速预测实现方案
人工智能·神经网络·lstm
中烟创新6 小时前
烟草专卖文书生成智能体与法规案卷评查智能体获评“年度技术最佳实践奖”
人工智能
得一录7 小时前
大模型中的多模态知识
人工智能·aigc
Github掘金计划7 小时前
Claude Work 开源平替来了:让 AI 代理从“终端命令“变成“产品体验“
人工智能·开源
ghgxm5207 小时前
Fastapi_00_学习方向 ——无编程基础如何用AI实现APP生成
人工智能·学习·fastapi