轮廓检测

轮廓(Contours),指的是有相同颜色或者密度,连接所有连续点的一条曲线。检测轮廓的工作对形状分析和物体检测与识别都非常有用。

在轮廓检测之前,首先要对图片进行二值化或者Canny边缘检测。在OpenCV中,寻找的物体是白色的,而背景必须是黑色的,因此图片预处理时必须保证这一点。


cv2.findContours函数

Python版示例如下,也可以参考【OpenCV-Python教程(11、轮廓检测)】【Contours : Getting Started】

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

1. 完整例子

import cv2#读入图片
img = cv2.imread("1.png")# 必须先转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINAEY)# 寻找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 画出轮廓,-1,表示所有轮廓,画笔颜色为(0, 255, 0),即Green,粗细为3
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)# 显示图片
cv2.namedWindow("Contours", cv2.NORMAL_WINDOW)
cv2.imshow("Contours", img)# 等待键盘输入
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2. 参数解释

这里的findContours函数,有三个参数

  • thresh -> 要寻找轮廓的图片,注意这里的轮廓会直接改变在thresh上,记得备份
  • cv2.RETR_TREE -> 表示轮廓检索模式(Contour retrieval mode)为,检索所有的轮廓,且重组为一个有层次的嵌套轮廓。层次信息返回在hierarchy中。
  • cv2.CHAIN_APPROX_SIMPLE -> 表示轮廓近似方法(Contour approximation method)。SIMPLE可以这样理解,假如一个矩形有1000个点,但是现在只用四个角的点表示就行了,即去掉冗余信息。

返回值也有两个,contours 和 hierarchy

对contours的理解如下

print "找到 %d 个轮廓" %(len(contours))
print "第 0 个轮廓有 %d 个点" %(len(contours[0]))# 画出第0个轮廓
cv2.drawContours(img, contours, 0, (0, 255, 0), 3)
cv2.imshow("first contours", img)# 画出第1个轮廓
cv2.drawContours(img, contours, 1, (0, 255, 0), 3)
cv2.imshow("second contours", img)# 画出所有的轮廓
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
cv2.imshow("all contours", img)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

对 hierarchy 的深究,可以参考这里:【Contours Hierarchy】


轮廓特征(Contour Features)

查找到轮廓以后,我们可以得出轮廓的一些特征信息,也可以在轮廓上做一些简单的操作,参考Python教程:【Contour Features】

1. 面积和周长示例

# 寻找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 取第 0 个轮廓
cnt = contours[0]# 轮廓面积
area = cv2.contourArea(cnt)# 周长,或者说,弧长;第二个参数的True表示该轮廓是否封闭
perimeter = cv2.arcLength(cnt, True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2. 轮廓近似

轮廓近似(Contour Approximation),要理解概念,先来看下面的三张图。第一张是找到的轮廓;第二张近似的幅度很大,忽略了很多的细节;第三细节多一点.

hehe


OpenCV中是用 cv2.approxPolyDP()函数来进行轮廓的近似的。见代码:

# 假设取第30个轮廓为例
cnt = contours[30]# 10%,即0.1的精确度
epsilon = 0.1 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)# 这里是第二张,10%的精确度
cv2.imshow("10% approximation", approx)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

同理,第三张可以用1%的精确度来得到。


3. 计算凸包

涉及凸多面体和凹多面体的概念,不多解释。如下图,本来是一个手掌的形状,现在用最小的凸多面体把它包起来。其中,凸进去(Bulge Inside)的部分,称为凸包缺陷(Convexity Defects),即箭头处,即偏导的局部最大值处。

convenHull

函数调用,以后用到再来细究吧!

hull = cv2.convexHull(cnt)
cv2.imshow("hull", hull)
  • 1
  • 2
  • 1
  • 2

4. 矩形边框

矩形边框(Bounding Rectangle)是说,用一个最小的矩形,把找到的形状包起来。还有一个带旋转的矩形,面积会更小,效果见下图

Bounding Rectangle

上代码

# 用绿色(0, 255, 0)来画出最小的矩形框架
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)# 用红色表示有旋转角度的矩形框架
rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect)
box = np.int0(box)
img = cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

PS其他的形状,如 封闭的圆形椭圆直线 等,例子见这里【Contour Features】,原理差不多,不再赘述。

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

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

相关文章

【大数据】阿里云大数据助理工程师认证(ACA)课程

阿里云大数据助理工程师认证(Alibaba Cloud Certified Associate,ACA) 是面向使用阿里云大数据产品的专业技术认证,主要涉及阿里云的大数据计算、存储、开发平台,数据应用类的基础产品。是对学员掌握阿里云大数据产品技…

WebGL——osg框架学习一

从今天开始,我们开始正式的学习osg框架,今天我们学习的是osg的渲染模块,我们来看一下代码结构。 所有DrawXXX的js模块都是渲染的模块,我们逐一来简单介绍一下,第一个Drawable.js,这个模块是描述可绘制对象的…

EmguCV 一些基本操作

一、先是在程序中图像的导入,我是根据图像路径实现,其中path是string类型,是图像路径。 IntPtr imgCvInvoke.cvLoadImage(path, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_ANYCOLOR); 二、图像灰度化处理,先创建一幅尺寸大小…

Java字符串分割

java中字符串的分割函数,split("你想要分割的字符", 你想要最多分割为多少段,正整数) 注意事项: 1.分割特殊字符考虑转义字符的使用。如: . \ | 2.第二个参数: 无: 不传默认分割全部…

OpenCV人脸识别的原理 .

在之前讲到的人脸测试后,提取出人脸来,并且保存下来,以供训练或识别是用,提取人脸的代码如下: [html] view plaincopy print?void GetImageRect(IplImage* orgImage, CvRect rectInImage, IplImage* imgRect,double s…

说一下SEO和SEM到底有哪些区别?

开场白免了,我们直接说与主题相关的。 SEO和SEM到底有什么区别? SEO和SEM到底有什么区别 我们先理解字面意思: SEO(Search Engine Optimization):汉译为搜索引擎优化。 SEM(Search Engine Marke…

django模型的继承

很多时候,我们都不是从‘一穷二白’开始编写模型的,有时候可以从第三方库中继承,有时候可以从以前的代码中继承,甚至现写一个模型用于被其它模型继承。这样做的好处,我就不赘述了,每个学习Django的人都非常…

SpringBoot部署项目到Docker仓库

SpringBoot部署项目到Docker仓库1.开启远程控制端口Centos7开启方式: vim /lib/systemd/system/docker.service找到ExecStart行 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock 重启docker 启动 systemctl start docker守护进程…

人脸识别经典方法

这篇文章是撸主要介绍人脸识别经典方法的第一篇,后续会有其他方法更新。特征脸方法基本是将人脸识别推向真正可用的第一种方法,了解一下还是很有必要的。特征脸用到的理论基础PCA在另一篇博客里:特征脸(Eigenface)理论基础-PCA(主成分分析法)…

Jquery常用正则验证

常用校验的正则表达式var rulesConfig { /** * str.replace(/^\s|\s$/g, ) 解析: str:要替换的字符串 \s : 表示 space ,空格 : 一个或多个 ^: 开始,^\s,以空格开始 $: 结束&#x…

svm参数说明

svm参数说明---------------------- 如果你要输出类的概率,一定要有-b参数 svm-train training_set_file model_file svm-predict test_file model_fileoutput_file 自动脚本:Python easy.py train_data test_data 自动选择最优参数,自动进行…

poj-3667(线段树区间合并)

题目链接&#xff1a;传送门 参考文章&#xff1a;传送门 思路&#xff1a;线段树区间合并问题&#xff0c;每次查询到满足线段树的区间最左值&#xff0c;然后更新线段树。 #include<iostream> #include<cstdio> #include<cstring> using namespace std; co…

面试题编程题11-python 生成随机数

随机整数&#xff1a; random.randint(a,b), [a,b] random.randrange(a,b,step) [a,b) 随机实数 random.random()返回0 到1 之间的浮点数转载于:https://www.cnblogs.com/feihujiushiwo/p/10922454.html

车牌识别之颜色选取

车牌定位是车牌识别中第一步&#xff0c;也是最重要的一步。 由于中国车牌种类多样&#xff0c;颜色不一&#xff0c; 再加上车牌经常有污损&#xff0c;以及车牌周围干扰因素太多&#xff0c;都成为了车牌定位的难点。 这里首先使用最简单算法来描述车牌定位&#xff0c;以及他…

Python - 排序( 插入, 冒泡, 快速, 二分 )

插入排序 算法分析 两次循环, 大循环对队列中的每一个元素拿出来作为小循环的裁定对象 小循环对堆当前循环对象在有序队列中寻找插入的位置 性能参数 空间复杂度  O(1) 时间复杂度  O(n^2) 详细代码解读 import randomdef func(l):# 外层循环: 对应遍历所有的无序数据for i…

[EmguCV|C#]使用CvInvoke自己繪製色彩直方圖-直方圖(Hitsogram)系列(4)

2014-02-0610325 0C# 檢舉文章 過年結束了&#xff0c;雖然還是學生所以其實還有兩個禮拜的假期&#xff0c;不過為了不讓自己發慌&#xff0c;趁著假期多利用充實自己&#xff0c;所以提早回到開工狀態&#xff0c;而這次總算要把一直說的自己動手繪製猜色直方圖文章寫出。 …

G.点我

链接&#xff1a;https://ac.nowcoder.com/acm/contest/903/G 题意&#xff1a; X腿与队友到河北省来参加2019河北省大学生程序设计竞赛&#xff0c;然而这场比赛的题目难度实在是太高了。比赛开始一个小时后&#xff0c;X腿仍然没有做出一个题。这时候&#xff0c;X腿惊讶的发…

轮廓的查找、表达、绘制、特性及匹配(How to Use Contour? Find, Component, Construct, Features Match)

前言 轮廓是构成任何一个形状的边界或外形线。前面讲了如何根据色彩及色彩的分布&#xff08;直方图对比和模板匹配&#xff09;来进行匹配&#xff0c;现在我们来看看如何利用物体的轮廓。包括以下内容&#xff1a;轮廓的查找、表达方式、组织方式、绘制、特性、匹配。 查…

Android:IntentService的学习

在Android的四大组件中&#xff0c;Service排行老二&#xff0c;在Android中的主要作用是后台服务&#xff0c;进行与界面无关的操作。由于Service运行在主线程&#xff0c;所以进行异步操作需要在子线进行。为此Android为我们提供了IntentService。 IntentService是一个抽象类…

智能商业大会构造信息化交流平台

在快速发展的当今社会&#xff0c;所有事物都在日新月异地变化着&#xff0c;相较于过去的传统商业的变化速度&#xff0c;现今基于数据的互联网商业变化速度高出了一个量级&#xff0c;同时市场对于企业的应对速度也有了更高的要求&#xff0c;然而面对大体量的数据&#xff0…