查找轮廓并获取bBox(findContours&boundingRect)

先上效果:
在这里插入图片描述

原图和二值化图像

在这里插入图片描述

CV_RETR_EXTERNAL模式下不同的轮廓绘制效果

实现代码如下:

	//读取图像
	cv::Mat image = cv::imread("D:\\PyProject01\\images\\geoface.png");
	imshow("src", image);
	if (image.empty())
	{
    
    
		cout << "读取图像出错" << endl;
		return -1;
	}
	Mat imageGray, imageBw;
	cvtColor(image, imageGray, CV_BGR2GRAY);
	//二值化
	int T1 = 60; 
	threshold(imageGray, imageBw, T1, 255, THRESH_BINARY_INV);
	//寻找轮廓
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(imageBw, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	//drawContours(image, contours, -1, Scalar(255, 0, 0), 1);
	for (int i = 0; i < contours.size(); ++i)
	{
    
    
		cv::Rect rect = cv::boundingRect(cv::Mat(contours[i]));
		cv::rectangle(image, rect, Scalar(0,0,255), 2);
		drawContours(image, contours, i, Scalar(255, 0, 0), 2); 
		//drawContours(image, contours, i, Scalar(255, 0, 0), CV_FILLED, 8, hierarchy);
		//Mat roi = image(rect);  //获取ROI
	}
	imshow("imageBw", imageBw);
	imshow("contours", image);
	waitKey();

findContours函数原形:

void findContours(
InputOutputArray image,
OutputArrayOfArrarys contours,
OutputArray hierarchy,
int mode,
int method,
Point offset=Point() );

drawContours函数原形:

void drawContours(
InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar& color,
int thickness=1,
int lineType=8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point() );

findcontours详解:



cv::void findContours(cv::InputOutputArray image,
                      cv::OutputArrayOfArray contours,
                      cv::OutputArray hierarchy,
                      int mode,     int method,
                      cv::Point offset = cv::Point())
 
 
//完整形式findContours(image, countours,hierarchy, mode,method, offset);
//一般使用时仅输入这四个参数即可findContours(image,countours,mode,method);
 
//image:单通道图像矩阵,可以是灰度图,建议二值图像(最好是Canny/拉普拉斯等边缘检测算子处理后的)
//countours:"vector<vector<Point>>contours"一个双重向量,向量内每个元素保存了一组由连续的point点构成的点的集合的向量,每一组point点集就是一个轮廓
//hierarchy:"vector<Vec4i>hierarchy","Vec4i"是Vec<int,4>的别名,定义了一个“向量内每一个元素包含了四个int型变量”的向量
参数1    image :
单通道图像矩阵。待提取轮廓的图像,可以是灰度图,常用的是二值图。
参数2    contours :
定义为一个双重向量  vector<vector<Point>> contours  每一组Point都连续,构成一组向量集合,在图像上的显示即为一个轮廓(点集),由于一张图像往往包含很多对象,因此一个轮廓不足以描述图像中的所有对象,因此还需要一个容器去包含所有的轮廓,我们称这个包含所有轮廓的容器为轮廓集。所以我们有上述的双重向量的定义方式。    轮廓数量=contours的元素个数
参数3    hierarchy :
定义为  vector<vector<int,4>>hierarchy  或  vector<Vec4i>hierarchy,相当于hierarchy中的每个元素都是一个由4int型组成的集合。直观的表示可以参考列数为4,行数为n的二维矩阵。这四个int型数hierarchy[i][0]~hierarchy[i][3]分别表示后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓的索引编号,如果当前轮廓所对应的这四个轮廓之一有缺失,比如说容器内的第一个轮廓为没有前一个轮廓,则相应位置hierarchy[i][1]=-1
参数4     mode :
该参数用于定义轮廓的检索模式,一般有4种取值(也称为4个宏)
        取值一:CV_RETR_EXTERNAL
        CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
        取值二:CV_RETR_LIST   
        CV_RETR_LIST检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1(即hierarchy[i][2]=hierarchy[i][3]=-1)
        取值三:CV_RETR_CCOMP  
      检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层
        取值四:CV_RETR_TREE
        检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
参数5     method :

用于定义轮廓的近似方法
        取值一:CV_CHAIN_APPROX_NONE 
        保存物体边界上所有连续的轮廓点一般用的比较多
        取值二:CV_CHAIN_APPROX_SIMPLE 
        仅保存轮廓的拐点信息,把所有轮廓拐点保存至contours向量内,拐点与拐点之间直线段上            的信息点不予保留
        取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS
        使用teh-Chinl chain 近似算法中的一个
参数6    offset :
        Point类型,轮廓相对于原轮廓的偏移量(通常使用默认的值 (00))
通常以一个坐标形式 Point 的参数(40,30)出现。(40,30)意思是将轮廓向右移动40个像素,再向下移动30个像素,若数值过大可能会出现溢出报错。

另外,对findcontours函数实现感兴趣的朋友可以参考这篇文章:https://zhuanlan.zhihu.com/p/581439910
参考:https://blog.csdn.net/KarvinDish/article/details/125425123

猜你喜欢

转载自blog.csdn.net/qq_44924694/article/details/129436516