OpenCV之 HOG檢測子針對SVM線性核的檢測

要做一些行人檢測方面的工作,環境爲vs2010+OpenCV2.4.4

        參考博客:http://blog.csdn.net/masibuaa/article/details/16105073

                             http://blog.csdn.net/masibuaa/article/details/16113373

         收集樣本訓練了自己的SVM分類器,接下來在用HOG的多尺度檢測函數detectMultiScale()進行檢測時遇到了一些問題,經過查閱大量的資料及反覆閱讀源代碼,終於搞清楚了原因,現在進行一下簡單的整理。

         整個過程可以分爲訓練分類器和HOG檢測兩部分

         OpenCV的SVM訓練函數中提供了4種核函數:Linear、poly、RBF、sigmoid,依次找出各核函數對應的效果最好的分類器,主要用到兩個函數SVM::train()和SVM::predict()。

         SVM::train()訓練分類器,該函數中可以指定包括核函數在內的其他參數。SVM::predict()用於預測。過程簡單表述爲:先確定某一具體核函數(如Linear),其他參數(如Cvalue)取默認值,輸入訓練樣本訓練分類器,統計測試樣本預測的準確率,不斷調整參數,找到預測準確率最高的分類器。

         在確定分類器後,則開始對整幅圖像利用HOG:: detectMultiScale()進行多尺度檢測,也正是在這個過程中遇到了問題。對線性核的情況,一切正常。但是在對其他核(如RBF)分類器的情況,出現了問題。OpenCV自帶的源代碼中,判斷是不是目標的閾值爲0,在檢測的過程中將HOG:: detectMultiScale()中對應的參數設置爲0即可,但在非線性核(如RBF)分類器的情況,其閾值則出現了一些不可預料的結果。

         針對出現的這種情況,反覆閱讀源代碼並查找了相關的資料,最終確定了原因:HOG的多尺度檢測函數(HOG:: detectMultiScale())或者更準確一點其檢測函數(HOG::detect ())只針對SVM線性核進行檢測!!這在設置HOG檢測子(HOG::setSVMDetector)的時候就已經確定了!!

         另外也可以由源代碼中看出,下面附上部分的源代碼片段進行說明,code1爲SVM線性核的計算方法,code2爲HOG檢測函數(HOG:: detect ())的計算方法。

code1:

for( j = 0; j < vcount; j++ )
    {
        const float* sample = vecs[j];
        double s = 0;
        for( k = 0; k <= var_count - 4; k += 4 )
            s += sample[k]*another[k] + sample[k+1]*another[k+1] +
                 sample[k+2]*another[k+2] + sample[k+3]*another[k+3];
        for( ; k < var_count; k++ )
            s += sample[k]*another[k];
        results[j] = (Qfloat)(s*alpha + beta);
    }
code2:
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]);
#ifdef HAVE_IPP
            Ipp32f partSum;
            ippsDotProd_32f(vec,svmVec,blockHistogramSize,&partSum);
            s += (double)partSum;
#else
            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];
#endif
        }
除了源代碼以外,在OpenCV的官網上也進行了相關的說明


可惜,在這個問題上糾結這麼久,答案其實早就已經給出來了,但一直都沒找到!

發佈了15 篇原創文章 · 獲贊 17 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章