欢迎访问个人网络日志🌹🌹知行空间🌹🌹
1.基本用法
获取对象的轮廓,一般最好先对图像进行灰度化再进行阈值处理,然后用来检测轮廓。
void cv::findContours(
InputOutputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
- image: 8位单通道图像
- contours: 检测到的轮廓,
vector<vector<cv::Point>> - hierarchy: 检测到的轮廓之间的嵌套和邻近关系,
vector<cv::Vec4i> - mode: 不同的轮廓检测算法,常用的有
RETR_EXTERNAL/RETR_LIST/RETR_CCOMP/RETR_TREE四种 - method: 轮廓逼近方法,见,可使用更少的点表示轮廓,减少内存占用。
- offset: 轮廓点应该偏移的量,当在
roi上提取轮廓后想还原到原图上时比较有用。
2.轮廓提取模式
第四个参数mode,可以选择不同的轮廓提取算法,常用的有RETR_EXTERNAL/RETR_LIST/RETR_CCOMP/RETR_TREE四种。下面分别进行介绍。在findContours函数中,其第3个参数hierarchy表示的轮廓之间的层级关系,对于不同mode的轮廓提取算法,其返回的值是不同的。如下图【来自于OpenCV Doc】:

图中不同的轮廓有层级嵌入关系,我们将外部的轮廓称为父,内部的轮廓称为子,hierarchy就是表示轮廓的父子和邻近关系的矩阵。上图中有0/1/2/3/4/5/2a/3a 8 个轮廓,其中0,1,2是最外侧的轮廓,可记为它们在层级0hierarchy-0。而2a是轮廓2的子轮廓,记为其在层级1hierarchy 1。同样轮廓3是轮廓2a的子轮廓,记为其在层级2hierarchy 2。同样轮廓3a是轮廓3的子轮廓,记为其在层级3hierarchy 3。4/5是3a的子轮廓,其构成层级4hierarchy 4。 属于每个层的轮廓都有其自己的信息,如它的子轮廓是什么,父轮廓是什么,OpenCV通过一个四个元素的数组来表示每个轮廓与其他轮廓的关系,这个四维数组中的值分别表示**[Next, Previous, First_Child, Parent], Next表示属于同一个层级hierarchy的下一个轮廓,以上图轮廓0为例,0,1,2属于同个层级hierarchy-0的轮廓,因此0的Next是1,1的Next是2。同一个层级中轮廓2已经是最后一个了,因此其Next是-1。同样对于上图的轮廓4,与其同属于层级4hierarchy-4的轮廓是5,因此4的Next=5,而5的Next=-1。Previous表示同一层级中之前的的那个轮廓**,如上图,1的Previous=0, 2的Previous=1,0的Previous=-1。First_Child表示当前轮廓的第一个子轮廓,如上图,0的First_Child=-1,2的First_Child=2a,3a的First_Child=4。Parent表示当前轮廓的父轮廓,如上图,4和5的父轮廓都是3a,3a的父轮廓是3,3的父轮廓是2a,2的Parent=-1。
findContours方法中的mode参数会返回不同的hierarchy信息,因为有些算法会找出轮廓间的嵌套和邻近关系,有些则只是把轮廓找出来而不会解析轮廓之间的信息。
2.1 RETR_LIST
RETR_LIST算法只会返回轮廓信息,而没有轮廓间的嵌套信息。因此,所有的轮廓都属于同个层级hierarchy没有父子关系, hierarchy返回值中只有Next和Previous,Parent和First_Child都为-1。四维数组的第3和第4个元素都是-1。如上图运行findContours后的输出:
findContours(image, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
>>> hierarchy
[1, -1, -1, -1]
[2, 0, -1, -1]
[3, 1, -1, -1]
[4, 2, -1, -1]
[5, 3, -1, -1]
[6, 4, -1, -1]
[7,

本文详细介绍了OpenCV中轮廓提取的基本用法及不同模式(RETR_LIST, RETR_EXTERNAL, RETR_CCOMP, RETR_TREE)的特点与应用。通过具体实例展示了如何理解轮廓之间的层级关系及其在图像处理中的作用。
最低0.47元/天 解锁文章
2447

被折叠的 条评论
为什么被折叠?



