关于HOGDescriptor中的SVMDetector

【原文:http://hi.baidu.com/windey1988/item/c239139f9efbacc3b62531fd】

opencv中带有计算HOG的代码,同时还包含了一个peopledetect的例程。

在例程中,声明一个HOGDescriptor的对象hog,构造函数为系统默认的构造函数,

检测窗大小为64*128,block大小为16*16,cell大小为8*8,每个cell包含的方向bin

为9个。对于hog对象的一个成员SVMDetector,采用如下的方式进行初始化:

       hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

输入一张图片时,对于这张图片进行多尺度检测。原理很简单:对于检测窗中

的图像计算HOG描述子,然后和SVMDetector求内积,加上一个rho,若大于等于

一个阈值,表示检测窗中对应的是行人。

      其源代码中检测部分核心实现如下:

        double s = rho;

        const float* svmVec = &svmDetector[0];

        int j, k;

        for( j = 0; j < nblocks; j++, svmVec += blockHistogramSize )

        {

            const HOGCache::BlockData& bj = blockData[j];

            Point pt = pt0 + bj.imgOffset;


            const float* vec = cache.getBlock(pt, &blockHist[0]);

            for( k = 0; k <= blockHistogramSize - 4; k += 4 )

                s += vec[k]*svmVec[k] + vec[k+1]*svmVec[k+1] +

                    vec[k+2]*svmVec[k+2] + vec[k+3]*svmVec[k+3];

            for( ; k < blockHistogramSize; k++ )

                s += vec[k]*svmVec[k];

        }

        if( s >= hitThreshold )

            hits.push_back(pt0);

       这里默认的Detector其实就是一个3780维的浮点数组。它到底是怎么来的呢?

这里我纠结了好久好久。网上有人说,它其实是支持向量的加权,也就是求和

(支持向量sv_i * alpha_i)。

       其实很简单,根据SVM的原理,构建一个最大间隔的超平面,有效地将样本

分为两类。分类超平面对应的方程为:wx+b=0.

       因此,我们很容易的可以知道,这个Detector其实就是方程中的w。

因此,由支持向量和对应的alpha加权可以得到。由于opencv中cvSVM类将支持向量

和权值alpha都设置为了保护成员,我们可以引入一个派生类继承于cvSVM,通过操作

cvSVM的支持向量和alpha可以得到检测子。

      关于如何得到SVMDetector的讨论可以看:

      http://tech.groups.yahoo.com/group/OpenCV/message/80890

      http://comments.gmane.org/gmane.comp.lib.opencv/46508

你可能感兴趣的:(HOG)