【原理】HOG+SVM

【原文:http://blog.sina.com.cn/s/blog_70987ec30101mt3y.html】

总体思路:

1、提取正负样本hog特征
2、投入svm分类器训练,得到model
3、由model生成检测子
4、利用检测子检测负样本,得到hardexample
5、提取hardexample的hog特征并结合第一步中的特征一起投入训练,得到最终检测子。


深入研究hog算法原理:
一、hog概述
Histograms of Oriented Gradients 
Histograms of Oriented Gradients,顾名思义,方向梯度直方图,是目标的一种描述的方式,既是描述子。
二、hog提出
hog是05年一位nb的博士提出来的,论文链接 http://wenku.baidu.com/view/676f2351f01dc281e53af0b2.html
三、算法理解
终于到10月了,终于可以松一口气了,整理一下hog的算法流程。
首先要有一个整体的认识,每一个目标都对应一个一维特征向量,这个向量一共有n维,这个n不是凭空瞎猜的,是有理有据,打个比方,为什么opencv自带的hog检测子是3781维的?这个问题在初期确实比较头疼,纠结了好长的时间,不过别着急,我们先来看一下opencv里的HOGDescriptor这个结构的构造函数HOGDescriptor(Size winSize,Size blocksize,Size blockStride,Size cellSize,...(后面的参数在这里用不到)),去查一下opencv默认的参数我们可以看到,winSize(64,128),blockSize(16,16),blockStride(8,8),cellSize(8,8),很显然hog是将一个特征窗口win划分为很多的块block,在每一个块里又划分为很多的细胞单元cell(即胞元),hog特征向量既是把这些所有的cell对应的小特征串起来得到一个高维的特征向量,那么这个窗口对应的一维特征向量维数n就等于 窗口中的块数 x 块中的胞元数  x 每一个胞元对应的特征向量数。
写到这里,我们计算一下3781如何得到的,窗口大小64x128,块大小16x16,块步长8x8,那么窗口中块的数目是((64-16)/8+1)*((128-16)/8+1) = 7*15 = 105个块,块大小为16x16,胞元大小为8x8,那么一个块中的胞元cell数目是 (16/8)*(16/8) = 4个胞元,到这里我们可以看到要求最后需要的维数n,只需要计算每一个胞元对应的向量,这个参数在哪呢?别急,我们把每一个胞元投影到9个bin(如何投影?这里卡了很长一段时间,后面会说),那么每一个胞元对应的向量就是9维,每个bin对应该9维向量的一个数,现在看一下是不是计算窗口维数的三个需求量都知道了,n = 窗口中的块数 x 块中的胞元数  x 每一个胞元对应的特征向量数,带入看一下n= 105x4x9 = 3780,这就是这个窗口对应的特征了。有人会说,为什么opencv里的getDefaultPeopleDetector()得到的是3781维呢?这是因为另外一维是一维偏移,(很崩溃是吧,我也崩溃很久。。。,下一段解释)。
我们利用hog+svm检测行人,最终的检测方法是最基本的线性判别函数,wx + b = 0,刚才所求的3780维向量其实就是w,而加了一维的b就形成了opencv默认的3781维检测算子,而检测分为train和test两部分,在train期间我们需要提取一些列训练样本的hog特征使用svm训练最终的目的是为了得到我们检测的w以及b,在test期间提取待检测目标的hog特征x,带入方程是不是就能进行判别了呢?
**************************************************************************************************
                                           华丽的分割线
写到这里,至少对hog的运作流程有了一个大概的认识,在网上能看到很多的hog计算方法,神马归一化,计算梯度,对每个胞元进行投影,千篇一律,对刚开始接触的人来说,看完好像懂了,但就是不知道怎么用,hog和svm如何配合,而且那些东西对我们的初期的学期完全没用,好处就是会用hog了,再回过头去看原理,才有收获,那些资料网上一堆,这里就不画蛇添足了。
另外值得一提的是在计算胞元特征的时候,需要向各个bin投影,这个投影里面大有文章,师兄毕业论文里就提到了,取名叫‘三维一次线性插值’,如果想深入了解hog的可以仔细琢磨去。
**************************************************************************************************
                                         继续华丽的分割
下面说一下libsvm和CvSVM的使用,我觉得libsvm更好用,不过cvsvm也是基于libsvm2.6(没记错的话)改写的,这两个的区别就是libsvm训练得到的是一个model,而cvsvm是xml文件,在计算最后的wx+b=0中的w向量的时候,对于libsvm直接处理model文件即可,但是对于cvsvm则可以跳过产生xml文件,直接使用cvsvm的对象中的属性即可(这里说的有点模糊,二者选一个即可,关系倒不是很大)

你可能感兴趣的:(HOG)