先看提取轮廓的代码:
Mat image = imread("D:/picture/images/binaryGroup.bmp",0);
if(!image.data)
return -1;
imshow("源图像",image);
//获取轮廓
std::vector<std::vector<Point>> contours;
//获取轮廓:
findContours(image, //图像
contours, //轮廓点
//包含图像拓扑结构的信息(可选参数,这里没有选)
CV_RETR_EXTERNAL, //获取轮廓的方法(这里获取外围轮廓)
CV_CHAIN_APPROX_NONE); //轮廓近似的方法(这里不近似,获取全部轮廓)
//打印轮廓信息
std::cout<<"共有外围轮廓:"<<contours.size()<<"条"<<std::endl;
std::vector<std::vector<Point>>::const_iterator itContours = contours.begin();
for(;itContours != contours.end();++itContours)
{
std::cout<<"每个轮廓的长度: "<<itContours->size()<<std::endl;
}
注意到轮廓的存储格式为std::vector<std::vector<Point>>,他说明整个轮廓是若干条轮廓按一定顺序组成的,而每个轮廓中的点也是有顺序的。
画出轮廓就比较简单了:
//画出轮廓
Mat result(image.size(),CV_8U,Scalar(255));
//画出轮廓,参数为:画板,轮廓,轮廓指示(这里画出所有轮廓),颜色,线粗
drawContours(result,contours,-1,Scalar(0),2);
imshow("提取外围轮廓",result);
还要注意提取轮廓的方法还有很多种,比如CV_RETR_LIST代表所有轮廓
findContours(image, //图像
contours, //轮廓点
//包含图像拓扑结构的信息(可选参数,这里没有选)
CV_RETR_LIST, //获取轮廓的方法(这里获取所有轮廓)
CV_CHAIN_APPROX_NONE); //轮廓近似的方法(这里不近似,获取全部轮廓
//画出轮廓
drawContours(result,contours,-1,Scalar(0),2);
imshow("提取所有轮廓",result);
通常,这样提取的轮廓包含一些我们不希望的轮廓(比如一些小洞),或者假如我们知道我们感兴趣的物体轮廓的大概范围时,我们就可以用下面的办法缩小目标范围:
//除去太长或者太短的轮廓
int cmin = 100;
int cmax = 1000;
std::vector<std::vector<Point>>::const_iterator itc = contours.begin();
while(itc != contours.end())
{
if(itc->size() < cmin || itc->size() > cmax)
itc = contours.erase(itc);
else
++itc;
}
//把结果画在源图像上:
Mat original = imread("D:/picture/images/group.jpg");
if(!original.data)
return -1;
drawContours(original,contours,-1,Scalar(255,255,255),2);
imshow("动物的轮廓",original);
//将轮廓重绘于白板上
result.setTo(Scalar(255));
drawContours(result,contours,-1,Scalar(0),1);
怎么提取轮廓的特征呢?OpenCV提供了很多函数,我们展示其中的几个:
//轮廓的形状描述子
//外接矩形
Rect r0 = boundingRect(Mat(contours[0]));
rectangle(result,r0,Scalar(0),2);
//最小外接圆
float radius;
Point2f center;
minEnclosingCircle(Mat(contours[1]),center,radius);
circle(result,Point(center),static_cast<int>(radius),Scalar(0),2);
//多边形估计
std::vector<Point> poly;
//参数为:输入图像的2维点集,输出结果,估计精度,是否闭合
approxPolyDP(Mat(contours[2]),poly,5,true);
std::cout<<"多边形大小:"<<poly.size()<<std::endl;
//画出结果
std::vector<Point>::const_iterator itp = poly.begin();
while(itp != poly.end()-1)
{
line(result,*itp,*(itp+1),Scalar(0),2);
++itp;
}
//将第一个点和最后一点连起来
line(result,*(poly.begin()),*(poly.end()-1),Scalar(128),2);
//计算凸包
std::vector<Point> hull;
convexHull(Mat(contours[3]),hull);
std::vector<cv::Point>::const_iterator it= hull.begin();
while(it != (hull.end()-1))
{
line(result,*it,*(it+1),Scalar(0),2);
++it;
}
line(result,*(hull.begin()),*(hull.end()-1),Scalar(0),2);
//计算矩信息
itc = contours.begin();
while(itc != contours.end())
{
//计算所有的距
Moments mom = moments(Mat(*itc++));
//计算并画出质心
circle(result,Point(mom.m10/mom.m00,mom.m01/mom.m00),2,Scalar(2),2);
}
imshow("形状描述子",result);
我们再次看到,轮廓的确是有顺序的。值得注意的是矩信息:OpenCV提供了一个结构体Moments,它的元素就是计算好的矩信息,里面存放了常用的距。
其实,OpenCV还提供了许多其他的形状描述子,比如函数cv::minAreaRect计算了最小外界倾斜的矩形。函数cv::contourArea估计轮廓区域的面积(里面的像素数)。函数cv::pointPolygonTest计算一个点是否在轮廓内,cv::matchShapes测量了2两个轮廓的相似程度等等。这里就不一一介绍了。
分享到:
相关推荐
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 010】提取直线、轮廓及连通区域》 博文链接: http://blog.csdn.net/davebobo/article/details/52583167 OpenCV版本:2.4.9
OpenCV 3计算机视觉:Python语言实现,代码+pdf文档,适合于计算机视觉研究者
开发环境为QT5.8+opencv3.2,主要实现了边缘检测,轮廓提取及轮廓跟踪,边缘检测使用了Canny算子、Sobel算子、Laplacian算子,轮廓跟踪使用八邻域法。
NULL 博文链接:https://westice.iteye.com/blog/721225
从静态的视频帧中获取的人物图片先二值化,再利用开操作闭操作以及轮廓填充,获取人物轮廓
基于OpenCV的图像轮廓提取实现,添加有滑动条可进行参数调节,实时显示提取效果
Opencv学习笔记 辛苦收集希望和大家交流
爱分享、爱极客的编程怪兽--DaveBobo 博文 《【OpenCV学习笔记 005】 操作像素》 博文链接: http://blog.csdn.net/davebobo/article/details/52541612 OpenCV版本:2.4.9
这个一个很基础的opencv学习笔记,一些常会遇到的问题,在这里做了肤浅的介绍,还有很多问题没有提及,以后会陆续整理,并上传
OpenCV学习笔记入门版,真正的入门级别,自己写的
opencv的学习资料:OpenCV2.1.pdf OpenCV中文手册 learning opencv电子版
OpenCV 3计算机视觉:Python语言实现 (Joe Minichino)
本方法是急于OpenCv下的图像轮廓提取方法
OpenCV视频提取轮廓的代码,有注释,很简单的例程,适用初学者
OpenCV学习笔记,(基础概念,归纳总结),相信你所选择的。
这是一个基于opencv的图像轮廓提取程序,可以识别轮廓边沿,是初级学者的参考代码
OpenCV学习笔记(C++版OpenCV学习笔记,主要包括基础模块和DNN模块)带详细注释源码!!!
标题学习opencv第一天: 一、图像基本操作: 1.图像读取:cv.imread(“文件位置:D:/python/picture.png” ) 函数功能:从文件路径中读取图片文件并显示出来,可读取的文件类型有JPG、JPEG、PNG、Webp等 函数原型:...
opencv+vs2005 图像处理的轮廓提取显示
OpenCV轮廓提取的源代码