物体的轮廓勾勒出了物体的整体形状,物体形状的边界像素一起组合成了轮廓。

灰度图像边界的明显特征是边界两侧灰度级的突变,根据这个特征,使用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 轮廓查找的更多相关文章

  1. opencv学习之路(22)、轮廓查找与绘制(一)

    一.简介 图2 二.代码 #include"opencv2/opencv.hpp" #include<iostream> using namespace std; us ...

  2. opencv学习之路(28)、轮廓查找与绘制(七)——位置关系及轮廓匹配

    一.点与轮廓的距离及位置关系 #include "opencv2/opencv.hpp" #include <iostream> using namespace std ...

  3. opencv学习之路(27)、轮廓查找与绘制(六)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓

    一.最小外接圆 #include "opencv2/opencv.hpp" #include<iostream> using namespace std; using ...

  4. opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形

    一.简介 二.外接矩形的查找绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //外接矩形的查找 ...

  5. opencv学习之路(24)、轮廓查找与绘制(三)——凸包

    一.简介 二.绘制点集的凸包 #include<opencv2/opencv.hpp> using namespace cv; void main() { //---绘制点集的凸包 Mat ...

  6. opencv学习之路(23)、轮廓查找与绘制(二)——访问轮廓每个点

    一.简介 二.画出每个轮廓的每个点 #include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src= ...

  7. OpenCV探索之路(十一):轮廓查找和多边形包围轮廓

    Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...

  8. opencv学习之路(29)、轮廓查找与绘制(八)——轮廓特征属性及应用

    一.简介 HSV颜色空间(hue色调,saturation饱和度,value亮度) 二.HSV滑动条 #include "opencv2/opencv.hpp" #include ...

  9. opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形

    一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...

随机推荐

  1. python--6、re模块

    re模块 用于在正则表达式匹配操作. python中为了避免实现输出'\','\n'字符的转义问题(如正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符,这里跟Python ...

  2. 2A课程笔记分享_StudyJams_2017

    课程2A 概述 课程2A.2B的内容主要是关于创建交互式应用的基础知识.之前的L1课程主要是Android UI的基础设计知识,基本上没涉及到编程. 2A的讲解主要包括:使用变量来更新欲显示在屏幕上的 ...

  3. H265

    H265 h265  一.名词 CTU: 编码树单元 CU: 编码单元 PU: 以CU为根,对CU进行划分,一个预测单元PU包含一个亮度预测块PB和两个色度预测块PB. TU: 以CU为根,变换单元T ...

  4. 各个数据库中,查询前n条记录的方法

    SQL查询前10条的方法为: 1.select top X *  from table_name --查询前X条记录,可以改成需要的数字,比如前10条. 2.select top X *  from  ...

  5. Deutsch lernen (15)

    1.    unterscheiden - unterschied - unterschieden  区别,区分:(能够)分清 Die beiden Begriffe sind nur schwer ...

  6. 5、scala数组转换

    1.使用yield和函数式编程转换数组 2.算法案例:移除第一个负数之后的所有负数 1.使用yield和函数式编程转换数组 使用yield进行数组转换 结合if守卫,仅转换需要转换的元素 使用函数式编 ...

  7. 设计包含min()函数的栈

    题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1). 分析:这是去年google的一道面试题. 我看到这道题目时,第一反应 ...

  8. 安卓Java读取SD卡文本文件

    在进行序列识别时,需要对多个模式串进行识别,需要对多行浮点数进行读取,并进行解析. 所以使用的方法为: 使用文本多行读取的方式:对每行文本进行正则表达式匹配:再进行字符转换. 代码如下:        ...

  9. VTK:VTK嵌入MFC成功

    VTK作为医学显示库,得到较多使用.作为较为上层的设计,对OpenGL进行了封装,并且有Windows.Linux.安卓等开发版本,可移植性较强. 不过VES暂时没有编译成功. 以下是嵌入MFC-ID ...

  10. Firebug全了解

    Firebug是firefox下的一个扩展,能够调试所有网站语言,如Html,Css等,但FireBug最吸引人的就是javascript调试功能,使用起来非常方便,而且在各种浏览器下都能使用(IE, ...