当前位置:网站首页>(12) findContours function hierarchy explanation
(12) findContours function hierarchy explanation
2022-08-10 19:56:00 【Heng Youcheng】
欢迎访问个人网络日志知行空间
1.基本用法
Get the outline of the object,Generally, it is best to first grayscale the image and then perform thresholding,and then used to detect contours.
void cv::findContours(
InputOutputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
- image: 8位单通道图像
- contours: 检测到的轮廓,
vector<vector<cv::Point>>
- hierarchy: Nesting and proximity relationships between detected contours,
vector<cv::Vec4i>
- mode: Different contour detection algorithms,常用的有
RETR_EXTERNAL/RETR_LIST/RETR_CCOMP/RETR_TREE
四种 - method: 轮廓逼近方法,见,Contours can be represented using fewer points,减少内存占用.
- offset: The amount by which the contour points should be offset,当在
roi
It is useful when you want to restore the original image after extracting the contour.
2.轮廓提取模式
第四个参数mode
,Different contour extraction algorithms can be selected,常用的有RETR_EXTERNAL/RETR_LIST/RETR_CCOMP/RETR_TREE
四种.下面分别进行介绍.在findContours
函数中,其第3个参数hierarchy
Represents a hierarchical relationship between contours,对于不同mode
contour extraction algorithm,其返回的值是不同的.如下图【来自于OpenCV Doc】:
Different contours in the graph have hierarchical embedded relationships,We call the outer contours 父,The inner contour is called子,hierarchy
It is a matrix representing the parent-child and adjacent relationship of contours.上图中有0/1/2/3/4/5/2a/3a
8 个轮廓,其中0,1,2
is the outermost contour,Can be recorded as they are in the hierarchy0hierarchy-0
.而2a
是轮廓2
的子轮廓,Note that it is in the hierarchy1hierarchy 1
.同样轮廓3
是轮廓2a
的子轮廓,Note that it is in the hierarchy2hierarchy 2
.同样轮廓3a
是轮廓3
的子轮廓,Note that it is in the hierarchy3hierarchy 3
.4/5
是3a
的子轮廓,its composition hierarchy4hierarchy 4
. The contours belonging to each layer have their own information,Such as what its sub-contours are,What is the parent profile,OpenCV
The relationship of each contour to other contours is represented by a four-element array,The values in this four-dimensional array are represented separately**[Next, Previous, First_Child, Parent]
, Next
Indicates that they belong to the same levelhierarchy
the next contour,Outline above0
为例,0,1,2
belong to the same levelhierarchy-0
的轮廓,因此0
的Next
是1
,1
的Next
是2
.contours in the same level2
已经是最后一个了,因此其Next
是-1
.The same goes for the contours in the image above4
,It belongs to the same level4hierarchy-4
的轮廓是5
,因此4
的Next=5
,而5
的Next=-1
.Previous
Represents the previous contour in the same level**,如上图,1
的Previous=0
, 2
的Previous=1
,0
的Previous=-1
.First_Child
Represents the first subcontour of the current contour,如上图,0
的First_Child=-1
,2
的First_Child=2a
,3a
的First_Child=4
.Parent
Represents the parent contour of the current contour,如上图,4
和5
The parent contours of 3a
,3a
的父轮廓是3
,3
的父轮廓是2a
,2
的Parent=-1
.
findContours
方法中的mode
parameters will return differenthierarchy
信息,Because some algorithms will find the nesting and adjacent relationship between contours,Some just find the contours without parsing the information between the contours.
2.1 RETR_LIST
RETR_LIST
The algorithm will only return contour information,There is no nesting information between contours.因此,All contours belong to the same levelhierarchy
没有父子关系, hierarchy
返回值中只有Next
和Previous
,Parent
和First_Child
都为-1
.The first of a four-dimensional array3和第4个元素都是-1
.Run as shown abovefindContours
后的输出:
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, 5, -1, -1]
[-1, 6, -1, -1]
这里的0/1/2/3/4/5/6/7
Correspondingly, the outline is incontours
中的下标.
2.2 RETR_EXTERNAL
RETR_EXTERNAL
算法,Only the outermost contour information will be returned,All subcontours are not returned,如上图,使用RETR_EXTERNAL
The algorithm will just returnhierarchy-0
层级0
的3个轮廓.当然hierarchy
中也只有3
proximity information between contours,Parent
和First_Child
依然都为-1
.
findContours(image, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
[1, -1, -1, -1]
[2, 0, -1, -1]
[-1, 1, -1, -1]
2.3 RETR_CCOMP
RETR_CCOMP
The algorithm will find all the contours in the graph,But only the outlines will be organized into two layershierarchy=2
.The outer contour of the object belongs tohierarchy-0
,The inner contour belongs tohierarchy-1
,如上图0/1/2/3/4/5
都属于hierarchy-0
,而2a/3a
属于hierarchy-1
.
findContours(image, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
[1, -1, -1, -1]
[2, 0, -1, -1]
[4, 1, 3, -1]
[-1, -1, -1, 2]
[6, 2, 5, -1]
[-1, -1, -1, 4]
[7, 4, -1, -1]
[-1, 6, -1, -1]
It's worth noting for contours2a
和3a
,其hierarchy
分别是[-1, -1, -1, 2]
和[-1, -1, -1, 4]
.这是因为2a
和3a
虽然属于hierarchy-1
,But there is still an outline in the middle3
,因此2a
和3a
There is no proximity relationship between them.
再来看个例子,如下图:【来自于OpenCV Doc】
轮廓0
is the outer contour,1
和2
respectively the outline0
The inner contour of the enclosed object,4
belongs to the inner contour,3
belong to the outer contour,6
belongs to the inner contour,5
belong to the outer contour,7
和8
Also belong to the outer contour.对于轮廓0
其属于hierarchy-1
,Two inner contours1
和2
属于hierarchy-2
.So for contours0
,其Next=3
,same levelhierarchy level
的下一个,previous=-1
,‵First-Child=1,so outline
0的
hierarchy=[3,-1, 1, -1]`.
轮廓1
belong to the hierarchy2
,hierarchy-2
,its next at the same level(与1
in the same parent outline)轮廓是2
,其他均为-1
,因此轮廓1
的hierarchy=[2, -1, -1, 0]
.
轮廓2
belong to the hierarchy2
,hierarchy-2
,Its previous contour is under the same parent outer contour1
,其余为-1
,因此轮廓2
的hierarchy=[-1, 1, -1, 0]
.
轮廓3
在hierarchy-1
中的Next=5,Previous=0,First-Child=4,Parent=-1
.
>>> hierarchy
array([[[ 3, -1, 1, -1],
[ 2, -1, -1, 0],
[-1, 1, -1, 0],
[ 5, 0, 4, -1],
[-1, -1, -1, 3],
[ 7, 3, 6, -1],
[-1, -1, -1, 5],
[ 8, 5, -1, -1],
[-1, 7, -1, -1]]])
2.4 RETR_TREE
RETR_TREE
The algorithm extracts all contours,and returns the nested relationship between all contours.如上图,使用RETR_TREE
the resulting contourhierarchy
之间的关系为:【来自于OpenCV Doc】The green words in parentheses indicate the level to which the contour belongshierarchy
.
以轮廓0
为例,其属于hierarchy-0
,‵Next=7, Previous=-1, First_Child=1, Parent=-1`.
>>> hierarchy
array([[[ 7, -1, 1, -1],
[-1, -1, 2, 0],
[-1, -1, 3, 1],
[-1, -1, 4, 2],
[-1, -1, 5, 3],
[ 6, -1, -1, 4],
[-1, 5, -1, 4],
[ 8, 0, -1, -1],
[-1, 7, -1, -1]]])
findContours(image, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
[3, -1, 1, -1]
[2, -1, -1, 0]
[-1, 1, -1, 0]
[5, 0, 4, -1]
[-1, -1, -1, 3]
[6, 3, -1, -1]
[-1, 5, -1, -1]
3.测试代码
#include <opencv2/opencv.hpp>
#include <common.h>
using namespace std;
int main(int argc, char **argv)
{
cv::RNG rng(12345);
cout << "Usage: " << argv[0] << "\n";
cv::String img_dir = "/images/OpenCV/2findContours/hole-hierarchy.png";
cv::Mat image = cv::imread(img_dir, cv::IMREAD_GRAYSCALE);
vector<cv::Vec4i> hierarchy;
vector<vector<cv::Point> > contours;
findContours(image, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
std::cout << "Contours Size: " << contours.size() << std::endl;
for(size_t i=0; i<contours.size(); i++)
{
cv::Scalar clr = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
cv::drawContours(image, contours, i, clr, 3);
}
for(auto &v : hierarchy)
{
std::cout << v << std::endl;
}
std::cout << image.channels() << std::endl;
cv::imwrite("contours.png", image);
cv::imshow("Img", image);
cv::waitKey(0);
return 0;
}s
参考资料
欢迎访问个人网络日志知行空间
边栏推荐
- 电脑为什么会蓝屏的原因
- CAS:190598-55-1_Biotin sulfo-N-hydroxysuccinimide ester生物素化试
- 赎金信问题答记
- pytorch使用Dataloader加载自己的数据集train_X和train_Y
- 力扣150-逆波兰表达式求值——栈实现
- Redis persistence mechanism
- What is the upstream bandwidth and downstream bandwidth of the server?
- [Go WebSocket] Your first Go WebSocket server: echo server
- nfs挂载服务器,解决挂载后无法更改用户id,无法修改、写文件,文件只读权限Read-only file system等问题
- 史上最全GIS相关软件(CAD、FME、Arcgis、ArcgisPro)
猜你喜欢
Colocate Join :ClickHouse的一种高性能分布式join查询模型
3D游戏建模学习路线
QoS Quality of Service Six Router Congestion Management
Optimization is a habit The starting point is to 'stand close to the critical'
2022杭电多校七 Black Magic (签到)
We used 48h to co-create a web game: Dice Crush, to participate in international competitions
[Go WebSocket] Your first Go WebSocket server: echo server
[email protected] NPs纳米酶|碳纳米管负载铂颗粒纳米酶|白血病拮抗多肽修饰的FeOPtPEG复合纳米酶"/>
Pt/CeO2单原子纳米酶|[email protected] NPs纳米酶|碳纳米管负载铂颗粒纳米酶|白血病拮抗多肽修饰的FeOPtPEG复合纳米酶
【无标题】基于Huffman和LZ77的GZIP压缩
主动信息收集
随机推荐
测试/开发程序员值这么多钱么?“我“不会愿赌服输......
keepalived:故障检测自动修复脚本
Random函数用法
烟雾、空气质量、温湿度…自己徒手做个环境检测设备
转铁蛋白(TF)修饰紫杉醇(PTX)脂质体(TF-PTX-LP)|转铁蛋白(Tf)修饰姜黄素脂质体
nfs挂载服务器,解决挂载后无法更改用户id,无法修改、写文件,文件只读权限Read-only file system等问题
ARouter使用自定义注解处理器,自动生成跳转Activity的代码,避免手动填写和管理path
spark学习笔记(九)——sparkSQL核心编程-DataFrame/DataSet/DF、DS、RDD三者之间的转换关系
铱钌合金/氧化铱仿生纳米酶|钯纳米酶|GMP-Pd纳米酶|金钯复合纳米酶|三元金属Pd-M-Ir纳米酶|中空金铂合金纳米笼核-多空二氧化硅壳纳米酶
大家要的Biotin-PEG3-Br/acid/NHS ester/alcohol/amine合集分享
Colocate Join :ClickHouse的一种高性能分布式join查询模型
We used 48h to co-create a web game: Dice Crush, to participate in international competitions
产品思维训练 | 新用户从注册到绑卡流失率很高是什么原因?
手把手教你Charles抓包工具使用
Introduction to 3 d games beginners essential 】 【 modeling knowledge
(十二) findContours函数的hierarchy详解
你不知道的浏览器页面渲染机制
flask的配置文件
【SemiDrive源码分析】【MailBox核间通信】52 - DCF Notify 实现原理分析 及 代码实战
mysql 中大小写问题