1. 程式人生 > >python通過HOG+SVM實現行人檢測思路

python通過HOG+SVM實現行人檢測思路

一、思路

1、選取視窗寬高為 64*128 ,block大小為 16*16畫素,block步長為8畫素,cell為8*8畫素,每個cell分9個bin,其他引數都預設

        這樣的話,一個block有4個cell,一個cell有9維,那一個block有 4*9=36維特徵描述子,寬為64,x方向能有(64/8)-1 = 7 個block,高為128,y方向能有(128/8)-1=15 個, 那麼一個視窗的的特徵描述子維度為 7*15*36 = 3780

2、提取正例,每個正例有3780個特徵,label 為 1 ,提取負例也是3780個,label為-1

      那麼問題來了,在這裡我使用的是INRIADATA資料來源,正例中它提供了 行人 位置(一個矩形的左上點和右下點)和一個 center點(標記的是頭部),而這個矩形的寬高,都不滿足 64*128,這裡,網路上大部分人都是直接resize或者做一些邊沿填充,將矩形調整為64*128,直接resize我覺得還好,只要原圖比例差不多,生成的特徵不會差太遠,而邊沿填充就很不好了,如圖1,填充的話就直接添加了很多非人體的特徵,在SVM學習中則相當於增加了正例中的錯誤分類。而我的做法是在原矩形的基礎上以矩形的中心為基準稍微調整其寬高,使之寬高比=64/128,然後再直接reszie為64*128,效果如圖2。我認為這樣是比較合適的。

     而負例怎麼提取呢?負例圖基本都是一張寬的風景圖,完全不包含行人。網上的做法是直接resize為64*128,這樣做,並沒有什麼問題,因為現實生活中是背景是千奇百怪的,負例的資訊是遠高於正例的,但我在這裡稍微講究點,用64*128的視窗提取負例,就這樣,我提取了500000多個的負例,由於numpy維度最高為100000左右,因此我嘗試分批訓練,但在執行第二次svm.train的時候報錯了“sv_count != 0 in function 'cv::ml::SVMImpl::do_train'” 這個問題是因為svm判斷了每次訓練不能沒有正例,因為正例只有2000多個,第二次分批的時候已經沒有正例了。這裡我做簡單點,生成負例的時候只隨機取了50000多個與2000多個正例一起訓練。

3、進行SVM訓練,引數都是預設用的是EPS_SVR。

     這裡值得一提的是svm.train 中響應值 _responses 應為 CV_VAR_ORDERED(迴歸)

4、進行難例訓練。

      使用第3步訓練得到的模型對負例原圖進行識別,將識別到的圖片作為難例,新增到特徵資料裡,再訓練。事實上按照步驟2的方式提取負例,已經沒有難例了。

5、得到最終模型。如圖3

    最終框出來的區域還得做非極大值抑制。

圖1
圖1
圖2

 

圖3