http://lib.csdn.net/article/opencv/29324(原文地址)
1. OpenCV中的Adaboost级联分类器的结构,包括强分类器和弱分类器的形式;
2. opencv自带的XML分类器中各项参数的含义,如internalNodes和leafValues标签里面的一大堆数字的意义。
下面进入正题。
——————————————-
众所周知,OpenCV中的Adaboost级联分类是树状结构,如图1,其中每一个stage都代表一级强分类器。当检测窗口通过所有的强分类器时才被认为是目标,否则拒绝。实际上,不仅强分类器是树状结构,强分类器中的每一个弱分类器也是树状结构。
图1 强分类器和弱分类器示意图
(这张图有笔误,应该是stage0,stage1,…,stageN-1,各位看官理解就好)
这篇文章将结合OpenCV-2.4.11中自带的haarcascade_frontalface_alt2.xml文件介绍整个级联分类器的结构。需要说明,自从2.4.11版本后所有分类器都被替换成新式XML,所以本文介绍新式XML结构。
1 XML的头部
在了解OpenCV分类器结构之前,先来看看存储分类器的XML文件中有什么。图2中注释了分类器XML文件头部信息,括号中的参数为opencv_traincascade.exe训练程序对应参数,即训练时设置了多少生成的XML文件对应值就是多少(如果不明白,可以参考我的前一篇文章)。
图2 分类器XML文件头部含义
其中<features>标签存储了所有的Haar特性,在本系列文章一中有讲解。
2 弱分类器结构
一个完整的弱分类器包括:1.若干个Haar特征 + 和Haar特征数量相等的弱分类器阈值2. 若干个leftValue3. 若干个rightValue
- 计算第一个Haar特征的特征值haar1,与第一个弱分类器阈值t1对比,当haar1<t1时,进入步骤2;当haar1>t1时,该弱分类器输出rightValue2并结束。
- 计算第二个Haar特征值haar2,与第二个弱分类器阈值t2对比,当haar2<t2时输出leftValue;当haar2>t2时输出rightValue1。
即通过上述步骤计算弱分类器输出值,这与OpenCV的cascadedetect.hpp文件中的predictOrdered()函数代码对应(这里简单解释一下,在OpenCV中所有弱分类器的leftValue和rightValue都依次存储在一个一维数组中,代码中的leafOfs表示当前弱分类器中leftValue和rightValue在该数组中存储位置的偏移量,idx表示在偏移量leafOfs基础上的leftValue和rightValue值的索引,cascadeLeaves[leafOfs - idx]就是该弱分类器的输出):
- do
- {
- CascadeClassifier::Data::DTreeNode& node = cascadeNodes[root + idx];
- double val = featureEvaluator(node.featureIdx);
- idx = val < node.threshold ? node.left : node.right;
- }
- while( idx > 0 );
- sum += cascadeLeaves[leafOfs - idx];
看到这里,你应该明白了弱分类器的工作方式,即通过计算出的Haar特征值与弱分类器阈值对比,从而选择最终输出leftValue和rightValue值中的哪一个。
- sum += cascadeLeaves[leafOfs - idx];
1. 为了找到图像中不同位置的目标,需要逐次移动检测窗口(窗口中的Haar特征相应也随着移动),这样就可以遍历到图像中的每一个位置;
2. 而为了检测到不同大小的目标,一般有两种做法:逐步缩小图像or逐步放大检测窗口,这样即可遍历到图像中不同大小的目标
- #define CV_HAAR_SCALE_IMAGE 2
下一篇,我会介绍一个必须但又容易被忽略的问题——利用并查集合并检测结果窗口。
http://lib.csdn.net/article/opencv/29324(原文地址)
1. OpenCV中的Adaboost级联分类器的结构,包括强分类器和弱分类器的形式;
2. opencv自带的XML分类器中各项参数的含义,如internalNodes和leafValues标签里面的一大堆数字的意义。
下面进入正题。
——————————————-
众所周知,OpenCV中的Adaboost级联分类是树状结构,如图1,其中每一个stage都代表一级强分类器。当检测窗口通过所有的强分类器时才被认为是目标,否则拒绝。实际上,不仅强分类器是树状结构,强分类器中的每一个弱分类器也是树状结构。
图1 强分类器和弱分类器示意图
(这张图有笔误,应该是stage0,stage1,…,stageN-1,各位看官理解就好)
这篇文章将结合OpenCV-2.4.11中自带的haarcascade_frontalface_alt2.xml文件介绍整个级联分类器的结构。需要说明,自从2.4.11版本后所有分类器都被替换成新式XML,所以本文介绍新式XML结构。
1 XML的头部
在了解OpenCV分类器结构之前,先来看看存储分类器的XML文件中有什么。图2中注释了分类器XML文件头部信息,括号中的参数为opencv_traincascade.exe训练程序对应参数,即训练时设置了多少生成的XML文件对应值就是多少(如果不明白,可以参考我的前一篇文章)。
图2 分类器XML文件头部含义
其中<features>标签存储了所有的Haar特性,在本系列文章一中有讲解。
2 弱分类器结构
一个完整的弱分类器包括:1.若干个Haar特征 + 和Haar特征数量相等的弱分类器阈值2. 若干个leftValue3. 若干个rightValue
- 计算第一个Haar特征的特征值haar1,与第一个弱分类器阈值t1对比,当haar1<t1时,进入步骤2;当haar1>t1时,该弱分类器输出rightValue2并结束。
- 计算第二个Haar特征值haar2,与第二个弱分类器阈值t2对比,当haar2<t2时输出leftValue;当haar2>t2时输出rightValue1。
即通过上述步骤计算弱分类器输出值,这与OpenCV的cascadedetect.hpp文件中的predictOrdered()函数代码对应(这里简单解释一下,在OpenCV中所有弱分类器的leftValue和rightValue都依次存储在一个一维数组中,代码中的leafOfs表示当前弱分类器中leftValue和rightValue在该数组中存储位置的偏移量,idx表示在偏移量leafOfs基础上的leftValue和rightValue值的索引,cascadeLeaves[leafOfs - idx]就是该弱分类器的输出):
- do
- {
- CascadeClassifier::Data::DTreeNode& node = cascadeNodes[root + idx];
- double val = featureEvaluator(node.featureIdx);
- idx = val < node.threshold ? node.left : node.right;
- }
- while( idx > 0 );
- sum += cascadeLeaves[leafOfs - idx];
看到这里,你应该明白了弱分类器的工作方式,即通过计算出的Haar特征值与弱分类器阈值对比,从而选择最终输出leftValue和rightValue值中的哪一个。
- sum += cascadeLeaves[leafOfs - idx];
1. 为了找到图像中不同位置的目标,需要逐次移动检测窗口(窗口中的Haar特征相应也随着移动),这样就可以遍历到图像中的每一个位置;
2. 而为了检测到不同大小的目标,一般有两种做法:逐步缩小图像or逐步放大检测窗口,这样即可遍历到图像中不同大小的目标
- #define CV_HAAR_SCALE_IMAGE 2
下一篇,我会介绍一个必须但又容易被忽略的问题——利用并查集合并检测结果窗口。