findContours 轮廓查找
物体的轮廓勾勒出了物体的整体形状,物体形状的边界像素一起组合成了轮廓。
灰度图像边界的明显特征是边界两侧灰度级的突变,根据这个特征,使用Sobel、拉普拉斯或Canny之类的边缘检测算子可以有效的检测到物体的边界,所有连续的边界像素组合在一起成为一个整体,就构成了物体的轮廓。
轮廓检测可以使用findContours函数,检测步骤是:
1. 使用拉普拉斯或Canny等边缘检测算子处理图像,获得仅包含边界的二值图像
2. 使用findContorus方法,获取图像所有的边界连续像素序列,并保存在contours向量中
3. 标示出contours向量中所有的轮廓序列
以下Opencv实现:
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include "iostream"
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
Mat imageSource=imread(argv[1],0);
imshow("Source Image",imageSource);
Mat image;
GaussianBlur(imageSource,image,Size(3,3),0);
Canny(image,image,100,250);
imshow("Canny Image",image);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(image,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
Mat imageContours=Mat::zeros(image.size(),CV_8UC1);
for(int i=0;i<contours.size();i++)
{
drawContours(imageContours,contours,i,Scalar(255),1,8,hierarchy);
}
imshow("Contours Image",imageContours);
waitKey(0);
return 0;
}
原图:
Canny边缘:
轮廓:
轮廓图像和Canny图像乍看起来表现几乎是一致的,但其实组成两者的数据结构差别很大:
Canny边缘图像只是一些相互独立的散点勾勒出了一个边界,点与点之间没有联系,是没有“思想”的;
轮廓图像是一系列的点组成的,相邻的点与点同属于一个轮廓“集合”,连续的点构成了一个整体,甚至我们可以通过编号对每个轮廓定位,定义其前后轮廓线段,内外轮廓包含、隶属等树形关系,是有“思想”,可进一步处理的。
findContours 轮廓查找的更多相关文章
- opencv学习之路(22)、轮廓查找与绘制(一)
一.简介 图2 二.代码 #include"opencv2/opencv.hpp" #include<iostream> using namespace std; us ...
- opencv学习之路(28)、轮廓查找与绘制(七)——位置关系及轮廓匹配
一.点与轮廓的距离及位置关系 #include "opencv2/opencv.hpp" #include <iostream> using namespace std ...
- opencv学习之路(27)、轮廓查找与绘制(六)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓
一.最小外接圆 #include "opencv2/opencv.hpp" #include<iostream> using namespace std; using ...
- opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形
一.简介 二.外接矩形的查找绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //外接矩形的查找 ...
- opencv学习之路(24)、轮廓查找与绘制(三)——凸包
一.简介 二.绘制点集的凸包 #include<opencv2/opencv.hpp> using namespace cv; void main() { //---绘制点集的凸包 Mat ...
- opencv学习之路(23)、轮廓查找与绘制(二)——访问轮廓每个点
一.简介 二.画出每个轮廓的每个点 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src= ...
- OpenCV探索之路(十一):轮廓查找和多边形包围轮廓
Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...
- opencv学习之路(29)、轮廓查找与绘制(八)——轮廓特征属性及应用
一.简介 HSV颜色空间(hue色调,saturation饱和度,value亮度) 二.HSV滑动条 #include "opencv2/opencv.hpp" #include ...
- opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形
一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...
随机推荐
- python--6、re模块
re模块 用于在正则表达式匹配操作. python中为了避免实现输出'\','\n'字符的转义问题(如正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符,这里跟Python ...
- 2A课程笔记分享_StudyJams_2017
课程2A 概述 课程2A.2B的内容主要是关于创建交互式应用的基础知识.之前的L1课程主要是Android UI的基础设计知识,基本上没涉及到编程. 2A的讲解主要包括:使用变量来更新欲显示在屏幕上的 ...
- H265
H265 h265 一.名词 CTU: 编码树单元 CU: 编码单元 PU: 以CU为根,对CU进行划分,一个预测单元PU包含一个亮度预测块PB和两个色度预测块PB. TU: 以CU为根,变换单元T ...
- 各个数据库中,查询前n条记录的方法
SQL查询前10条的方法为: 1.select top X * from table_name --查询前X条记录,可以改成需要的数字,比如前10条. 2.select top X * from ...
- Deutsch lernen (15)
1. unterscheiden - unterschied - unterschieden 区别,区分:(能够)分清 Die beiden Begriffe sind nur schwer ...
- 5、scala数组转换
1.使用yield和函数式编程转换数组 2.算法案例:移除第一个负数之后的所有负数 1.使用yield和函数式编程转换数组 使用yield进行数组转换 结合if守卫,仅转换需要转换的元素 使用函数式编 ...
- 设计包含min()函数的栈
题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1). 分析:这是去年google的一道面试题. 我看到这道题目时,第一反应 ...
- 安卓Java读取SD卡文本文件
在进行序列识别时,需要对多个模式串进行识别,需要对多行浮点数进行读取,并进行解析. 所以使用的方法为: 使用文本多行读取的方式:对每行文本进行正则表达式匹配:再进行字符转换. 代码如下: ...
- VTK:VTK嵌入MFC成功
VTK作为医学显示库,得到较多使用.作为较为上层的设计,对OpenGL进行了封装,并且有Windows.Linux.安卓等开发版本,可移植性较强. 不过VES暂时没有编译成功. 以下是嵌入MFC-ID ...
- Firebug全了解
Firebug是firefox下的一个扩展,能够调试所有网站语言,如Html,Css等,但FireBug最吸引人的就是javascript调试功能,使用起来非常方便,而且在各种浏览器下都能使用(IE, ...