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。

代码如下:

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()

运行结果:

在这里插入图片描述
同时,程序还会显示如下的结果:

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()判断点与轮廓的关系。

代码如下:

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()

运行结果:
在这里插入图片描述

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

distA= 1.0
distB= -1.0
distC= 0.0

从以上结果可以看出,

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/62094.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多路复用select实现

select函数 int select(int nfds, fd_set *readfds,fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);nfds:是三个集合中编号最高的文件描述符,加上1readfds/writefds/exceptfds: 可读集合/可写集合/异常集合timeout NULL:永久阻塞0&…

flink kafka消费者如何处理kafka主题的rebalance

背景: 我们日常使用kafka客户端消费kafka主题的消息时,当消费者退出/加入消费者组,kafka主题分区数有变等事件发生时,都会导致rebalance的发生,此时一般情况下,如果我们不自己处理offset,我们不…

Android Studio实现滑动图片验证码

源代码链接 效果: MainActivity package com.example.slidingpattern;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.Moti…

photoshop生成器引入到electron项目(electron与photoshop建立通信)

Photoshop引入了nodejs,在启动的时候,通过pipe调起nodejs运行时核心generator-builtin,通过KLVR机制与ps进行通信和交互,同时会加载用户编写的扩展。 这里记录一下引入时的踩坑过程 generator-core就是它的源码,elect…

栈和队列(二) 队列操作详解及栈与队列的相互实现

文章目录 四、队列1、什么是队列2、队列的基本操作Queue.hQueue.c初始化队列队尾入队列队头出队列获取队列头部元素获取队列队尾元素获取队列中有效元素个数检测队列是否为空,如果为空返回非零结果,如果非空返回0销毁队列 五、设计循环队列六、栈与队列的…

整数中1出现的次数(从1到n整数中1出现的次数)

解题思路1: 设定整数点(如1、10、100等等)作为位置点i(对应n的各位、十位、百位等等),分别对每个数位上有多少包含1的点进行分析。 第一步:对n进行分割,分为两部分:高位…

标准化归一化 batch norm, layer norm, group norm, instance norm

Layer Normalization - EXPLAINED (in Transformer Neural Networks) Layer Normalization - EXPLAINED (in Transformer Neural Networks) 0~4min:什么是multi-head attention 5~7min:layer norm图示 7~9min:公式举例layer norm 9:54-end:layer norm的代码示例 group n…

Redis安装配置远程连接

1. yum 安装 redis: 直接使用命令,将 redis 安装到 linux 服务器中: yum -y install redis 2. 启动 redis: 在 xshell 里,可以使用下面命令,以后台方式启动 redis: [rootVM-8-17-centos /]…

【李宏毅机器学习·学习笔记】Tips for Training: Batch and Momentum

本节课主要介绍了Batch和Momentum这两个在训练神经网络时用到的小技巧。合理使用batch,可加速模型训练的时间,并使模型在训练集或测试集上有更好的表现。而合理使用momentum,则可有效对抗critical point。 课程视频: Youtube&…

# X11、Xlib、XFree86、Xorg、GTK、Qt、Gnome和KDE之间的关系

X11、Xlib、XFree86、Xorg、GTK、Qt、Gnome和KDE之间的关系 很多人对于他们是啥是傻傻分不清的,我做了个表格供大家参考。 摘抄: X11是X Window System Protocol, Version 11(RFC1013),是X server和X client之间的通…

Observability:识别生成式 AI 搜索体验中的慢速查询

作者:Philipp Kahr Elasticsearch Service 用户的重要注意事项:目前,本文中描述的 Kibana 设置更改仅限于 Cloud 控制台,如果没有我们支持团队的手动干预,则无法进行配置。 我们的工程团队正在努力消除对这些设置的限制…

100G光模块的应用案例分析:电信、云计算和大数据领域

100G光模块是一种高速光模块,由于其高速率和低延迟的特性,在电信、云计算和大数据领域得到了广泛的应用。在本文中,我们将深入探讨100G光模块在这三个领域的应用案例。 一、电信领域 在电信领域,100G光模块被广泛用于构建高速通…