OpenCV计算机图像处理 —— 凸性缺陷 + 点多边形测试 + 形状匹配 + 轮廓分层与cv.findContours()

目录

  • OpenCV计算机图像处理 —— 凸性缺陷 + 点多边形测试 + 形状匹配 + 轮廓分层与cv.findContours()
  • 1. 凸性缺陷
  • 2. 点多边形测试
  • 3. 形状匹配
  • 4. 轮廓分层与cv.findContours()
    • 4.1 轮廓分层与cv.findcontours()的关系
    • 4.2 轮廓检索模式(四种参数)

1. 凸性缺陷

一般来说凸曲线都是凸出或平坦的曲线,如果在内部凸出了(凹进去了)我们就称其为凸性缺陷,OpenCV提供了一个方法cv.convexityDefects()

这个函数返回一个数组,其中每行包含这些值-【起点,终点,最远点,到最远点的近似距离】,我们可以用图像把它形象化,我们画一条连接起点和终点的线,然后在最远处画一个圆

import cv2 as cv
import numpy as npimg = cv.imread(r'E:\image\test14.png')
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, 2, 1)
cnt = contours[0]
hull = cv.convexHull(cnt, returnPoints=False)
defects = cv.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])cv.line(img, start, end, [0, 255, 0], 2)cv.circle(img, far, 5, [0, 0, 255], -1)
cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()

在以前轮廓的内容中我们提到了了一个函数cv.convexHull(),当这个函数的属性returnPoints = False时,我们就可以找到凸性缺陷

代码解释:又到了激动人心的解析代码的时间啦!第4-5行即是老生常谈的读取图片并转化为灰度图,第6行通过threshold()函数设置阈值,第7行通过findContours()方法找到轮廓,将第一个轮廓拿出来后用convexHull()函数检查轮廓的凸度缺陷,然后使用convexityDefects()函数得到这些凸度缺陷对应点的相关信息,包括起点终点等

2. 点多边形测试

点多边形测试中涉及了一个新的函数:cv.pointPolygonTest(),顾名思义它是一个测试函数,第一个参数是轮廓,第二个参数就是我们的测试点了,第三个参数指的是measureDist,如果其取值为True,这个函数会找到有符号的距离,反之它只会反映出这个点是在轮廓线内部、上面还是外部(分别返回1、-1和0)

import cv2 as cv
import numpy as np
img = cv.imread(r'E:\image\test12.png')
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, 2, 1)
cnt = contours[0]
img02 = cv.drawContours(img, [cnt], 0, (0, 0,255), 3)
dist = cv.pointPolygonTest(cnt, (20, 20), True)
dist2 = cv.pointPolygonTest(cnt, (192.5, 156), True)
print("point:(20,20) = " + str(dist))
print("point:(192.5,156) = " + str(dist2))
cv.imshow('test', img02)
cv.waitKey(0)
cv.destroyWindow()

3. 形状匹配

OpenCV中的形状匹配与一个函数有关:cv.matchShapes(),这个函数使我们能够比较两个形状(或两个轮廓),并返回一个显示相似性的度量,这个值越低说明匹配越好,在实质上它是根据矩值计算出来的

值得注意的是,即使是图像旋转也不会对结果产生很大的影响

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pytimg1 = cv.imread(r'E:/image/star01.png', 0)
img2 = cv.imread(r'E:/image/star02.png', 0)
img3 = cv.imread(r'E:/image/rectangle01.png', 0)
ret, thresh = cv.threshold(img1, 127, 255, 0)
ret, thresh2 = cv.threshold(img2, 127, 255, 0)
ret, thresh3 = cv.threshold(img3, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, 2, 1)
cnt1 = contours[0]
contours, hierarchy = cv.findContours(thresh2, 2, 1)
cnt2 = contours[0]
contours, hierarchy = cv.findContours(thresh3, 2, 1)
cnt3 = contours[0]
ret = cv.matchShapes(cnt1, cnt2, 1, 0.0)
ret2 = cv.matchShapes(cnt1, cnt3, 1, 0.0)
print("星图1与星图2的匹配度量 = " + str(ret))
print("星图1与方图1的匹配度量 = " + str(ret2))
pyt.subplot(1, 3, 1), pyt.imshow(img1, cmap="gray")
pyt.title("star_img01"), pyt.xticks([]), pyt.yticks([])
pyt.subplot(1, 3, 2), pyt.imshow(img2, cmap="gray")
pyt.title("star_img02"), pyt.xticks([]), pyt.yticks([])
pyt.subplot(1, 3, 3), pyt.imshow(img3, cmap="gray")
pyt.title("rectangle_img01"), pyt.xticks([]), pyt.yticks([])
pyt.show()

4. 轮廓分层与cv.findContours()

4.1 轮廓分层与cv.findcontours()的关系

在前面的文章我们聊了怎么使用cv.findcontours()函数找到轮廓,并且提到了它的第三个参数轮廓检索模式,对于这个参数我们通常使用cv.RETR_LIST或cv.RETR_TREE就能得到很好的效果,而且对应这个函数的三个输出我们也很有必要了解一下,它的输出包括三个数组,包括图像(image)、轮廓(contours)和hierarchy,它其实就是我们在这一节要聊的”轮廓层次结构”

在某些情况下,某些形状位于其他形状中,就像嵌套的图形一样,在这种情况下,我们把外部的称为父类,把内部的称为子类,这样,图像中的轮廓就有了一定的相互关系。我们可以指定一个轮廓是如何相互连接的,比如,它是另一个轮廓的子轮廓,还是父轮廓等等。这种关系的表示称为层次结构

所以每个轮廓都有它自己的信息关于它是什么层次,谁是它的孩子,谁是它的父母等等,OpenCV将它表示为一个包含四个值的数组: [Next, Previous, First_Child, Parent],这就是我们在findcontours()函数中得到的第三个参数

4.2 轮廓检索模式(四种参数)

RETR_LIST

这是四个标志中最简单的一个,它只是检索所有的轮廓,但不创建任何亲子关系,在这个规则下,父轮廓和子轮廓是平等的,他们只是轮廓,并且都属于同一层级,如果我们在开发中没有使用任何层次结构特性,它就是我们最佳的选择

RETR_EXTERNAL

如果使用此标志,它只返回极端外部标志,所有孩子的轮廓都被留下了,更形象地来说,根据这项规则,每个家庭只有长子得到关注,它不关心家庭的其他成员,所以当我们只关心外部轮廓时可以使用它

RETR_CCOMP

此标志检索所有轮廓并将其排列为2级层次结构,物体的外部轮廓(即物体的边界)放在层次结构-1中,对象内部孔洞的轮廓(如果有)放在层次结构-2中,如果其中有任何对象,则其轮廓仅在层次结构1中重新放置,以及它在层级2中的漏洞等等

RETR_TREE

它就是最完美的一个家伙了,它检索所有的轮廓并创建一个完整的家族层次结构列表,当我们需要检索所有轮廓时会使用它

接下来通过代码看看吧,实践永远是最好的老师

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pytimg = cv.imread(r'E:/image/the_first.png')
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img_gray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
cnt = contours[0]
contours, hierarchy = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
cnt2 = contours[0]
contours, hierarchy = cv.findContours(thresh, cv.RETR_CCOMP, cv.CHAIN_APPROX_NONE)
cnt3 = contours[0]
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
cnt4 = contours[0]
img1 = cv.drawContours(thresh, [cnt], 0, (255, 0, 0), 2)
img2 = cv.drawContours(thresh, [cnt2], 0, (0, 255, 0), 2)
img3 = cv.drawContours(thresh, [cnt3], 0, (0, 0, 255), 2)
img4 = cv.drawContours(thresh, [cnt4], 0, (0, 0, 0), 2)
pyt.subplot(2, 2, 1), pyt.imshow(img1, cmap="gray")
pyt.title("RETR_LIST"), pyt.xticks([]), pyt.yticks([])
pyt.subplot(2, 2, 2), pyt.imshow(img2, cmap="gray")
pyt.title("RETR_EXTERNAL"), pyt.xticks([]), pyt.yticks([])
pyt.subplot(2, 2, 3), pyt.imshow(img3, cmap="gray")
pyt.title("RETR_CCOMP"), pyt.xticks([]), pyt.yticks([])
pyt.subplot(2, 2, 4), pyt.imshow(img3, cmap="gray")
pyt.title("RETR_TREE"), pyt.xticks([]), pyt.yticks([])
pyt.show()

(注:文章内容参考OpenCV4.1中文官方文档)
如果文章对您有所帮助,记得一键三连支持一下哦

OpenCV计算机图像处理 —— 凸性缺陷 + 点多边形测试 + 形状匹配 + 轮廓分层与cv.findContours()相关推荐

  1. Opencv之利用matchshape算子实现简单的形状匹配

    Opencv之利用matchshape算子实现简单的形状匹配 算子: matchShapes( InputArray contour1, InputArray contour2, int method ...

  2. 唤醒手腕 - 爆肝 3 天整理出来关于 Opencv 计算机图像处理详细教程(更新中)

    Opencv 库安装教程 OpenCV 是一个开源的计算机视觉库,OpenCV 库用C语言和 C++ 语言编写,可以在 Windows.Linux.Mac OS X 等系统运行.同时也在积极开发 Py ...

  3. Opencv:基于Hu-moments(hu矩)的形状匹配

    本文将按照以下目录展开介绍: 什么是图像矩: 如何计算图像矩: 什么是Hu矩: 如何利用Opencv计算一个图像Hu矩: 如何利用Hu-矩来寻找两个形状的相似性: 1. 什么是图像力矩 图像矩是图像像 ...

  4. opencv cv.findContours 函数详解

    函数 cv.findContours contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy ...

  5. OpenCV之imgproc 模块. 图像处理(5)在图像中寻找轮廓 计算物体的凸包 创建包围轮廓的矩形和圆形边界框 为轮廓创建可倾斜的边界框和椭圆 轮廓矩 多边形测试

    在图像中寻找轮廓 目标 在这个教程中你将学到如何: 使用OpenCV函数 findContours 使用OpenCV函数 drawContours 原理 例程 教程的代码在下面给出. 你也可以从 这里 ...

  6. OpenCV与图像处理学习三——线段、矩形、圆、椭圆、多边形的绘制以及文字的添加

    OpenCV与图像处理学习三--线段.矩形.圆.椭圆.多边形的绘制以及文字的添加 一.OpenCV中的绘图函数 1.1 线段绘制 1.2 矩形绘制 1.3 圆绘制 1.4 椭圆的绘制 1.5 多边形绘 ...

  7. 纺织计算机应用技术pdf,计算机图像处理技术在纺织品测试中的应用.pdf

    计算机图像处理技术在纺织品测试中的应用 !""# 年$ 月·第%% 卷·第$ 期 !"#$%"#& '()'&*( !+&($+( , ...

  8. 使用Python+opencv进行图像处理(一) | 视觉入门

    计算机视觉是人工智能最热门的应用领域之一.人工智能技术推动了汽车自动驾驶.机器人以及各种照片处理类软件的巨大发展.目标检测技术也在稳步推进.生成对抗网络(GANs)同样也是人们最近比较关注的一个问题. ...

  9. OpenCV实战(1)——OpenCV与图像处理基础

    OpenCV实战(1)--OpenCV与图像处理基础 0. 前言 1. OpenCV 基础 1.1 安装 OpenCV 1.2 OpenCV 主要模块 1.3 使用 Qt 进行 OpenCV 开发 2 ...

最新文章

  1. iOS封装HTTPS双向和单向验证
  2. Matplotlib的介绍及简单操作
  3. 【已解决】图灵机模型(模拟二进制非负整数加1)
  4. android 原生分享界面_这些技巧和习惯,让你的原生 Android 更好用(上篇)
  5. (转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性
  6. iOS设计模式 - 桥接
  7. 让猫给人打工,猫咖是一门好生意吗?
  8. python 字典(dict)
  9. 关于js中replace()只能替换字符串中第一个对象的问题
  10. ubuntu上安装python3.7教程_给ubuntu18安装python3.7的详细教程
  11. 【知识蒸馏】如何写好BERT知识蒸馏的损失函数代码(一)
  12. 【配送路径规划】基于matlab遗传算法求解带时间窗的多配送中心半开放式车辆路径规划问题【含Matlab源码 YC002期】
  13. Unity3d C#获取海康摄像头直播视频流预览萤石截图实现
  14. java和3d建模_基于Java3D技术和Swing技术的3D建模开发
  15. 史上ElasticSearch 最全详细使用教程
  16. 马来亚大学研究生多久毕业?这份问卷调查结果拍了拍你
  17. 易天光模块交期漫画故事
  18. 关联查询(多表查询)
  19. C++程序员发展方向有哪些?
  20. 开发环境配置 -- 集成

热门文章

  1. 不发短信获取短信中心号
  2. Python新手都知道而你却不知的经典案例
  3. 按键触发快捷怼人小工具(怼人必备良药)
  4. 通俗易懂 高并发案例春节抢红包分析 乐观锁 悲观锁 分布式锁
  5. 使用Blend的一些问题
  6. 计算机培训word,最新计算机培训word.pptx
  7. scons 手册_SCons用户手册
  8. 锂电池的充电电压和电流应该是多少
  9. C站 APP 搜索工具使用体验与对比
  10. 工装夹具检具治具机械设计机构solidworks模型3d课程图纸sw