流程:原图转灰度图—灰度图转二值图—(滤波)—找轮廓
void findContours( InputOutputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset = Point());
参数image:inputArray类型的输入图像,填Mat类的对象即可,要是二值图
参数contours:检测到的轮廓,函数调用后的结果存放在这里,每个轮廓存储为一个点向量,用Point类型的vector表示:
vector<vector<Point>> contours;
里面的容器代表一个轮廓的每个点,外面的容器代表的每个轮廓
参数hierarchy:是可选的输出向量,包含了图像的拓扑信息。其作为轮廓数量的表示,包含了许多元素。每个轮廓contours[i]对应4个hierarchy元素:
hierarchy[i][0],hierarchy[i][1],hierarchy[i][2],hierarchy[i][3]
分别表示后一个轮廓,前一个轮廓,子轮廓,父轮廓 的索引编号,如果没有对应项,
则对应的hierarchy[i]值设置为负值。
可表示为: vector<Vec4i> hierarchy;
参数mode:轮廓的检索模式。
①RETR_EXTERNAL:只检测最外的轮廓,对于所以轮廓都设置为
hierarchy[i][2] = hierarchy[i][3] = -1
②RETR_LIST:将检测到的所有轮廓放在list中,轮廓不建立等级关系(也就没有子,父轮廓)
③RETR_CCOMP:将检测到的所有轮廓分成两个等级,顶层是外部轮廓,
第二层是孔洞的内部轮廓,如果内部轮廓里面还有轮廓,那么里面的轮廓归属于顶层轮廓
④RETE_TREE:将检测到的所有轮廓按照等级树归分
***后面三种几乎都可以检测出全部轮廓,只是顺序不一样***
参数method:为轮廓的近似方法
① CHAIN_APPROX_NONE:获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1,
即max(abs(x1 - x2), abs(y2 - y1)) == 1
(即保存所有连续的轮廓点到contours向量内)
② CHAIN_APPROX_SIMPLE:压缩水平,垂直,对角线方向的元素,只保留该方向的终点坐标。
例如矩形轮廓只要四个顶点
(即仅仅保存轮廓的拐点,存入contours向量内)
③ CHAIN_APPROX_TC89_L1:使用Teh-Chin链算法
④ CHAIN_APPROX_TC89_KCOS:使用Teh-Chin链算法
参数offset:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量
轮廓层级原理:
如图中有0,1,2,3,4这四个轮廓,这个序号是我随意编写,在程序中findContours()函数会自动寻找标记,这也是轮廓检索的序号,序号从0~(N-1)。
以mode:RETR_TREE模式为例讲解:
后一个轮廓,前一个轮廓的概念是同级的
1.图中0号没有后一个,前一个轮廓,父轮廓,有子轮廓1,3,按照序号的顺序,优先选择子轮廓1,所以表达方式是:hierarchy[-1,-1,1,-1] (-1代表没有对应的轮廓)
2.图中1号按照序号的顺序,3号是它的后一个轮廓,没有前一个轮廓,有子轮廓2号,父轮廓0号,所以表达方式是:hierarchy[3,-1,2,0]
3.图中2号没有后一个,前一个,以及子轮廓,有父轮廓1号,表示为hierarchy[-1,-1,-1,1]
4.图中3号没有后一个轮廓,有前一个轮廓1号,子轮廓4号,父轮廓0号,所以表示为
hierarchy[-1,1,4,0];
5.图中4号没有后一个,前一个,以及子轮廓,有父轮廓3号,表示为hierarchy[-1,-1,-1,3]
绘制轮廓:
void drawContours( InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point() );
参数image:目标图像;
参数contours:所有的输入轮廓;
参数contourIdx:表示绘制第几个轮廓,当为负值表示绘制全部轮廓;
参数color:绘制颜色;
参数thickness:绘制粗细,为负值则绘制在轮廓内部;
参数lineType:线的类型;
参数hierarchy:可选的层次结构信息,默认Mat();
参数maxLevel:表示用于绘制轮廓的最大等级;
参数offset:偏移参数。