Opencv249源码分析Cascade Classification二.docx
- 文档编号:28844977
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:55
- 大小:38.19KB
Opencv249源码分析Cascade Classification二.docx
《Opencv249源码分析Cascade Classification二.docx》由会员分享,可在线阅读,更多相关《Opencv249源码分析Cascade Classification二.docx(55页珍藏版)》请在冰豆网上搜索。
Opencv249源码分析CascadeClassification二
Opencv2.4.9源码分析——CascadeClassification
(二)
训练级联分类器的源码在OpenCV/sources/app/traincascade目录下。
首先我们给出级联分类器的特征类型的相关类和函数。
CvHaarFeatureParams、CvLBPFeatureParams和CvHOGFeatureParams分别表示HAAR状特征、LBP特征和HOG特征的参数类,它们都继承于CvFeatureParams:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
classCvFeatureParams:
publicCvParams
{
public:
//级联分类器能够使用三种特征类型用于训练样本:
HAAR、LBP和HOG
enum{HAAR=0,LBP=1,HOG=2};
//缺省构造函数,赋值maxCatCount为0,featSize为1
CvFeatureParams();
//初始化maxCatCount和featSize
virtualvoidinit(constCvFeatureParams&fp);
//表示向params.xml文件写入一些信息:
maxCatCount和featSize的值
virtualvoidwrite(cv:
:
FileStorage&fs)const;
//表示从params.xml文件内读取一些信息:
maxCatCount和featSize的值
virtualboolread(constcv:
:
FileNode&node);
//构建相应的特征参数,即级联分类器具体使用哪种特征,如果输入参数featureType=0,则应用HAAR,该函数返回CvHaarFeatureParams的指针;如果featureType=1,则应用LBP,该函数返回CvLBPFeatureParams的指针;如果featureType=2,则应用HOG,该函数返回CvHOGFeatureParams的指针。
staticcv:
:
Ptr
//表示样本特征的类别数,如果该值为0,则表示特征是数值的形式,对于HAAR和HOG,该值为0,对于LBP,该值被赋值为256
intmaxCatCount;//0incaseofnumericalfeatures
//表示一个特征所包含的特征成分的数量,HAAR和LBP为1,HOG为36,即HOG特征包含36(9×4)个特征成分
intfeatSize;//1incaseofsimplefeatures(HAAR,LBP)andN_BINS(9)*N_CELLS(4)incaseofDalal'sHOGfeatures
};
CvHaarEvaluator、CvLBPEvaluator和CvHOGEvaluator分别表示HAAR状特征、LBP特征和HOG特征的计算评估特征值的类,它们都继承于CvFeatureEvaluator类:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
classCvFeatureEvaluator
{
public:
virtual~CvFeatureEvaluator(){}//析构函数
//初始化一些变量:
featureParams、winSize、numFeatures、cls,另外还调用了generateFeatures函数,而CvFeatureEvaluator类的子类的init函数主要完成各自特征的初始化参数的任务
virtualvoidinit(constCvFeatureParams*_featureParams,
int_maxSampleCount,cv:
:
Size_winSize);
//确保样本图像img的尺寸正确,并且设置该图像的类别标签clsLabel,而CvFeatureEvaluator类的子类的setImage函数主要完成积分图像或梯度方向直方图的计算
virtualvoidsetImage(constcv:
:
Mat&img,ucharclsLabel,intidx);
//表示向xml文件写入一些内容
virtualvoidwriteFeatures(cv:
:
FileStorage&fs,constcv:
:
Mat&featureMap)const=0;
//重载()运算符,CvFeatureEvaluator类的子类CvHaarEvaluator和CvHOGEvaluator完成了第sampleIdx个样本图像的第featureIdx个特征的特征值的计算,而CvHOGEvaluator完成的是第sampleIdx个样本图像的第featureIdx个特征成分的方向直方图的计算
virtualfloatoperator()(intfeatureIdx,intsampleIdx)const=0;
//构建相应特征的特征值计算,即级联分类器具体使用哪种特征,如果输入参数type=0,则应用HAAR,该函数返回CvHaarEvaluator的指针;如果type=1,则应用LBP,该函数返回CvLBPEvaluator的指针;如果type=2,则应用HOG,该函数返回CvHOGEvaluator的指针。
staticcv:
:
Ptr
//得到numFeatures值
intgetNumFeatures()const{returnnumFeatures;}
//得到CvFeatureParams:
:
maxCatCount值
intgetMaxCatCount()const{returnfeatureParams->maxCatCount;}
//得到CvFeatureParams:
:
featSize值
intgetFeatureSize()const{returnfeatureParams->featSize;}
//得到cls值
constcv:
:
Mat&getCls()const{returncls;}
//得到矩阵cls中的第si个元素的值,即得到第si个样本的类别标签
floatgetCls(intsi)const{returncls.at
protected:
//虚函数,执行子类的generateFeatures函数,产生HAAR、LBP或HOG的各自特征
virtualvoidgenerateFeatures()=0;
intnpos,nneg;//分别表示正、负样本的数量
intnumFeatures;//表示特征数量
//表示正样本图像的尺寸大小,负样本图像的尺寸是根据正样本图像的尺寸进行剪切
cv:
:
SizewinSize;
CvFeatureParams*featureParams;//特征变量
cv:
:
Matcls;//表示样本的类别标签,即样本的响应值
};
在HAAR、LBP和HOG这三种特征的参数类和评估类中,最重要的是评估类中的setImage函数、generateFeatures函数和重载()运算符,它们的作用分别是计算积分图像或梯度方向直方图、产生特征,以及计算特征值。
下面我们就分别给出这三种特征的相关函数的解释。
HAAR状特征:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidCvHaarEvaluator:
:
setImage(constMat&img,ucharclsLabel,intidx)
//img表示待处理的样本图像
//clsLabel表示img图像的类别标签,即img图像是正样本还是负样本
//idx表示img在所有样本图像的索引值
{
//sum和tilted分别表示所有样本图像的积分图像和旋转积分图像,normfactor表示特征值的归一化因子,这三个变量在init函数中定义,这里再次确认这三个变量是否定义好
CV_DbgAssert(!
sum.empty()&&!
tilted.empty()&&!
normfactor.empty());
//调用父类的setImage函数,确定图像img尺寸大小是否正确,并赋值类别标签
CvFeatureEvaluator:
:
setImage(img,clsLabel,idx);
//sum和titled包含的单一图像的积分图像和旋转积分图像都是以相量的形式存储的,在这里都需转换为矩阵的形式,以便于积分图像的计算
MatinnSum(winSize.height+1,winSize.width+1,sum.type(),sum.ptr
MatinnTilted(winSize.height+1,winSize.width+1,tilted.type(),tilted.ptr
MatinnSqSum;
//计算图像img的灰度积分图像innSum,灰度平方的积分图像innSqSum,旋转的积分图像innTilted
integral(img,innSum,innSqSum,innTilted);
//得到特征值的归一化因子,一个样本图像只有一个归一化因子
normfactor.ptr
}
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
voidCvHaarEvaluator:
:
generateFeatures()
{
//得到HAAR状特征的模式,即HAAR状特征模板是BASIC、CORE还是ALL,该值由用户定义。
BASIC为图1中的(a)、(b)、(e)、(i)和(n),CORE为BASIC模式再加上图1中的(f)、(j)和(m),ALL为图1中的全部模板
intmode=((constCvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
//偏移量,就是积分图像的宽(在程序中,积分图像的宽和高都要比原图像的宽和高多1),用于计算图像中的某一点的像素从图像左上角开始扫描的位置,如坐标(x,y)在图像的位置是x+y×offset,这是因为积分图像是以相量的形式存储的,必须通过这种形式才能从相量中提取出积分图像中某一像素的积分值
intoffset=winSize.width+1;
//遍历样本图像的所有像素
//x和y表示HAAR状特征模板在样本图像中左上角的坐标
for(intx=0;x { for(inty=0;y { //得到以(x,y)为左上角坐标的所有不同大小、不同类型的HAAR状特征模板 for(intdx=1;dx<=winSize.width;dx++) { for(intdy=1;dy<=winSize.height;dy++) { //haar_x2 //图1(a) //判断HAAR状特征矩形模板是否超出了样本图像的边界 if((x+dx*2<=winSize.width)&&(y+dy<=winSize.height)) { //得到一个HAAR状特征模板,把它放入表示特征模板变量的features向量队列中,Feature是CvHaarEvaluator类中的一个类,该类在后面有详细介绍 features.push_back(Feature(offset,false, x,y,dx*2,dy,-1, x+dx,y,dx,dy,+2)); } //haar_y2 //图1(b) if((x+dx<=winSize.width)&&(y+dy*2<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx,dy*2,-1, x,y+dy,dx,dy,+2)); } //haar_x3 //图1(e) if((x+dx*3<=winSize.width)&&(y+dy<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx*3,dy,-1, x+dx,y,dx,dy,+3)); } //haar_y3 //图1(i) if((x+dx<=winSize.width)&&(y+dy*3<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx,dy*3,-1, x,y+dy,dx,dy,+3)); } if(mode! =CvHaarFeatureParams: : BASIC) { //haar_x4 //图1(f) if((x+dx*4<=winSize.width)&&(y+dy<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx*4,dy,-1, x+dx,y,dx*2,dy,+2)); } //haar_y4 //图1(j) if((x+dx<=winSize.width)&&(y+dy*4<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx,dy*4,-1, x,y+dy,dx,dy*2,+2)); } } //x2_y2 //图1(n) if((x+dx*2<=winSize.width)&&(y+dy*2<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx*2,dy*2,-1, x,y,dx,dy,+2, x+dx,y+dy,dx,dy,+2)); } if(mode! =CvHaarFeatureParams: : BASIC) { //图1(m) if((x+dx*3<=winSize.width)&&(y+dy*3<=winSize.height)) { features.push_back(Feature(offset,false, x,y,dx*3,dy*3,-1, x+dx,y+dy,dx,dy,+9)); } } if(mode==CvHaarFeatureParams: : ALL) { //tiltedhaar_x2 //图1(c) if((x+2*dx<=winSize.width)&&(y+2*dx+dy<=winSize.height)&&(x-dy>=0)) { features.push_back(Feature(offset,true, x,y,dx*2,dy,-1, x,y,dx,dy,+2)); } //tiltedhaar_y2 //图1(d) if((x+dx<=winSize.width)&&(y+dx+2*dy<=winSize.height)&&(x-2*dy>=0)) { features.push_back(Feature(offset,true, x,y,dx,2*dy,-1, x,y,dx,dy,+2)); } //tiltedhaar_x3 //图1(g) if((x+3*dx<=winSize.width)&&(y+3*dx+dy<=winSize.height)&&(x-dy>=0)) { features.push_back(Feature(offset,true, x,y,dx*3,dy,-1, x+dx,y+dx,dx,dy,+3)); } //tiltedhaar_y3 //图1(k) if((x+dx<=winSize.width)&&(y+dx+3*dy<=winSize.height)&&(x-3*dy>=0)) { features.push_back(Feature(offset,true, x,y,dx,3*dy,-1, x-dy,y+dy,dx,dy,+3)); } //tiltedhaar_x4 //图1(h) if((x+4*dx<=winSize.width)&&(y+4*dx+dy<=winSize.height)&&(x-dy>=0)) { features.push_back(Feature(offset,true, x,y,dx*4,dy,-1, x+dx,y+dx,dx*2,dy,+2)); } //tiltedhaar_y4 //图1(l) if((x+dx<=winSize.width)&&(y+dx+4*dy<=winSize.height)&&(x-4*dy>=0)) { features.push_back(Feature(offset,true, x,y,dx,4*dy,-1, x-dy,y+dy,dx,2*dy,+2)); } } } } } } numFeatures=(int)features.size();//得到HAAR状特征的数量 } 得到一个HAAR状特征矩形模板: [cpp]viewplaincopy在CODE上查看代码片派生到我的代码片 CvHaarEvaluator: : Feature: : Feature(intoffset,bool_tilted, intx0,inty0,intw0,inth0,floatwt0, intx1,inty1,intw1,inth1,floatwt1, intx2,inty2,intw2,inth2,floatwt2) //offset表示偏移量,即积分图像的宽 //_tilted表示是否倾斜 //x0、y0、w0、h0和wt0,x1、y1、w1、h1和wt1以及x2、y2、w2、h2和wt2分别表示HAAR状特征模板内三个不同矩形的左上角坐标、宽、高和它的权重,HAAR状特征模板最多包含3个矩形,其中x2、y2、w2、h2和wt2这5个参数缺省为0,用于表示此时的HAAR状特征模板内只有2个矩形 { tilted=_tilted;//赋值,表示该模板是否倾斜 //给HAAR状特征模板内的三个矩形左上角坐标、宽、高和权重赋值 rect[0].r.x=x0; rect[0].r.y=y0; rect[0].r.width=w0; rect[0].r.height=h0; rect[0].weight=wt0; rect[1].r.x=x1; rect[1].r.y=y1; rect[1].r.width=w1; rect[1].r.height=h1; rect[1].weight=wt1; rect[2].r.x=x2; rect[2].r.y=y2; rect[2].r.width=w2; rect[2].r.height=h2; rect[2].weight=wt2; if(! tilted)//模板不倾斜 { //CV_HAAR_FEATURE_MAX等于3,表示HAAR状特征模板内矩形的最多数量 for(intj=0;j { if(rect[j].weight==0.0F)//权值为0表示没有该矩形 break; //CV_SUM_OFFSETS为宏定义,作用是把模板内的矩形rect的4个顶点坐标转换为以图像左上角为起点开始扫描的位置(如坐标(x,y)在图像的位置是x+y×offset),并把它们赋值到fastRect结构内 CV_SUM_OFFSETS(fastRect[j].p0,fastRect[j].p1,fastRect[j].p2,fastRect[j].p3,rect[j].r,offset) } } else//模板倾斜45度 { for(intj=0;j { if(rect[j].weight==0.0F) break; //CV_TILTED_OFFSETS为宏定义,作用是把模板内的倾斜矩形rect的4个顶点坐标转换为以图
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Opencv249源码分析Cascade Classification二 Opencv249 源码 分析 Cascade Classification