OPENCV ADABOOST人脸检测训练程序阅读笔记(LBP特征)
人脸检测学习笔记(数据集-DLIB人脸检测原理-DLIBOpenCV人脸检测方法及对比)
⼈脸检测学习笔记(数据集-DLIB⼈脸检测原理-DLIBOpenCV⼈脸检测⽅法及对⽐)1.Easily Create High Quality Object Detectors with Deep Learning2016/10/11dlib中的MMOD实现使⽤HOG特征提取,然后使⽤单个线性过滤器。
这意味着它⽆法学习检测出具有复杂姿势变化的物体。
HOG:⽅向梯度直⽅图(Histogram of oriented gradient)是在计算机视觉和图像处理领域⽤于⽬标检测的特征描述器。
⼈脸检测基准FDDB有两种模式:10倍交叉验证和不受限制。
两者都在同⼀数据集上进⾏测试,但在10倍交叉验证模式下,您只能对FDDB 数据集中的数据进⾏训练。
在⽆限制模式下,您可以训练您喜欢的任何数据,只要它不包含来⾃FDDB的图像。
FDDB站点:⼈脸数据集:FDDB、ImageNet、AFLW、Pascal VOC、VGG、WIDER 、Ibug(https:///resources/facial-point-annotations/)、facescrub()等。
2.dlib-models(1)mmod_human_face_detector是在这个数据集上训练的:http:///files/data/dlib_face_detection_dataset-2016-09-30.tar.gz。
作者通过在许多公开可⽤的图像数据集(不包括FDDB数据集)中查找⼈脸图像来创建数据集。
特别是,有来⾃ImageNet,AFLW,Pascal VOC,VGG数据集,WIDER和facescrub的图像。
数据集中的所有注释都是由作者使⽤dlib的imglab⼯具创建的。
mmod_human_face_detector 包含两种模式。
不能⼈脸识别。
(2)shape_predictor_68_face_landmarks.dat.bz2这是在ibug 300-W数据集上训练的()。
openCV的图像处理计算机视觉学习笔记-人脸检测
In [1]:from imutils import*In [2]:image = imread('face.png')show(image)1. image:输入图像2. scaleFactor=1.1:这个是每次缩小图像的比例,默认是1.13. minNeighbors=3:匹配成功所需要的周围矩形框的数目,每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3。
4. minSize:匹配人脸的最小范围5. flags=0:可以取如下这些值:CASCADE_DO_CANNY_PRUNING=1, 利用canny边缘检测来排除一些边缘很少或者很多的图像区域CASCADE_SCALE_IMAGE=2, 正常比例检测CASCADE_FIND_BIGGEST_OBJECT=4, 只检测最大的物体CASCADE_DO_ROUGH_SEARCH=8 初略的检测In [3]:# 级联分类器detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10, 10), flags=cv for (x,y,w,h) in rects:# 画矩形框cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)show(image)In [4]:def facedetect(image):image = imread(image)# 级联分类器detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=2, minSize=(10, 10), flag for (x,y,w,h) in rects:# 画矩形框cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)show(image)In [5]:facedetect('Solvay.jpg')In [ ]:。
OpenCV学习笔记人脸检测的代码分析
OpenCV学习笔记人脸检测的代码分析一、预备知识:1、动态内存存储及操作函数CvMemStoragetypedef struct CvMemStorage{struct CvMemBlock* bottom;/* first allocated block */struct CvMemBlock* top; /* the current memory block - top of the stack */struct CvMemStorage* parent; /* borrows new blocks from */int block_size; /* block size */int free_space; /* free space in the top block (in bytes) */} CvMemStorage;内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等动态增长数据结构的底层结构。
它是由一系列以同等大小的内存块构成,呈列表型---bottom 域指的是列首,top 域指的是当前指向的块但未必是列尾.在bottom和top之间所有的块(包括bottom, 不包括top)被完全占据了空间;在top和列尾之间所有的块(包括块尾,不包括top)则是空的;而top 块本身则被占据了部分空间-- free_space 指的是top块剩余的空字节数。
新分配的内存缓冲区(或显示的通过cvMemStorageAlloc 函数分配,或隐示的通过cvSeqPush, cvGraphAddEdge等高级函数分配)总是起始于当前块(即top块)的剩余那部分,如果剩余那部分能满足要求(够分配的大小)。
分配后,free_space 就减少了新分配的那部分内存大小,外加一些用来保存适当列型的附加大小。
当top块的剩余空间无法满足被分配的块(缓冲区)大小时,top块的下一个存储块被置为当前块(新的top块)-- free_space 被置为先前分配的整个块的大小。
LBP特征ADABOOST分类器
本章首先介绍了特征级融合的现状。基于特征级融合的流程一般基于图像识别的预分 割、特征提取、分类器三层次框架,随后本文从特征提取和分类器两方面进行了介绍。随后 基于SAR图像特点,重点介绍了本文针对SAR图像特点采用的基于Meanshift初分割;马尔 可夫随机场特征和LBP特征,以及AdaBoost分类器的特征级融合方案。
∑ (a) 归一化权重ωt,i ←
ωt ,i ωn
j t,j
h(x)
=
⎧⎪1 ⎨ ⎪⎩0
∑ ∑ α h T t=1 t t
(x)
≥
1 2
α T
t=1 t
otherwise
(b) 对每一个特征 j 训练一个分类器 hj ,hj 由一个特征产生。误差与ωt 有关,
∑ 为 ε j = iωi hj (xi ) − yi
种关系。
目前基于特征融合的算法还比较分散,没有形成较为统一的理论框架。其中
Datcu及其研究小组的工作较为引人注明[48][49][50][51][52]。他们基于特征学
47F
48F
49F
50FLeabharlann 51F习和聚类研究,提出了基于多源遥感图像融合的数据挖掘研究框架。该框架基于
马尔可夫场理论对各类图像进行特征提取工作,随后基于K均值等算法,在特征
在此近似的条件下,MPL 参数估计就是使得伪似然概率 p({xs}) 最大或对数 伪似然概率 log p({xs}) 最大的 θ 值,即:
91
θ
=
arg
max θ
log
pθ
({xs})
(4.8)
定义2. GMRF参数估计: 用局部概率的乘积代替联合概率分布,得到伪似 然方程:
LBP算法(人脸识别特征提取)
LBP算法(人脸识别特征提取)LBP(Local Binary Patterns)算法是一种用于人脸识别中的特征提取算法。
该算法能够有效地描述图像局部纹理特征,通过将图像划分为不同的区域,并计算每个区域的局部二值模式(Local Binary Pattern),从而提取出图像的纹理特征。
本文将介绍LBP算法的原理、应用以及算法的优缺点。
LBP算法的原理是基于图像局部纹理的分布统计。
算法首先将图像划分为若干个重叠的圆形区域,然后选取每个区域的中心像素点作为参考点,根据参考点和周围像素的灰度值大小关系,将周围像素的灰度值二值化。
具体而言,如果周围像素的灰度值大于或等于参考点的灰度值,则将其对应位置的二值设置为1,否则设置为0。
这样,就得到了一个局部二值模式。
对于每个局部二值模式,在其周围像素形成的二进制数中,可以计算出一个十进制的值,该值即为对应的LBP值。
然后,可以统计整个图像中不同LBP值的出现次数,以得到该图像的纹理特征向量。
为了保持LBP特征的旋转不变性,通常将计算得到的纹理特征向量进行旋转不变模式(Rotation-Invariant Patterns)的处理。
LBP算法在人脸识别中的应用非常广泛。
通过提取图像的纹理特征,LBP算法能够有效地区分人脸图像中不同的区域,从而实现人脸检测、人脸识别等任务。
与其他特征提取算法相比,LBP算法具有计算简单、计算效率高以及对光照变化、表情变化等具有较强的鲁棒性的优点。
然而,LBP算法也存在一些缺点。
首先,LBP算法提取的特征主要反映了图像的纹理信息,对于人脸的形状、结构等特征没有很好的表达能力。
其次,LBP算法对于像素点近邻选择的问题较为敏感,不同的近邻选择可能会导致特征的差异。
最后,LBP算法没有考虑像素点的空间关系,在一些图像中可能导致特征提取不准确。
为了克服这些缺点,研究人员对LBP算法进行了改进和扩展,提出了许多改进的LBP算法。
例如,Extended LBP(ELBP)算法结合了LBP算法和傅里叶描述子,融合了纹理和形状信息;Uniform LBP(ULBP)算法通过将LBP值分为不同的均匀模式,增强了特征的区分能力和鲁棒性;Multi-scale LBP(MLBP)算法在不同尺度下提取LBP特征,增强了特征的描述能力。
基于OpenCV人脸检测技术的研究及实现
基于OpenCV人脸检测技术的研究及实现作者:王洋郑佳春来源:《物联网技术》2018年第03期摘要:为了在视频流中准确检测到人脸,文中基于OpenCV设计了一个人脸检测系统。
使用Haar和LBP两种算子提取特征,通过AdaBoost算法构造级联分类器,检测出人脸区域。
通过计算机仿真验证,发现采用LBP算子提取特征的正面检测率更高,达90%以上,且检测时间更短,平均检测时间降低1个数量级,取得了较好的效果。
该模块可移植性强,可扩展,为后续研究打下了良好的基础。
关键词:视频流;特征提取;局部二值模式;人脸检测中图分类号:TP39:U644.8 文献标识码:A 文章编号:2095-1302(2018)03-0081-03O引言随着计算机技术和数字成像技术的进步,机器视觉技术蓬勃发展。
人脸识别—直是计算机视觉和人工智能中的重要问题。
人脸识别技术因无需与用户进行肢体接触,使用简单、安全,经过几十年的研究和发展,已成为一项热门的研究课题,受到越来越多研究者的重视。
该技术可广泛应用于公共场所人口统计及视频监控,安全驾驶提醒,门禁管理系统等相关领域。
因此找到一个高效明了的算子提取特征描述人脸和分类器至关重要。
研究者为此提出了主成分分析法(PCA)、线性判别式分析(LDA)等全局描述方法和Haar特征与LBP特征等局部描述的特征等。
局部特征在不同的光照及姿态和复杂环境下,具有较强的鲁棒性,得到了广泛应用。
本文利用Visual Studio 2013和开源计算机视觉平台OpenCV搭建了一个人脸识别模块,利用Haar和LBP两种算子提取特征,进行视频流的人脸识别。
该模块搭建方便,可移植性强,在Windows,Android和iOS系统上均可实现。
1人脸识别模块1.1 Haar特征Haar特征是以图像灰度分布为基础并反映图像灰度值变化的一种特征,主要是由黑白矩阵像素组合而成的不同模板,包含边缘特征、线性特征、中心环绕特征。
opencv adaboost人脸检测训练程序阅读笔记(LBP特征)
1、训练程序整体流程(1)读输入参数并打印相关信息(2)进入训练程序最外层入口classifier.train1)读正负样本,将正负样本放入imgLiast中,先读正样本,后读负样本2)load( dirName )判断之前是否有已训练好的xml文件,若有,不在重新训练该stage的xml文件,没有返回false,初始化参数3)计算requiredLeafFARate = pow(maxFalseAlarm,numStages)/max_depth,该参数是stage停止条件(利用训练样本集来计算tempLeafFARate,若tempLeafFARate小于这一参数,则退出stage训练循环);4)Stage训练循环5)更新训练样本集,计算tempLeafFARate(负样本被预测为正样本的个数除以读取负样本的次数,第一次没有训练之前,这个比值为1,因为没训练之前,所有负样本都被预测成了正样本,当第一层训练好以后,负样本采集时会先用第一层的分类器预测一次,若能分类,则不选用,选用负样本的数目是固定的,但选用这么多负样本总共要选的次数会随着层数的增多而加大,因为层数越大,分类器的分类能力也要求越大,说需要的样本就是前面分类器所不恩呢该识别的,故在采集时也比较困难。
)6)判断stage是否退出训练,若tempLeafFARate<requiredLeafFARate则退出stage训练,否则继续;7)强训练器训练入口tempStage->train()a.建立训练数据data = new CvCascadeBoostTrainData(主要是一些参数的设置,还有特征值的计算)b.初始化样本权重update_weights( 0 );c.弱分类器训练循环i)tree->train—》do_trainai) 根节点的初始root = data->subsample_data( _subsample_idx );(主要是对根节点的一些参数进行初始化,parent 0,count 1,split 0,value 0,class_idx 0,maxlr 0,left = right = 0,等等)bi) CV_CALL( try_split_node(root)),根据根节点计算整颗数的各节点的参数配置aii) calc_node_value( node );计算节点的回归值,类似于分类投票值sum(w*class_lable),正样本的class_lable取,负样本的class_lable取-1;计算节点的风险值node_risk,noderisk is the sum of squared errors: sum_i((Y_i -<node_value>)^2)bii) 判断节点是否可以分裂(判断依据:样本值和设计的节点最大深度);再利用node_risk与regression_accuracy,如果这个节点的所有训练样本的节点估计值的绝对差小于这个参数,节点不再进行分裂cii) 找出最佳分裂best_split = find_best_split(node);aiii) 定义DTreeBestSplitFinder finder( this, node );biii) parallel_reduce(cv::BlockedRange(0, data->var_count), finder);此时调用DTreeBestSplitFinder类的操作符DTreeBestSplitFinder::operator()(constBlockedRange& range)aiv) 遍历所有特征vi = vi1; vi< vi2; vi++biv) res = tree->find_split_cat_reg()得到特征为split->var_idx = vi的最佳分裂的质量split->quality(split->quality越大越好)av) 将特征为vi所有样本的特征值返回到cat_labelsbv) 计算每个特征值取值不权值和和响应和,例如特征值为,则将所有特征值列表中特征值为的样本权值相加,LBP的特征值范围是0~255,故有256个categorycv) 计算每个category的平均响应值,即将每个category的响应和除以每个category的样本权值和dv) icvSortDblPtr( sum_ptr, mi, 0 );把256个值进行升序排序,注意sum_ptr里存的是sum[i]的地址,这里排序的依据是特征值还是按照每个特征值的平均响应来排序???个人感觉是按特征值的平均响应来排序fv) 将每个特征值的平均响应值乘以该特征值的总权值得到每个特征值的总响应gv) 遍历subset_i = 0; subset_i< mi-1; subset_i++avi) 计算索引是subset_i在排序前的idxbvi) 获取索引idx对应的样本总权重cvi) 获取索引idx对应的样本总响应dvi) 以subset_i为分裂点,计算分裂质量(sumL*sumL)/ weightL +(sumR*sumR)/ weightRfvi) 若最佳分裂质量小于这个质量,则更新最佳分裂质量hv) 经过训练得到最佳分裂点和最佳分裂质量,将遍历得到的值更新到split结构体各参数。
一种改进的LBP特征的人脸识别方法
表4 改进后的音频生命探测仪滤波范围设置
高频滤波器音频设定范围
1000Hz—1300Hz
低频滤波器音频设定范围
15Hz—850Hz
图3.1是用凯塞窗函数设计的FIR数字带通滤波器,通带
范围为1000Hz到1300Hz,阻带范围为15Hz到850Hz、1500Hz到
4500Hz,阻带波纹为0.01dB,通带波纹为0.05dB,信号采样频率
由于本文处理的图片是事先归一化好的,所以略去了人脸 检测和人眼定位这两部分,最后,本文利用matlab语言开发了一 个简单的识别系统,程序界面如图3:
这样,由20种不同大小的区域产生的特征总数为7141个。 相比传统的图像块划分的方法产生的几十个特征,这几千个特 征能够很详尽地、充分地对人脸的纹理信息进行描述。利用 AdaBoost算法根据阈值挑选出错误率最小的弱分类器(即特 征)。本文中弱分类器的定义如下:
2 LBP人脸特征的提取
通常在进行LBP特征提取前,需要对人脸图片进行大小归一 化,以保证利用LBP得到的直方图有相同的数量的LBP值。一般 都是利用两眼的坐标对图像进行归一化,使所比较的图片的大 小一致,并消除旋转,本文中归一化后图片的大小为120×110。
3 样本和特征的构造和挑选
对于120×110大小的图片由第1种矩形块生成的特征个数 是:
为19980Hz。
根据图3.2我们可以看出这种改进了滤波范围的窗函数法
能在很低的输入信噪比条件下,取得很好的去噪效果。这就说
明运用这种方法能有效地从地震现场的人声污染中找到所需
要的小孩的呼救声信号。
图3.1改进后的Kaiser窗
图3.2(b)输入信噪比SNR=-10时的改进滤波
4 结语
基于MB-LBP特征和JIH的Adaboost人脸检测算法
基于MB-LBP特征和JIH的Adaboost人脸检测算法
付心浩;谢勤岚
【期刊名称】《计算机与数字工程》
【年(卷),期】2016(44)5
【摘要】针对纯粹引入Haar-like特征的人脸检测算法误检率高且受光照条件影响较大的问题,在保证实时性基本不受影响的前提下,以提高检测精度及增强对光照的鲁棒性为目的,提出了基于Adaboost算法结合MB-LBP算子和联合积分直方图(JIH)及Haar模板进行人脸特征提取的新方法.测试结果验证了新方法训练的分类器比单纯使用Haar特征或MB-LBP效果好,证明了提出的方法的有效性.
【总页数】4页(P944-947)
【作者】付心浩;谢勤岚
【作者单位】中南民族大学生物医学工程学院武汉 430074;中南民族大学生物医学工程学院武汉 430074
【正文语种】中文
【中图分类】TP391
【相关文献】
1.基于人脸特征和AdaBoost算法的多姿态人脸检测 [J], 阮锦新;尹俊勋
2.Hadoop云平台下基于HOG特征和Adaboost分类器的快速行人检测算法 [J], 黄金国;刘涛;周先春
3.基于人脸特征和Adaboost算法的人脸定位 [J], 黄葛峰;吴忠;吴建国
4.基于Haar-NMF特征和级联AdaBoost的脱岗检测算法 [J], 魏京天;王军;王玉
楠;薄煜明
5.基于新增haar特征和改进AdaBoost的人脸检测算法 [J], 张彩丽; 刘广文; 詹旭; 才华; 刘智
因版权原因,仅展示原文概要,查看原文内容请购买。
基于LBP特征和AdaBoost的行人检测方法
基于LBP特征和AdaBoost的行人检测方法王德才;秦亮曦【摘要】行人检测在智能汽车、监控系统和高级机器人等领域有广泛的应用.针对低分辨率和需要实时处理的行人检测应用场景,提出了采用一致化LBP直方图特征结合Ad-aBoost分类器的高效行人检测方法.在AdaBoost的训练过程中,采用了CART(Classification And Regression Tree)作为弱分类器,并结合基于Gini不纯度的剪枝方法,有效地提高了训练速度和分类器的性能.针对Caltech行人检测数据集的实验结果表明,基于LBP特征和CART弱分类器的AdaBoost分类行人检测方法具有较好的性能.【期刊名称】《河北软件职业技术学院学报》【年(卷),期】2016(018)003【总页数】5页(P51-54,77)【关键词】行人检测;局部二值模式;AdaBoost方法;分类回归树【作者】王德才;秦亮曦【作者单位】广西大学计算机与电子信息学院计算机系,南宁 530004;广西大学计算机与电子信息学院计算机系,南宁 530004【正文语种】中文【中图分类】TP391.41行人检测[1](Pedestrian Detection)技术是计算机视觉学科中快速发展的一个领域,其研究成果在智能汽车、监控系统和高级机器人应用等方面起着十分重要的作用。
行人检测的研究来源于各类应用的真实需求,有很强的应用背景和市场价值,比如在汽车辅助驾驶系统和视频场景监控等领域,行人检测已经开始广泛应用。
行人检测的研究成果最终要为应用服务,传统的行人检测平台如车载辅助驾驶系统往往采用复杂和昂贵的采集设备来获取较高质量的视频或图像输入,并且使用专用计算设备来提高处理速度。
而近年来计算机硬件能力的快速提高使得嵌入式设备以及移动智能设备已经基本具备实时行人检测的能力,为行人检测系统的小型化和快速普及带来了机遇。
本文基于这一考虑,针对低分辨率和实时处理的应用场景,提出了采用一致化LBP直方图特征结合AdaBoost分类器的高效行人检测方法。
如何用OpenCV自带的adaboost程序训练并检测目标
如何⽤OpenCV⾃带的adaboost程序训练并检测⽬标 OpenCV⾃带的adaboost程序能够根据⽤户输⼊的正样本集与负样本集训练分类器,常⽤于⼈脸检测,⾏⼈检测等。
它的默认特征采⽤了Haar,不⽀持其它特征。
Adaboost的原理简述:()每个Haar特征对应看⼀个弱分类器,但并不是任伺⼀个Haar特征都能较好的描述⼈脸灰度分布的某⼀特点,如何从⼤量的Haar特征中挑选出最优的Haar特征并制作成分类器⽤于⼈脸检测,这是AdaBoost算法训练过程所要解决的关键问题。
Paul Viola和Michael Jones于2001年将Adaboost算法应⽤于⼈脸检测中,其基本思想是针对不同的训练集训练同⼀个分类器(弱分类器),然后把这些不同训练集上的得到的分类器联合起来,构成⼀个最终的强分类器。
Adaboost 算法中不同的训练集是通过调整每个样本对应的权重来实现的。
开始时,每个样本对应的权重是相同的,对于h1 分类错误的样本,加⼤其对应的权重;⽽对于分类正确的样本,降低其权重,这样分错的样本就被突出出来,从⽽得到⼀个新的样本分布 U2 。
在新的样本分布下,再次对弱分类器进⾏训练,得到弱分类器h2 。
依次类推,经过 T 次循环,得到 T 个弱分类器,把这 T 个弱分类器按⼀定的权重叠加(boost)起来,得到最终想要的强分类器。
训练系统总体框架,由“ 训练部分”和 “ 补充部分”构成。
依据系统框架,本⽂的训练系统可分为以下⼏个模块:(1)以样本集为输⼊,在给定的矩形特征原型下,计算并获得矩形特征集;(2)以特征集为输⼊,根据给定的弱学习算法,确定闽值,将特征与弱分类器⼀⼀对应,获得弱分类器集;(3)以弱分类器集为输⼊,在训练检出率和误判率限制下,使⽤A d a B o o s t 算法挑选最优的弱分类器构成强分类器;(4)以强分类器集为输⼊,将其组合为级联分类器;(5)以⾮⼈脸图⽚集为输⼊,组合强分类器为临时的级联分类器,筛选并补充⾮⼈脸样本。
OpenCV人脸识别LBPH算法源码分析
OpenCV⼈脸识别LBPH算法源码分析1 背景及理论基础⼈脸识别是指将⼀个需要识别的⼈脸和⼈脸库中的某个⼈脸对应起来(类似于指纹识别),⽬的是完成识别功能,该术语需要和⼈脸检测进⾏区分,⼈脸检测是在⼀张图⽚中把⼈脸定位出来,完成的是搜寻的功能。
从OpenCV2.4开始,加⼊了新的类FaceRecognizer,该类⽤于⼈脸识别,使⽤它可以⽅便地进⾏相关识别实验。
原始的LBP算⼦定义为在3*3的窗⼝内,以窗⼝中⼼像素为阈值,将相邻的8个像素的灰度值与其进⾏⽐较,若周围像素值⼤于或等于中⼼像素值,则该像素点的位置被标记为1,否则为0。
这样,3*3邻域内的8个点经⽐较可产⽣8位⼆进制数(通常转换为⼗进制数即LBP码,共256种),即得到该窗⼝中⼼像素点的LBP值,并⽤这个值来反映该区域的纹理特征。
如下图所⽰:原始的LBP提出后,研究⼈员不断对其提出了各种改进和优化。
1.1 圆形LBP算⼦基本的 LBP算⼦的最⼤缺陷在于它只覆盖了⼀个固定半径范围内的⼩区域,这显然不能满⾜不同尺⼨和频率纹理的需要。
为了适应不同尺度的纹理特征,Ojala等对LBP算⼦进⾏了改进,将3×3邻域扩展到任意邻域,并⽤圆形邻域代替了正⽅形邻域,改进后的LBP算⼦允许在半径为R的圆形邻域内有任意多个像素点,从⽽得到了诸如半径为R的圆形区域内含有P个采样点的LBP算⼦,OpenCV中正是使⽤圆形LBP算⼦,下图⽰意了圆形LBP算⼦:1.2 旋转不变模式从LBP的定义可以看出,LBP算⼦是灰度不变的,但却不是旋转不变的,图像的旋转就会得到不同的LBP值。
Maenpaa等⼈⼜将LBP算⼦进⾏了扩展,提出了具有旋转不变性的LBP算⼦,即不断旋转圆形邻域得到⼀系列初始定义的LBP值,取其最⼩值作为该邻域的LBP值。
下图给出了求取旋转不变LBP的过程⽰意图,图中算⼦下⽅的数字表⽰该算⼦对应的LBP值,图中所⽰的8种LBP模式,经过旋转不变的处理,最终得到的具有旋转不变性的LBP值为15。
LBP算法(人脸识别特征提取)
LBP算法(人脸识别特征提取)LBP(Local Binary Patterns)算法是一种用于人脸识别的特征提取方法。
它通过计算图像中每个像素点的局部二值模式,将图像中的纹理信息转化为一个向量来表示人脸的特征。
LBP算法独特的特征提取方式使其在人脸识别领域具有广泛的应用。
LBP算法的核心概念是局部二值模式。
在图像中,对于一个中心像素点,将其周围的像素点与中心像素点进行比较,如果周围像素点的灰度值大于等于中心像素点的灰度值,则将该像素点表示为1,否则表示为0。
通过这样的比较过程,我们可以得到一个二进制数值,即该区域的局部二值模式。
LBP算法通过计算图像中每个像素点的局部二值模式,将整个图像转换为一个特征向量。
具体来说,我们可以将图像分成多个小区域,每个小区域内部都有一个中心像素点。
对于每个中心像素点,我们都可以得到一个局部二值模式,将其表示为一个二进制数值。
然后,我们可以将这些二进制数值连接起来,形成一个特征向量,用于表示整个图像。
这个特征向量反映了图像中不同区域的纹理信息,因此可以用于人脸识别。
LBP算法具有以下几个优点:首先,它是一种局部特征提取方法,能够对人脸的纹理信息进行有效提取。
其次,LBP算法计算简便,不需要复杂的数学运算。
第三,LBP算法对于光照、噪声等因素具有一定的鲁棒性,可以在不同的环境下进行人脸识别。
然而,LBP算法也存在一些不足之处。
首先,LBP算法只能提取图像的纹理信息,对于其他特征如颜色,形状等没有考虑。
其次,LBP算法对于图像中纹理变化较大的区域容易受到干扰,造成特征提取不准确。
为了解决这些问题,研究者们通过改进LBP算法的方式提出了一系列的变体算法,如旋转不变LBP(RILBP)、多尺度LBP(MLBP)等。
总结起来,LBP算法是一种用于人脸识别的特征提取方法。
它通过计算图像中每个像素点的局部二值模式,将图像中的纹理信息转化为一个向量来表示人脸的特征。
LBP算法具有计算简便、对光照噪声具有一定鲁棒性等优点,但也存在对纹理变化较大的区域容易受到干扰等不足之处。
OpenCV学习笔记(十六)
OpenCV学习笔记(十六)前言:第一种方法是人脸检测中最常用的是Haar-Adaboost算法,该算法首先在人脸检测中得到广泛运用,而后也被用于其它有关目标检测中。
adaboost 是一套机器学习的框架,根据给出的正样本和副样本训练一个用于识别正样本一类物体的模型。
这个模型的本质就是分类器,又叫做级联(cascade)分类器。
本文主要是学习使用OpenCV自带的adaboost+haar特征程序,并展示其用于人脸检测的效果,最后学习如何训练自己的分类器。
第二种方法是基于OpenCV内置的HOG+SVM算法。
这种算法我用python语言编写程序,通过读取视频中的每一帧图像来作为输入检测人脸。
一、基于Haar-Adaboost算法的代码演示OpenCV支持的目标检测的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification)。
1.#include <opencv2/opencv.hpp>2.#include <iostream>3.ing namespace cv;ing namespace std;6.7.int main( )8.{9.String cascadeFilePath = "D:\\OpenCV3.1\\opencv\\build\\etc\\haarcascades\\haarcasca de_frontalface_alt.xml"; //反斜杠’\‘表示转义字符,所以绝对路径需要如是表示10.CascadeClassifier face_cascade;11.if (!face_cascade.load(cascadeFilePath)) // 用load函数加载XML分类器文件12.{13.printf("could not load the haar data...\n");14.return -1;15.}16.Mat src_img, gray_img;17.src_img = imread("test16.jpg");18.cvtColor(src_img, gray_img, COLOR_BGR2GRAY);19.equalizeHist(gray_img, gray_img); //直方图均衡化20.imshow("原图", src_img);21.22.vector<Rect> faces; // faces是一个容器,用来接收检测到的人脸23.face_cascade.detectMultiScale(gray_img, faces, 1.1,2, 0, Size(10, 10), Size(30, 30)); //寻找人脸24.for (auto t = 0; t < faces.size(); ++t)25.{26.rectangle(src_img, faces[t], Scalar(0, 0, 255), 2, 8, 0); // 用红色矩形框出人脸27.}dWindow("检测结果",CV_WINDOW_AUTOSIZE);29.imshow("检测结果", src_img);30.31.waitKey(0);32.return 0;33.}运行程序如下:我们换张人多的照片试试:注意事项:(1)在xml文件的路径当中,我们用到了“\\”,为什么呢?且听我娓娓道来:在Unix/Linux中,路径的分隔采用正斜杠"/",比如"/home/hutaow";而在Windows中,路径分隔采用反斜杠"\",比如"C:\Windows\System"。
LBP特征ADABOOST分类器
LBP特征ADABOOST分类器LBP(Local Binary Patterns)特征是一种用于图像和人脸识别的特征描述符。
它是一种局部纹理特征,用于描述图像局部区域的纹理信息。
LBP特征能够捕捉图像的局部纹理模式,具有不变性和高效性的优点,因此广泛应用于人脸识别、图像分类和目标检测等领域。
LBP特征描述了图像中所有像素点与其相邻像素点之间的相对关系,并将这种相对关系编码成一个二进制串。
具体来说,对于每个像素点,计算与其相邻像素点的灰度差值,并将灰度差值进行二值化,得到一个二进制码。
将这些二进制码进行串联,即得到了该像素点的LBP特征。
ADABOOST(Adaptive Boosting)是一种常用的分类器学习算法。
它是基于一系列弱分类器的组合来构建一个强分类器。
ADABOOST的核心思想是通过逐步调整样本权重来重复训练分类器,每一次训练都会根据上一次分类结果调整样本权重,使得分类器对误分类样本具有更高的关注度。
LBP特征的优势在于其有效捕捉了图像纹理信息,对光照变化和噪声有一定的鲁棒性。
而ADABOOST算法则能够逐步调整样本权重,注意到误分类样本,从而提升分类器的性能。
将LBP特征与ADABOOST分类器相结合,可以进一步提高分类器对图像纹理信息的感知能力,并提高分类的准确性。
LBP特征和ADABOOST分类器的结合在实际应用中取得了良好的效果。
例如,在人脸识别领域,采用LBP特征与ADABOOST分类器能够有效地对人脸图像进行特征提取和分类,实现人脸的自动识别。
在图像分类和目标检测中,利用LBP特征与ADABOOST分类器可以识别不同类别的图像,并准确地检测出目标物体。
总之,LBP特征与ADABOOST分类器的结合能够有效地提取图像的纹理信息,并用于分类和识别任务。
这种组合在计算机视觉和模式识别领域具有广泛的应用前景,可以应用于人脸识别、图像分类、目标检测等多个领域。
通过进一步的算法改进和优化,可以进一步提高分类器的性能,并推动相关研究在实际应用中的推广和应用。
一种基于MBLBP特征的AdaBoost人脸检测算法
日8-即241。目
=口也_
Co)
gl
92
岛
岛
&
譬l
g,
鼠
邑
图1 (-)积分图像计算矩形内像素值;(b)H叫‘一like特征的计算;(c)MB—LBP:3 x3大方块。
3分类器训练
本文利用AdaBoost学习算法挑选特征并训练分类器。首先挑选最具分辨能力的特征构造弱分类器,然
后将多个弱分类器组合成强分类器。
】1 1日
xl自“g
shen‘山s啪z“‰em…㈧on
M_“B1w¨m
Pm…u…】c8
2007。
4’{月t*^.Ri,P{}*《^&&d#}镕4[^-±目*16目H#n#{‘・&¥dm(c^cIs){¥☆Ut女£’c
20∞¥
Hale Waihona Puke 作者简介涂玲,女,1985年&生,北京=业大学在读研究生。专业为信皂与通信工程。
训练,用训练得到Adaboost分类器进行人脸检测,实验表明,基于MB—LBP特征的AdaBoost算法能够
达到比较满意的检测结果并显著缩短训练时间。 关键词:人脸检测,AdaBoost,MB—LBP
A AdaBoost face detection algorithm based
on
MB—LBP features
2 P
VI。h and M
J。n%R“Ⅲ州t…bnI d—Jan m…lnd Jourml“Camper v…57(2)1
Robot
redtime。b】删^l姒m[^8thIEEE
o…¨帅d c舶…computer
V Jslon
c
v…哪2∞1
58
37-154.Z004
3…2慨.Ruk%chu.Shining
基于深度学习人脸匹配中的年龄识别总结汇报(Adaboost 、融合LBP和HOG)
Part 1
Adaboost 算法的原理
单击此处添加文本具体内容
Adaboost
• AdaBoost它的自适应在于:前一个基本分 类器分错的样本会得到加强,加权后的全 体样本再次被用来训练下一个基本分类器。 同时,在 每一轮中加入一个新的弱分类器, 直到达到某个预定的足够小的错误率或达 到预先指定的最大迭代次数。
19
融合LBP和HOG特征的人脸年龄估计 • 用典型相关性分析(CCA)对LBP和HOG得 到的特征进行融合,确定一个系数使得他们 之间的相关度最大。
20
融合LBP和HOG特征的人脸年龄估计
21
资料下载
h t t p s : / / w w w. i x u e s h u . c o m / d o c u m e n t / 8 b 3 a 4 5 8 d 7 0 6 c 9 2 1 4 3 1 8 9 4 7 a 1 8 e 7 f 9 3 8 6 . h t m l
4
Adaboost
• 1.初始化训练数据的权值分布。如果有N个 样本,则每一个训练样本最开始时都被赋 予相同的权值:1/N。
• 2.训练弱分类器。具体训练过程中,如果某 个样本点已经被准确地分类,那么在构造 下一个训练集中,它的权值就被降低;相 反,如果某个样本点没有被准确地分类, 那么它的权值就得到提高。然后,权值更 新过的样本集被用于训练下一个分类器, 整个训练过程如此迭代地进行下去。 5
对于第二个问题,AdaBoost采用加权多数表决的方法,加大分类误差率小的弱分 类器的权重,减小分类误差率大的弱分类器的权重。这个很好理解,正确率高分 得好的弱分类器在强分类器中当然应该有较大的发言权。
Python基于OpenCV库Adaboost实现人脸识别功能详解
Python基于OpenCV库Adaboost实现⼈脸识别功能详解本⽂实例讲述了Python基于OpenCV库Adaboost实现⼈脸识别功能。
分享给⼤家供⼤家参考,具体如下:以前⽤Matlab写神经⽹络的⾯部眼镜识别算法,研究算法逻辑,采集⼤量训练数据,迭代,计算各感知器的系数。
相当之⿇烦~⽽现在运⽤调⽤pythonOpenCV库Adaboost算法,⽆需知道算法逻辑,⽆需进⾏模型训练,⼈脸识别变得相当之简单了。
需要⽤到的库是opencv(open source computer vision),下载安装⽅式如下:使⽤pip install numpy语句安装numpy(如果出现错误:Microsoft Visual C++ 9.0 is required <unable to find vcvarsall.bat>,使⽤管理员⾝份安装Microsoft Visual C++ 9.0,重新启动计算机,再使⽤使⽤pip install numpy语句安装numpyopencv2.4.10下载之后解压(随便解压到哪⾥),将解压⽬录opencv⽂件夹中,build->python->2.7->x86下的⽂件cv2.pyd 复制到python2.7\Lib\site-packages 中测试是否安装成功,执⾏解压⽬录下的sources\samples\python\drawing.py或者进⼊python环境,使⽤import cv2⾸先讲讲需要⽤到的新函数:CascadeClassifier()函数,导⼊分类器cv2.CascadeClassifier('xxxxx.xml')#haarcascade_frontalface_alt.xml脸部识别⽂件#haarcascade_eye.xml眼部识别⽂件函数的参数是xml完整路径(具体看你的opencv安装在哪⾥的,在opencv\sources\data\haarcascades下⾯),xml⽂件中是封装好的算法detectMultiScale()函数,进⾏识别detectMultiScale(image,scaleFactor,minNeighbors,flags,minSize,maxSize)最终返回值为识别出的矩阵框[x, y, w, h],(x,y)左上⾓起始坐标,w宽,h⾼image:⽤于检测的图像scaleFactor:前后两次相继的扫描中,搜索窗⼝的⽐例系数.例如1.1指将搜索窗⼝依次扩⼤10%。
OPENCV的HAAR+ADABOOST(OPENCV HAARTRAINING.EXE)的训练笔记及注意点说明
Opencv的haar+adaboost(opencv_haartraining.exe)的训练笔记及注意点说明这里是用opencv的haar+adaboost来训练人头检测的,以下是训练的操作流程、注意点说明以及对一些错误的解释。
一、操作流程1、准备工作将需要用到的样本及可执行文件都放到同一个文件夹下,其中pos和neg 两个文件夹分别为正负样本的文件夹。
这样做的目的是省去可能存在的麻烦,比如在写路径的时候容易出错。
另外,还需提前采集好正负样本,这里是用自编程序进行采集,要保证样本差异性,每个人的人头样本采集2-3张即可,采集区域应包含头和肩。
(注:后来发现正样本可以有重复,数量也没有要求。
)2、归一化处理将样本重命名,目的是修改描述文件时比较方便,不重命名也不会影响训练的。
同时,对样本进行尺寸归一化,用自编程序处理,其中正样本一定要尺寸归一化。
3、正负样本描述文件生成进入正样本文件夹pos,执行dir/b>pos.data,即可生成正样本描述文件pos.data,该文件的后缀名也可以是txt,在本次开发中我们用的是.txt文件。
负样本的描述文件类似生成。
有以下几个注意点:(1)负样本说明文件不能含有目标物体;(2)负样本图像尺寸不受到限制,但是尺寸越大,训练所用的时间越长;(3)负样本图像可以是灰度图,也可以不是,笔者建议使用灰度图,这样处理起来可能更有效率;(4)负样本图像尽量不要重复,增大负样本图像的差异性,可以增加分类器的使用范围,笔者建议可以使用网上的素材库,将1000多张不含目标的图片灰度处理后用来训练,效果更佳。
4、正样本的vec文件生成执行命令如下:D:\sample\headcount\haar+adaboost_sample>opencv_createsamples.exe -vec pos.vec-info D:\sample\headcount\harr+adaboost_sample\pos\pos.txt-bg D:\sample\headcount\haar+adaboost_sample\neg\neg.txt-w20-h20-num105这个命令一定要注意将路径写全,至少要从opencv_createsamples.exe所在目录写起。
OpenCV学习笔记3找出人脸,同时比较两张图片中的人脸相似度
OpenCV学习笔记3:找出人脸,同时比较两张图片中的人脸相似度分类:OpenCV2012-11-12 18:50 5394人阅读评论(4) 收藏举报终于到了有实际应用的功能了,有2张图片,里面各有一个人脸,我的目的是比较这两个人脸的相似度,这里用到了facedetect的功能,还有图像转换,图像剪切,以及直方图的比较。
具体流程是:1。
分别用facedetect功能将两张图片中的人脸检测出来2。
将人脸部分的图片剪切出来,存到两张只有人脸的图片里。
3。
将这两张人脸图片转换成单通道的图像4。
使用直方图比较这两张单通道的人脸图像,得出相似度。
这里对图的要求还是比较高的,光线和姿势不能有差别,脸的垂直或者左右角度偏差就会影响比较,但和两张图片的大小关系不大,本人觉得较适合于证件照的对比。
下面是代码,其中haarcascade_frontalface_alt.xml是opencv里facedetect例子用的样本。
比较的是srcImage和targetImage对应的文件.还有下面是IplImage和Mat混用,纯当熟悉这两个类了。
[cpp]view plaincopy1.[cpp]view plaincopy1.[cpp]view plaincopy1.#include "opencv/cv.hpp"2.#include "opencv2/objdetect/objdetect.hpp"3.#include "opencv2/highgui/highgui.hpp"4.#include "opencv2/imgproc/imgproc.hpp"5.6.#include <iostream>7.#include <stdio.h>8.ing namespace std;ing namespace cv;11.12.String cascadeName = "D:\\OpenCV-2.4.2\\data\\haarcascades\\haarcascade_frontalface_alt.xml";13.14.IplImage* cutImage(IplImage* src, CvRect rect) {15. cvSetImageROI(src, rect);16. IplImage* dst = cvCreateImage(cvSize(rect.width, rect.height),17. src->depth,18. src->nChannels);19.20. cvCopy(src,dst,0);21. cvResetImageROI(src);22.return dst;23.}24.25.IplImage* detect( Mat& img, CascadeClassifier& cascade, double scale)26.{27.int i = 0;28.double t = 0;29. vector<Rect> faces;30. Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );31.32. cvtColor( img, gray, CV_BGR2GRAY );33. resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );34. equalizeHist( smallImg, smallImg );35.36. t = (double)cvGetTickCount();37. cascade.detectMultiScale( smallImg, faces,38. 1.3, 2, CV_HAAR_SCALE_IMAGE,39. Size(30, 30) );40. t = (double)cvGetTickCount() - t;41. printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );42.for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )43. {44. IplImage* temp = cutImage(&(IplImage(img)), cvRect(r->x, r->y, r->width, r->height));45.return temp;46. }47.48.return NULL;49.}50.//画直方图用51.int HistogramBins = 256;52.float HistogramRange1[2]={0,255};53.float *HistogramRange[1]={&HistogramRange1[0]};54.int CompareHist(IplImage* image1, IplImage* image2)55.{56. IplImage* srcImage;57. IplImage* targetImage;58.if (image1->nChannels != 1) {59. srcImage = cvCreateImage(cvSize(image1->width, image1->height), image1->depth, 1);60. cvCvtColor(image1, srcImage, CV_BGR2GRAY);61. } else {62. srcImage = image1;63. }64.65.if (image2->nChannels != 1) {66. targetImage = cvCreateImage(cvSize(image2->width, image2->height), srcImage->depth, 1);67. cvCvtColor(image2, targetImage, CV_BGR2GRAY);68. } else {69. targetImage = image2;70. }71.72. CvHistogram *Histogram1 = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY,HistogramRange);73. CvHistogram *Histogram2 = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY,HistogramRange);74.75. cvCalcHist(&srcImage, Histogram1);76. cvCalcHist(&targetImage, Histogram2);77.78. cvNormalizeHist(Histogram1, 1);79. cvNormalizeHist(Histogram2, 1);80.81.// CV_COMP_CHISQR,CV_COMP_BHATTACHARYYA这两种都可以用来做直方图的比较,值越小,说明图形越相似82. printf("CV_COMP_CHISQR : %.4f\n", cvCompareHist(Histogram1, Histogram2,CV_COMP_CHISQR));83. printf("CV_COMP_BHATTACHARYYA : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_BHATTACHARYYA));84.85.86.// CV_COMP_CORREL, CV_COMP_INTERSECT这两种直方图的比较,值越大,说明图形越相似87. printf("CV_COMP_CORREL : %.4f\n", cvCompareHist(Histogram1, Histogram2,CV_COMP_CORREL));88. printf("CV_COMP_INTERSECT : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_INTERSECT));89.90. cvReleaseHist(&Histogram1);91. cvReleaseHist(&Histogram2);92.if (image1->nChannels != 1) {93. cvReleaseImage(&srcImage);94. }95.if (image2->nChannels != 1) {96. cvReleaseImage(&targetImage);97. }98.return 0;99.}100.String srcImage = "d:\\ldh1.jpg";101.String targetImage = "d:\\ldh5.jpg";102.int main(int argc, char* argv[])103.{104. CascadeClassifier cascade;105. namedWindow("image1");106. namedWindow("image2");107.if( !cascade.load( cascadeName ) )108. {109.return -1;110. }111.112. Mat srcImg, targetImg;113. IplImage* faceImage1;114. IplImage* faceImage2;115. srcImg = imread(srcImage);116. targetImg = imread(targetImage);117. faceImage1 = detect(srcImg, cascade, 1);118.if (faceImage1 == NULL) {119.return -1;120. }121.// cvSaveImage("d:\\face.jpg", faceImage1, 0); 122. faceImage2 = detect(targetImg, cascade, 1); 123.if (faceImage2 == NULL) {124.return -1;125. }126.// cvSaveImage("d:\\face1.jpg", faceImage2, 0); 127. imshow("image1", Mat(faceImage1));128. imshow("image2", Mat(faceImage2));129.130. CompareHist(faceImage1, faceImage2);131. cvWaitKey(0);132. cvReleaseImage(&faceImage1);133. cvReleaseImage(&faceImage2);134.return 0;135.}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、训练程序整体流程(1)读输入参数并打印相关信息(2)进入训练程序最外层入口classifier.train1)读正负样本,将正负样本放入imgLiast中,先读正样本,后读负样本2)load(dirName)判断之前是否有已训练好的xml文件,若有,不在重新训练该stage的xml文件,没有返回false,初始化参数3)计算requiredLeafFARate=pow(maxFalseAlarm,numStages)/max_depth,该参数是stage停止条件(利用训练样本集来计算tempLeafFARate,若tempLeafFARate小于这一参数,则退出stage训练循环);4)Stage训练循环5)更新训练样本集,计算tempLeafFARate(负样本被预测为正样本的个数除以读取负样本的次数,第一次没有训练之前,这个比值为1,因为没训练之前,所有负样本都被预测成了正样本,当第一层训练好以后,负样本采集时会先用第一层的分类器预测一次,若能分类,则不选用,选用负样本的数目是固定的,但选用这么多负样本总共要选的次数会随着层数的增多而加大,因为层数越大,分类器的分类能力也要求越大,说需要的样本就是前面分类器所不恩呢该识别的,故在采集时也比较困难。
)6)判断stage是否退出训练,若tempLeafFARate<requiredLeafFARate则退出stage训练,否则继续;7)强训练器训练入口tempStage->train()a.建立训练数据data=new CvCascadeBoostTrainData(主要是一些参数的设置,还有特征值的计算)b.初始化样本权重update_weights(0);c.弱分类器训练循环i)tree->train—》do_trainai)根节点的初始root=data->subsample_data(_subsample_idx);(主要是对根节点的一些参数进行初始化,parent0,count1,split0,value0,class_idx0,maxlr0,left=right=0,等等)bi)CV_CALL(try_split_node(root)),根据根节点计算整颗数的各节点的参数配置aii)calc_node_value(node);计算节点的回归值,类似于分类投票值sum(w*class_lable),正样本的class_lable取,负样本的class_lable取-1;计算节点的风险值node_risk,noderisk is the sum of squared errors:sum_i((Y_i-<node_value>)^2)bii)判断节点是否可以分裂(判断依据:样本值和设计的节点最大深度);再利用node_risk与regression_accuracy,如果这个节点的所有训练样本的节点估计值的绝对差小于这个参数,节点不再进行分裂cii)找出最佳分裂best_split=find_best_split(node);aiii)定义DTreeBestSplitFinder finder(this,node);biii)parallel_reduce(cv::BlockedRange(0,data->var_count),finder);此时调用DTreeBestSplitFinder类的操作符DTreeBestSplitFinder::operator()(constBlockedRange&range)aiv)遍历所有特征vi=vi1;vi<vi2;vi++biv)res=tree->find_split_cat_reg()得到特征为split->var_idx=vi的最佳分裂的质量split->quality(split->quality越大越好)av)将特征为vi所有样本的特征值返回到cat_labelsbv)计算每个特征值取值不权值和和响应和,例如特征值为,则将所有特征值列表中特征值为的样本权值相加,LBP的特征值范围是0~255,故有256个categorycv)计算每个category的平均响应值,即将每个category的响应和除以每个category的样本权值和dv)icvSortDblPtr(sum_ptr,mi,0);把256个值进行升序排序,注意sum_ptr里存的是sum[i]的地址,这里排序的依据是特征值还是按照每个特征值的平均响应来排序???个人感觉是按特征值的平均响应来排序fv)将每个特征值的平均响应值乘以该特征值的总权值得到每个特征值的总响应gv)遍历subset_i=0;subset_i<mi-1;subset_i++avi)计算索引是subset_i在排序前的idxbvi)获取索引idx对应的样本总权重cvi)获取索引idx对应的样本总响应dvi)以subset_i为分裂点,计算分裂质量(sumL*sumL)/weightL+(sumR*sumR)/weightRfvi)若最佳分裂质量小于这个质量,则更新最佳分裂质量hv)经过训练得到最佳分裂点和最佳分裂质量,将遍历得到的值更新到split结构体各参数。
Iv)得到该特征对应的split->subset,for(i=0;i<=best_subset;i++)avi)计算索引是i在排序前的idxbvi)split->subset[idx>>5]|=1<<(idx&31);subset[8],每个数组里存放32位的整数,整数值由idx决定,idx也就是特征值大小civ)若bestSplit->quality<split->quality,将split拷贝到bestSplitciii)初始化一个bestSplit,将finder.bestSplit拷贝到bestSplit,并返回bestSplitdii)将bestSplit赋给node->spliteii)计算节点方向quality_scale=calc_node_dir(node);aiii)获取最佳特征的索引vibiii)遍历所有样本i=0;i<n;i++aiv)计算第i个样本的特征为vi的特征值idxbiv)获取第i个样本的权重wciv)d=idx>=0?CV_DTREE_CAT_DIR(idx,subset):0CV_DTREE_CAT_DIR(idx,subset)=(2*((subset[(idx)>>5]&(1<<((idx)&31)))==0)-1)(d=1或者d=-1)div)sum+=d*w;sum_abs+=(d&1)*wfiv)dir[i]=(char)d;ciii)R=(sum_abs+sum)*0.5;(取向正样本的所有权重和)diii)L=(sum_abs-sum)*0.5;;(取向负样本的所有权重和)fiii)node->maxlr=MAX(L,R);giii)返回node->split->quality/(L+R);fii)split_node_data(node);aiii)complete_node_dir(node);对每个样本的归类属性再一次定义,确保每个样本要么分到左边要么分到右边biii)遍历样本,得到左节点和右节点的样本数nl和nrciii)对左节点和右节点初始化diii)分别计算左节点和右节点的每个特征对应的分类样本数(这中间的代码不是很懂!!!)gii)try_split_node(node->left);Iii)try_split_node(node->right);ii)cvSeqPush(weak,&tree);将训练好的树添加到弱分类器重iii)update_weights(tree);更新样本权重ai)weak_eval[i]=f(x_i)in[-1,1]对应代码为weak_eval->data.db[i]*=-orig_response->data.i[i];i为0~n-1,n为样本数目bi)w_i*=exp(-y_i*f(x_i))iv)trim_weights();调整权重,但在程序中未看出调整,该函数是根据更新后的权重调整subsample_mask的数据,即利用阈值判断正样本被检测正确的将subsample_mask的数据赋值为1;v)强制退出循环判断cvCountNonZero(subsample_mask),若subsample_mask中数据全为0,则直接退出弱分类器循环,这种情况应该不会出现d.弱分类器训练循环终止条件判断while(!isErrDesired()&&(weak->total<params.weak_count));(isErrDesired()计算负样本的虚警率,若小于maxfalserat返回true,反之返回false;isErrDesired()还计算stage阈值,具体计算过程:对正样本进行预测,预测值放在eval向量中,对向量中的预测值排序(本人默认为升序),计算阈值索引int thresholdIdx= (int)((1.0F-minHitRate)*numPos);threshold=eval[thresholdIdx];这样在检测时,根据叶子节点的预测值小于这个阈值即认为是负样本)8)如果强分类器重弱分类器的个数大于0,返回ture,否则返回false9)返回ture时输出和打印相关信息,否则退出stage循环10)保存stage的xml文件(3)输出和打印相关信息。