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() { //轮廓最小外 ...
随机推荐
- 全局设置border-box
全局设置 border-box 很好,更符合我们通常对一个「盒子」尺寸的认知.,其次它可以省去一次又一次的加加减减,它还有一个关键作用——让有边框的盒子正常使用百分比宽度.但是使用了 border-b ...
- Excel的用到的常规的技巧
这几天在做各种发票的报表,好几百的数据当然离不开EXCel,自己又是个白班,就记录下啦! EXCEL 判断某一单元格值是否包含在某一列中 就在Excel的表格中加入这个函数:=IF(ISERROR(V ...
- SqlServer 导出指定表数据 生成Insert脚本
版权声明:本文为博主原创文章,未经博主允许不得转载.
- Android测试写入文本Log
写入本地SD卡: @SuppressLint("SdCardPath") public void writeFileSdcard(String fileName, String m ...
- PJAX全局无刷新的设置方法~
先添加必要文件: <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></scrip ...
- SGU495Kids and Prizes 数学期望
题意: 有n个奖品,m个人排队来选礼物,对于每个人,他打开的盒子,可能有礼物,也有可能已经被之前的人取走了,然后把盒子放回原处.为最后m个人取走礼物的期望. 题解: 本道题与之前的一些期望 DP 题目 ...
- 【剑指Offer】34、第一个只出现一次的字符
题目描述: 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 解题思路: ...
- PHP第一节课
基础语法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- 移动端调试 vConsole
<head> <script src="path/to/vconsole.min.js"></script> <script> va ...
- (C/C++学习)3.C++中cin的成员函数(cin.get();cin.getine()……)
说明:流输入运算符,在一定程度上为C++程序的开发提供了很多便利,我们可以避免C语言那种繁琐的输入格式,比如在输入一个数值时,还需指定其格式,而cin以及cout则不需要.但是cin也有一些缺陷,比如 ...