OpenCV-Python(21):凸缺陷检测及点到多边形最短的距离求解

学习目标

  • 凸缺陷的查找
  • 求某一点到一个多边形的最短距离
  • 不同形状的匹配

凸缺陷

        前面我们已经学习了轮廓的凸包,对象上的任何凹陷都被成为凸缺陷。OpenCV 中有一个函数cv2.convexityDefect() 可以帮助我们找到凸缺。函数使用如下:

hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)

注意:如果查查找凸缺陷,在使用函数cv2.convexHull 找凸包时,参数returnPoints 一定要是False。 

        它会返回一个数组,其中每一行包含的值是[起点,终点,最远的点,到最远点的近似距离]。我们可以在一张图上显示它。我们将起点和终点用一条绿线连接,在最远点画一个圆圈,要记住的是返回结果的前三个值是轮廓点的索引。所以我们还要到轮廓点中去找它们。

import cv2
import numpy as np
img = cv2.imread('star.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 127, 255,0)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt = contours[0]
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
for i in range(defects.shape[0]):s,e,f,d = defects[i,0]start = tuple(cnt[s][0])end = tuple(cnt[e][0])far = tuple(cnt[f][0])
cv2.line(img,start,end,[0,255,0],2)
cv2.circle(img,far,5,[0,0,255],-1)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果如下: 

点多边形测试 

         点多边形测试(Point Polygon Test)是求解图像中的一个点到一个对象轮廓的最短距离。如果点在轮廓的外面,返回值为负;如果在轮廓上,返回值为0;如果在廓内,返回值为正。

下面我们以点(50,50)为例:

dist = cv2.pointPolygonTest(cnt,(50,50),True)

        此函数的第三个参数是measureDist。如果设置为True,就会计算最短距离。如果是False,只会判断这个点与轮廓之间的位置关系,返回值为(+1,-1,0)
注意:如果你不知道具体距离,建议你将第三个参数设置为False,这样速度会度会提高2到3倍。

形状匹配

        函数cv2.matchShape() 可以帮我们比较两个形状或轮廓的相似度。如果返回值越小,匹配度越好。它是根据Hu 矩来计算的。文档中对不同的方法都有解释。我们试着将下面的图形进行比较:

import cv2
import numpy as npimg1 = cv2.imread('star.jpg',0)
img2 = cv2.imread('star2.jpg',0)ret, thresh = cv2.threshold(img1, 127, 255,0)
ret, thresh2 = cv2.threshold(img2, 127, 255,0)contours,hierarchy = cv2.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv2.findContours(thresh2,2,1)
cnt2 = contours[0]ret = cv2.matchShapes(cnt1,cnt2,1,0.0)
print (ret)我得到的结果是:
• A 与自己匹配度 0.0
• A 与B 匹配度 0.001946
• A 与C 匹配度 0.326911

看到了吧,即使发生了旋转对匹配的结果影响也不是非常大。 

示例

        1.创建一个小程序,可以将图片上的点绘制成不同的颜色,颜色是根据这个点到轮廓的距离来决定的。要使用的函数:cv2.pointPolygonTest()。

以下是一个示例代码,演示如何使用cv2.pointPolygonTest()函数根据点到轮廓的距离来确定颜色:

import cv2
import numpy as np# 加载图像
image = cv2.imread('image.jpg')# 将图像转为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化图像
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 创建一个空白图像
result = np.zeros_like(image)# 绘制轮廓
cv2.drawContours(result, contours, -1, (255, 255, 255), 2)# 遍历图像上的每个点
for y in range(result.shape[0]):for x in range(result.shape[1]):# 计算点到轮廓的距离distance = cv2.pointPolygonTest(contours[0], (x, y), True)# 根据距离设置颜色if distance > 0:result[y, x] = (0, 0, 255)  # 蓝色elif distance < 0:result[y, x] = (0, 255, 0)  # 绿色else:result[y, x] = (255, 0, 0)  # 红色# 显示图像
cv2.imshow("Distance to Contour", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中,首先加载图像,并将图像转换为灰度图像。然后使用cv2.threshold()函数对灰度图像进行二值化处理,得到二值图像binary。接下来使用cv2.findContours()函数查找轮廓,并将轮廓保存在contours中。然后创建一个空白图像result,并使用cv2.drawContours()函数绘制轮廓。接着使用两层循环遍历图像上的每个点,对每个点使用cv2.pointPolygonTest()函数计算该点到轮廓的距离,根据距离设置点的颜色。

最后,显示图像。点到轮廓的距离为正数表示点在轮廓的外部,为负数表示点在轮廓的内部,为零表示点在轮廓上。根据距离的正负,我们将点的颜色设置为蓝色、绿色或红色。请确保将代码中的image.jpg替换为你要处理的图像文件的路径。

2. 使用函数cv2.matchShapes() 匹配带有字母或者数字的图片。 

以下是一个使用cv2.matchShapes()函数匹配带有字母或数字的图片的示例代码:

import cv2
import numpy as np# 加载模板图像
template = cv2.imread('template.jpg', 0)# 加载目标图像
target = cv2.imread('target.jpg', 0)# 二值化模板图像和目标图像
_, template_binary = cv2.threshold(template, 127, 255, cv2.THRESH_BINARY)
_, target_binary = cv2.threshold(target, 127, 255, cv2.THRESH_BINARY)# 查找模板图像和目标图像的轮廓
template_contours, _ = cv2.findContours(template_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
target_contours, _ = cv2.findContours(target_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 计算模板图像和目标图像的Hu矩
template_hu_moments = cv2.HuMoments(cv2.moments(template_contours[0])).flatten()
target_hu_moments = cv2.HuMoments(cv2.moments(target_contours[0])).flatten()# 计算模板图像和目标图像的形状匹配分数
match_score = cv2.matchShapes(template_contours[0], target_contours[0], cv2.CONTOURS_MATCH_I1, 0)# 输出结果
print("Hu Moments of Template Image: ", template_hu_moments)
print("Hu Moments of Target Image: ", target_hu_moments)
print("Shape Matching Score: ", match_score)

在上述代码中,首先加载模板图像和目标图像,并将它们转换为灰度图像。然后使用cv2.threshold()函数对模板图像和目标图像进行二值化处理,得到二值图像template_binarytarget_binary

接下来使用cv2.findContours()函数查找模板图像和目标图像的轮廓,并将轮廓保存在template_contourstarget_contours中。

然后计算模板图像和目标图像的Hu矩,使用cv2.moments()函数计算图像的矩,再使用cv2.HuMoments()函数计算Hu矩,并将其展平为一维数组。

最后使用cv2.matchShapes()函数计算模板图像和目标图像的形状匹配分数。cv2.matchShapes()函数的第一个参数是模板图像的轮廓,第二个参数是目标图像的轮廓,第三个参数是形状匹配方法,第四个参数是匹配时的数值参数。请确保将代码中的template.jpgtarget.jpg替换为你要处理的模板图像和目标图像的路径。

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

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

相关文章

【量化】蜘蛛网策略复现

文章目录 蜘蛛网策略研报概述持仓数据整理三大商品交易所的数据统一筛选共有会员清洗数据计算研报要求数据全部代码 策略结果分析无参数策略有参数策略正做反做 MSD技术指标化 蜘蛛网策略 策略来自《东方证券-股指期货趋势交易之蜘蛛网策略——从成交持仓表中捕捉知情投资者行为…

C#学习笔记 - C#基础知识 - C#从入门到放弃 - C# Windows窗体技术及基础控件(二)

C# 入门基础知识 - C# Windows窗体技术及基础控件 第12节 Windows窗体技术及基础控件12.8 Label 控件12.9 Button 控件12.10 TextBox控件12.11 RichTextBox 控件12.12 Timer控件12.13 CheckBox 控件12.14 RadioButton 控件12.15 ComboBox 控件、ListBox 控件和CheckedListBox 控…

什么是 NLP (自然语言处理)

NLP&#xff08;自然语言处理&#xff09;到底是做什么&#xff1f; NLP 的全称是 Natural Language Processing&#xff0c;翻译成中文称作&#xff1a;自然语言处理。它是计算机和人工智能的一个重要领域。顾名思义&#xff0c;该领域研究如何处理自然语言。 自然语言就是我…

构建全场景解决方案,中国移动磐维数据库赋能数字化建设加速向前

【引言】随着数字化转型的加速&#xff0c;数据成为企业的核心资产&#xff0c;数据库作为数据的基础设施&#xff0c;承载着企业的业务发展和创新能力。如何构建一个高效、稳定、安全的数据库平台&#xff0c;满足不同场景的数据需求&#xff0c;是企业面临的重要挑战。本文将…

前端必须的服务端项目,node + express (这篇文章就够用)包含源代码

作为一个前端程序员&#xff0c;刚开始入门的时候&#xff0c;你觉得只要学习前端代码&#xff08;js css html&#xff09;就行了&#xff0c;实际上&#xff0c;到后面很多知识都涉及到服务端&#xff0c;在我们学习的过程中难免需要写一些 demo。比如在浏览器的缓存、或者…

公司防泄密软件监控员工哪些行为?

公司防泄密软件通常监控员工在使用电脑和其他存储设备时的一系列行为&#xff0c;以确保数据安全和防止敏感信息泄露。以下是一些公司防泄密软件可能监控的员工行为&#xff1a; 文件访问和操作&#xff1a; 软件可能会监控员工对文件的访问、打开、编辑、复制和移动操作。异常…

基于鸿蒙OS开发一个前端应用

创建JS工程&#xff1a;做鸿蒙应用开发到底学习些啥&#xff1f; 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择HarmonyOS模板库&#xff0c…

【MYSQL】-表的约束

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

Redis管道

问题引出 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤&#xff1a; 1 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket返回&#xff0c;通常以阻塞模式等待服务端响应。 2 服务端…

B (1038) : DS哈希查找—二次探测再散列

文章目录 一、题目描述二、输入与输出1.输入2.输出 三、参考代码 一、题目描述 定义哈希函数为H(key) key%11。输入表长&#xff08;大于、等于11&#xff09;&#xff0c;输入关键字集合&#xff0c;用二次探测再散列构建哈希表&#xff0c;并查找给定关键字。 二、输入与输…

用户规模破亿!基于文心一言的创新应用已超4000个

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

1.3MySQL中的自连接

自己的表和自己连接&#xff0c;核心&#xff1a;一张表拆为两张一样的表。 语法&#xff1a;select 字段列表 from 表 [as] 表别名1,表 [as] 表别名2 where 条件...; 关于怎样把一个表拆分成一个表&#xff0c;只要给它们分别取别名就行 categoryidpidcategoryname21信息…

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件是一款极其巧妙且具有开创性的工具&#xff0c;它赋予用户细致跟踪和全面分析其网站性能的卓越能力。有了这个非凡的插件&#xff0c;个人可以毫不费力地建立并认真监控他们的Google Analytics目标&#xff0c;从而…

conda环境下Could not build wheels for dlib解决方法

1 问题描述 在安装模型运行的conda环境时&#xff0c;出现如下问题&#xff1a; Building wheels for collected packages: basicsr, face-alignment, dlib, ffmpy, filterpy, futureBuilding wheel for basicsr (setup.py) ... doneCreated wheel for basicsr: filenamebasi…

记录一下亿级别数据入库clickhouse

需求背景 公司的业务主要是广告数据归因的&#xff0c;每天的pv数据和加粉数据粗粗算一下&#xff0c;一天几千万上亿是有的。由于数据量大&#xff0c;客户在后台查询时间跨度比较大的数据时&#xff0c;查询效率就堪忧。因而将数据聚合后导到clickhouse进行存储&#xff0c;…

32阵元 MVDR和DREC DOA估计波束方向图对比

32阵元 MVDR和DREC DOA估计波束方向图对比 一、原理 MVDR原理&#xff1a;https://zhuanlan.zhihu.com/p/457528114 DREC原理&#xff08;无失真响应特征干扰相消器&#xff09;&#xff1a;http://radarst.ijournal.cn/html/2019/3/201903018.html 主要参数&#xff1a; 阵…

完全适配各类中小医院专科医院和诊所的云HIS系统源码【前端:Angular+Nginx ,后台:SpringBoot】

云HIS系统采用SaaS软件应用服务模式&#xff0c;提供软件应用服务多租户机制&#xff0c;实现一中心部署多机构使用。相对传统HIS单机构应用模式&#xff0c;它可灵活应对区域医疗、医疗集团、医联体、连锁诊所、单体医院等应用场景&#xff0c;并提升区域内应用的标准化与规范…

Java技术栈 —— Nginx的使用

Java技术栈 —— Nginx的使用 一、认识Nginx二、搭建Nginx环境2.1 在Ubuntu上安装Nginx 三、使用Nginx3.1 配置负载均衡(HTTP) 一、认识Nginx 企业需要运行多个相同的副本&#xff0c;并将负载分散在整个系统集群上&#xff0c;为了高性能的负载均衡&#xff0c;引入了Nginx代…

通过C++程序实现光驱的自动化刻录和读取

文章目录 ISO文件格式光盘的基本概念光盘种类特点DVDR光盘使用windows调用Linux调用Linux平台下用到的C库:读取设备驱动列表向光驱中写文件 数字存储媒体快速发展的今天&#xff0c;光驱的使用已经不像以前那样普及了。但是在数据备份、安装软件和操作系统、旧设备兼容等领域还…

PiflowX大数据流水线系统

PiflowX大数据流水线系统。支持分布式计算引擎flink和spark。以所见即所得的方式&#xff0c;实现大数据采集、处理、存储与分析流程化配置、运行与智能监控。 PiflowX基于Piflow&#xff08;PiFlow: 混合型科学大数据流水线系统&#xff0c;包含丰富的处理器组件&#xff0c;…