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边缘图像只是一些相互独立的散点勾勒出了一个边界,点与点之间没有联系,是没有“思想”的;

轮廓图像是一系列的点组成的,相邻的点与点同属于一个轮廓“集合”,连续的点构成了一个整体,甚至我们可以通过编号对每个轮廓定位,定义其前后轮廓线段,内外轮廓包含、隶属等树形关系,是有“思想”,可进一步处理的。


原文地址:https://www.cnblogs.com/mtcnn/p/9411985.html