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区域内,具体应用示例我们后续在实战篇中讲解并代码示例。

相关推荐
扫地僧985几秒前
MuMu-LLaMA:通过大型语言模型进行多模态音乐理解和生成(Python代码实现+论文)
人工智能·语言模型·llama
skywalk81632 分钟前
Trae 是一款由 AI 驱动的 IDE,让编程更加愉悦和高效。国际版集成了 GPT-4 和 Claude 3.5,国内版集成了DeepSeek-r1
人工智能·trae
WenGyyyL8 分钟前
使用OpenCV和MediaPipe库——驼背检测(姿态监控)
人工智能·python·opencv·算法·计算机视觉·numpy
梓羽玩Python21 分钟前
开源版Manus来了!14.7k标星的OpenManus,让AI替你全自动执行任务!
人工智能·github
蹦蹦跳跳真可爱58922 分钟前
Python----数据分析(Matplotlib四:Figure的用法,创建Figure对象,常用的Figure对象的方法)
python·数据分析·matplotlib
广拓科技22 分钟前
中国视频生成 AI 开源潮:腾讯阿里掀技术普惠革命,重塑内容创作格局
人工智能·开源
dr李四维31 分钟前
Java在小米SU7 Ultra汽车中的技术赋能
java·人工智能·安卓·智能驾驶·互联·小米su7ultra·hdfs架构
guanshiyishi32 分钟前
ABeam 德硕 | 中国汽车市场(1)——正在推进电动化的中国汽车市场
人工智能·物联网·汽车
思茂信息33 分钟前
CST直角反射器 --- 距离多普勒(RD图), 毫米波汽车雷达ADAS
前端·人工智能·5g·汽车·无人机·软件工程
瑞瑞大大1 小时前
简单介绍下Manus功能
人工智能