opencv使用findContours寻找物体轮廓

OpenCV中的findContours函数是用来检测物体的轮廓

函数原型:

CV_EXPORTS_W void findContours( InputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset = Point());

/** @overload */
CV_EXPORTS void findContours( InputArray image, OutputArrayOfArrays contours,
                              int mode, int method, Point offset = Point());

@brief Finds contours in a binary image.在二值图像中寻找轮廓。

The function retrieves contours from the binary image using the algorithm @cite Suzuki85 . The contours
are a useful tool for shape analysis and object detection and recognition. See squares.cpp in the
OpenCV sample directory.

使用@cite Suzuki85算法从二进制图像中检索功能轮廓。 轮廓是用于形状分析以及对象检测和识别的有用工具。 请参阅OpenCV示例目录。

@note Since opencv 3.2 source image is not modified by this function.

@param image Source, an 8-bit single-channel image. 

Non-zero pixels are treated as 1's. Zeropixels remain 0's, so the image is treated as binary .

非零像素视为1。 零像素保持为0,因此图像被视为二进制图像。

 You can use #compare, #inRange, #threshold ,#adaptiveThreshold, #Canny, and others to create a binary image out of a grayscale or color one.If mode equals to #RETR_CCOMP or #RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1).

您可以使用#compare,#inRange,#threshold,#adaptiveThreshold,#Canny和其他来创建灰度或彩色的二进制图像。如果模式等于#RETR_CCOMP或#RETR_FLOODFILL,则输入也可以是标签(CV_32SC1)的32位整数图像。

@param contours Detected contours. Each contour is stored as a vector of points (e.g.std::vector<std::vector<cv::Point> >).

检测到轮廓 每个轮廓都存储为点的向量(例如std :: vector <std :: vector <cv :: Point >>)
@param hierarchy Optional output vector (e.g. std::vector<cv::Vec4i>), containing information about the image topology. It has as many elements as the number of contours. For each i-th contour contours[i], the elements
hierarchy[i][0] , hierarchy[i][1] , hierarchy[i][2] , and hierarchy[i][3] are set to 0-based indices in contours of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.

可选输出向量(例如:std::vector<cv::Vec4i>),包含关于图像拓扑的信息。它的元素和轮廓的数量一样多。对于每一个第i条等高线[i],将元素hierarchy[i][0]、hierarchy[i][1]、hierarchy[i][2]、hierarchy[i][3]分别设置为下一个等高线和上一个等高线(即第一个子等高线和父等高线)的基于0的等高线索引。如果轮廓i没有下一个、上一个、父轮廓或嵌套轮廓,层次结构[i]中的相应元素将为负。

@param mode Contour retrieval mode, see #RetrievalModes 轮廓检索模式
@param method Contour approximation method, see #ContourApproximationModes 轮廓近似法
@param offset Optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context.

第一个参数:image,8bit单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;

第二个参数:contours,定义为vector<vector<Point>> contours”,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。  有多少轮廓,向量contours就有多少元素。

第三个参数:hierarchy,定义为“vector<Vec4i> hierarchy”,先来看一下Vec4i的定义: typedef     Vec<int, 4>   Vec4i;                                                                                                                                       

           Vec4i是Vec<int,4>的别名,定义了一个“向量内每一个元素包含了4个int型变量”的向量。所以从定义上看,hierarchy也是一个向量,向量内每个元素保存了一个包含4个int整型的数组。向量hiararchy内的元素和轮廓向量contours内的元素是对应的,向量的容量相同。hierarchy向量内每一个元素的4个int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第  i个轮廓的一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个 轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] ~hierarchy[i][3]的相应位被设置为默认值-1。

第四个参数:int型的mode,定义轮廓的检索模式

  •  取值一:CV_RETR_EXTERNAL 只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
  • 取值二:CV_RETR_LIST   检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量 都会被置为-1,具体下文会讲到
  • 取值三:CV_RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层
  • 取值四:CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。

第五个参数:int型的method,定义轮廓的近似方法:

  •            取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内
  •            取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留
  •            取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

第六个参数:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量并且Point还可以是负值。

#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("4.jpg", 0);
	imshow("Source Image", imageSource);
	Mat image;
	//高斯滤波
	GaussianBlur(imageSource, image, Size(3, 3), 0);
	//边缘检测
	Canny(image, image, 100, 250);
	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);
	Mat Contours = Mat::zeros(image.size(), CV_8UC1);  //绘制
	for (int i = 0; i < contours.size(); i++)
	{
		//contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数
		for (int j = 0; j < contours[i].size(); j++)
		{
			//绘制出contours向量内所有的像素点
			Point P = Point(contours[i][j].x, contours[i][j].y);
			Contours.at<uchar>(P) = 255;
		}

		//输出hierarchy向量内容
		cout << "向量hierarchy的第" << i << " 个元素内容为:" << endl << hierarchy[i] << endl << endl;

		//绘制轮廓
		drawContours(imageContours, contours, i, Scalar(255), 1, 8, hierarchy);
	}
	imshow("Contours Image", imageContours); //轮廓
	imshow("Point of Contours", Contours);   //向量contours内保存的所有轮廓点集
	waitKey(0);
	return 0;
}

 参考文章:

findContours函数参数详解

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值