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

灰度图像边界的明显特征是边界两侧灰度级的突变,根据这个特征,使用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. 这是一个无效的原路径/url

    当我们在SourceTree上新建一个“从URL克隆”的远程项目时,在确认“URL”无误的前提下依然报红色字体“这是一个无效的原路径/URL”错误,我们只需要快捷键“Command + ,”打开Sou ...

  2. System.net.mail发送电子邮件

    之前做的实现发送邮件的功能,基于System.net.mail,在本地测试是可以发送邮件的,发布到服务器上发送不了邮件,后来发现STMP默认使用25端口收发邮件,服务器封掉25了端口,导致发送邮件失败 ...

  3. JS 有趣的eval优化输入验证

    //eval就是计算字符串[可以放任何js代码]里的值 . var str1='12+3'; eval(str1); . var str2='[1,2,3]'; eval(str2[]); .eval ...

  4. [hihocoder][Offer收割]编程练习赛50

    循环数组 计算a[i]的前缀和s[i],计算l[i]为1~i-1中最小的s值,r[i]为i~n中最大的s值. 则a[i]~a[n]满足性质的条件为r[i]-s[i-1]>0,a[1]~a[i-1 ...

  5. Android Studio 将module打成jar包

    1.新建测试工程,工程里面有两个module,app是Android工程,mylibrary是Android Library库. 2.打开mylibrary目录下的build.gradle文件,加入下 ...

  6. Visual C++ 6.0的界面介绍

      双击Visual C++ 6.0安装目录下的文件启动Visual C++ 6.0,通过“文件”→“新建”可新建一个Win32 Console Application项目.创建好项目后,显示Visu ...

  7. 关于VM虚拟机在使用网络时与锐捷网络冲突的解决问题

    在使用NAT网络模式的时候,锐捷会因为冲突强制关闭NAT服务,导致虚拟机无法上网,解决的办法是让NAT服务一直保持启动,写一个bat脚本来一直检测服务是否在运行,并且进行启动操作. 当不需要用虚拟机的 ...

  8. QT显示框架嵌入Vs控制台工程

      一.一些准备工作: 1.安装Qt for VS 的插件: 安装Qt for VS 的插件 下载地址:http://download.qt.io/official_releases/vsaddin/ ...

  9. POJ_2063_完全背包

    Investment Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10090   Accepted: 3540 Descr ...

  10. es7 class的写法

    再看vue-router源码的时候(代码链接)看到这样的代码片段: export default class VueRouter { app: any; apps: Array<any>; ...