当前位置:   article > 正文

detectmultiscale函数参数含义_分类器是如何做检测的?——CascadeClassifier中的detectMultiScale函数解读...

detectmultiscale

原地址:http://blog.csdn.net/delltdk/article/details/9186875

在进入detectMultiScal函数之前,首先需要对CascadeClassifier做初始化。

1.     初始化——read函数

CascadeClassifier的初始化很简单:

cv::CascadeClassifier classifier;

classifier.load(“cascade.xml”); //这里的xml是训练得到的分类器xml

CascadeClassifier类中既有load也有read函数,二者是相同的,load将引用read函数。

1.1   xml的结构

训练得到的分类器以xml形式保存,整体上它包括stageType、featureType、height、width、stageParams、featureParams、stages、features几个节点。

图1. 分类器的Xml文件整体结构

除stages和features外,其他主要是一些分类器的参数。

Stages中包含15个stage(训练程序设定),每个stage中包含多个weakClassifiers,而每个weakClassifier中又包含一个internalNodes和一个leafValues。internalNodes中四个变量代表一个node,分别为node中的left/right标记、特征池中的ID和threshold。leafValues中两个变量代表一个node,分别为left leaf的值和right leaf的值。

图2. 分类器的Xml文件具体结构

而features是分类器的特征池,每个特征包含一个矩形和要提取的特征序号(0~35)。

图3. features的具体结构

1.2   read的过程

下面是read代码,主要包括从xml中获取两部分内容:data和featureEvaluator的读取。

bool CascadeClassifier::read(constFileNode&root)

{

if( !data.read(root) )//data成员变量的读取

return false;

// load features---特征的读取

featureEvaluator= FeatureEvaluator::create(data.featureType);

FileNodefn =root[CC_FEATURES];

if( fn.empty() )

return false;

return featureEvaluator->read(fn);

}

1.2.1         data成员变量的读取

data的读取中同样可以分为两部分:分类器参数读取和stage分类树的建立。

首先是参数部分的获取。

static constfloatTHRESHOLD_EPS= 1e-5f;

// load stage params

// stageType为BOOST类型

string stageTypeStr = (string)root[CC_STAGE_TYPE];

if( stageTypeStr == CC_BOOST)

stageType= BOOST;

else

return false;

//这里以HOG特征分类器为例,featureType=2(HOG)

string featureTypeStr = (string)root[CC_FEATURE_TYPE];

if( featureTypeStr == CC_HAAR)

featureType= FeatureEvaluator::HAAR;

else if( featureTypeStr== CC_LBP )

featureType= FeatureEvaluator::LBP;

else if( featureTypeStr== CC_HOG )

featureType= FeatureEvaluator::HOG;

else

return false;

//检测窗口的最小size,也就是正样本的size

origWinSize.width = (int)root[CC_WIDTH];

origWinSize.height = (int)root[CC_HEIGHT];

CV_Assert(origWinSize.height> 0 &&origWinSize.width > 0 );

//我训练得到的HOG分类器为true,还不清楚这里的意思

isStumpBased= (int)(root[CC_STAGE_PARAMS][CC_MAX_DEPTH])== 1 ?true : false;

// load feature params

//载入特征参数,HOG分类器下包括两个参数:maxCatCount和featSize,featSize很透明,就是特征的种类数,这里为36,是指每个block中4个cell、每个cell9个梯度方向的直方图。例如特征号为3时,计算的是当前窗口中划分为4个cell后第一个cell中所有点在120°方向(可能是,这要视起始角度而定)上分量的和,然后经过归一化后的值。对于第二个参数maxCatCount,这里为0,尚不清楚(这是指代表一个弱分类器的树的类别数量,用来计算一棵树的节点大小也就是nodeStep)

FileNode fn = root[CC_FEATURE_PARAMS];

if( fn.empty() )

return false;

ncategories= fn[CC_MAX_CAT_COUNT];

int subsetSize = (ncategories+ 31)/32,

nodeStep = 3 + ( ncategories>0 ? subsetSize: 1 );

至此分类器参数读取完毕。

接下来是建立分类树,也就是stage部分的载入。

// load stages

fn = root[CC_STAGES];

if( fn.empty() )

return false;

stages.reserve(fn.size());//stages包含15个节点,fn.size()==15

classifiers.clear();

nodes.clear();

FileNodeIteratorit =fn.begin(),it_end=fn.end();

for( int si = 0; it != it_end; si++, ++it )//遍历stages

{

FileNodefns = *it;

Stagestage;//stage结构中包含threshold、ntrees和first三个变量

stage.threshold = (float)fns[CC_STAGE_THRESHOLD]-THRESHOLD_EPS;

fns= fns[CC_WEAK_CLASSIFIERS];

if(fns.empty())

returnfalse;

stage.ntrees = (int)fns.size();

stage.first = (int)classifiers.size();//ntrees和first指出该stage中包含的树的数目和起始位置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/733767
推荐阅读
  

闽ICP备14008679号