利用Hog特征和SVM分类器进行行人检测
1、HOG特征:
?????? 方向梯度直方圖(Histogram of Oriented Gradient, HOG)特征是一種在計算機視覺和圖像處理中用來進行物體檢測的特征描述子。它通過計算和統計圖像局部區域的梯度方向直方圖來構成特征。Hog特征結合SVM分類器已經被廣泛應用于圖像識別中,尤其在行人檢測中獲得了極大的成功。需要提醒的是,HOG+SVM進行行人檢測的方法是法國研究人員Dalal在2005的CVPR上提出的,而如今雖然有很多行人檢測算法不斷提出,但基本都是以HOG+SVM的思路為主。
(1)主要思想:
?????? 在一副圖像中,局部目標的表象和形狀(appearance and shape)能夠被梯度或邊緣的方向密度分布很好地描述。(本質:梯度的統計信息,而梯度主要存在于邊緣的地方)。
(2)具體的實現方法是:
?????? 首先將圖像分成小的連通區域,我們把它叫細胞單元。然后采集細胞單元中各像素點的梯度的或邊緣的方向直方圖。最后把這些直方圖組合起來就可以構成特征描述器。
(3)提高性能:
?????? 把這些局部直方圖在圖像的更大的范圍內(我們把它叫區間或block)進行對比度歸一化(contrast-normalized),所采用的方法是:先計算各直方圖在這個區間(block)中的密度,然后根據這個密度對區間中的各個細胞單元做歸一化。通過這個歸一化后,能對光照變化和陰影獲得更好的效果。
(4)優點:
?????? 與其他的特征描述方法相比,HOG有很多優點。首先,由于HOG是在圖像的局部方格單元上操作,所以它對圖像幾何的和光學的形變都能保持很好的不變性,這兩種形變只會出現在更大的空間領域上。其次,在粗的空域抽樣、精細的方向抽樣以及較強的局部光學歸一化等條件下,只要行人大體上能夠保持直立的姿勢,可以容許行人有一些細微的肢體動作,這些細微的動作可以被忽略而不影響檢測效果。因此HOG特征是特別適合于做圖像中的人體檢測的。
?
2、HOG特征提取算法的實現過程:
大概過程:
HOG特征提取方法就是將一個image(你要檢測的目標或者掃描窗口):
1)灰度化(將圖像看做一個x,y,z(灰度)的三維圖像);
2)采用Gamma校正法對輸入圖像進行顏色空間的標準化(歸一化);目的是調節圖像的對比度,降低圖像局部的陰影和光照變化所造成的影響,同時可以抑制噪音的干擾;
3)計算圖像每個像素的梯度(包括大小和方向);主要是為了捕獲輪廓信息,同時進一步弱化光照的干擾。
4)將圖像劃分成小cells(例如6*6像素/cell);
5)統計每個cell的梯度直方圖(不同梯度的個數),即可形成每個cell的descriptor;
6)將每幾個cell組成一個block(例如3*3個cell/block),一個block內所有cell的特征descriptor串聯起來便得到該block的HOG特征descriptor。
7)將圖像image內的所有block的HOG特征descriptor串聯起來就可以得到該image(你要檢測的目標)的HOG特征descriptor了。這個就是最終的可供分類使用的特征向量了。
?
?
具體每一步的詳細過程如下:
(1)標準化gamma空間和顏色空間
?????為了減少光照因素的影響,首先需要將整個圖像進行規范化(歸一化)。在圖像的紋理強度中,局部的表層曝光貢獻的比重較大,所以,這種壓縮處理能夠有效地降低圖像局部的陰影和光照變化。因為顏色信息作用不大,通常先轉化為灰度圖;
???? Gamma壓縮公式:
?????比如可以取Gamma=1/2;
?
(2)計算圖像梯度
????????計算圖像橫坐標和縱坐標方向的梯度,并據此計算每個像素位置的梯度方向值;求導操作不僅能夠捕獲輪廓,人影和一些紋理信息,還能進一步弱化光照的影響。
圖像中像素點(x,y)的梯度為:
?????? 最常用的方法是:首先用[-1,0,1]梯度算子對原圖像做卷積運算,得到x方向(水平方向,以向右為正方向)的梯度分量gradscalx,然后用[1,0,-1]T梯度算子對原圖像做卷積運算,得到y方向(豎直方向,以向上為正方向)的梯度分量gradscaly。然后再用以上公式計算該像素點的梯度大小和方向。
?
(3)為每個細胞單元構建梯度方向直方圖
????????第三步的目的是為局部圖像區域提供一個編碼,同時能夠保持對圖像中人體對象的姿勢和外觀的弱敏感性。
我們將圖像分成若干個“單元格cell”,例如每個cell為6*6個像素。假設我們采用9個bin的直方圖來統計這6*6個像素的梯度信息。也就是將cell的梯度方向360度分成9個方向塊,如圖所示:例如:如果這個像素的梯度方向是20-40度,直方圖第2個bin的計數就加一,這樣,對cell內每個像素用梯度方向在直方圖中進行加權投影(映射到固定的角度范圍),就可以得到這個cell的梯度方向直方圖了,就是該cell對應的9維特征向量(因為有9個bin)。
????????像素梯度方向用到了,那么梯度大小呢?梯度大小就是作為投影的權值的。例如說:這個像素的梯度方向是20-40度,然后它的梯度大小是2(假設啊),那么直方圖第2個bin的計數就不是加一了,而是加二(假設啊)。
???????? 細胞單元可以是矩形的(rectangular),也可以是星形的(radial)。
?
(4)把細胞單元組合成大的塊(block),塊內歸一化梯度直方圖
?????? 由于局部光照的變化以及前景-背景對比度的變化,使得梯度強度的變化范圍非常大。這就需要對梯度強度做歸一化。歸一化能夠進一步地對光照、陰影和邊緣進行壓縮。
??????? 作者采取的辦法是:把各個細胞單元組合成大的、空間上連通的區間(blocks)。這樣,一個block內所有cell的特征向量串聯起來便得到該block的HOG特征。這些區間是互有重疊的,這就意味著:每一個單元格的特征會以不同的結果多次出現在最后的特征向量中。我們將歸一化之后的塊描述符(向量)就稱之為HOG描述符。
??????? 區間有兩個主要的幾何形狀——矩形區間(R-HOG)和環形區間(C-HOG)。R-HOG區間大體上是一些方形的格子,它可以有三個參數來表征:每個區間中細胞單元的數目、每個細胞單元中像素點的數目、每個細胞的直方圖通道數目。
?????? 例如:行人檢測的最佳參數設置是:3×3細胞/區間、6×6像素/細胞、9個直方圖通道。則一塊的特征數為:3*3*9;
?
(5)收集HOG特征
??????最后一步就是將檢測窗口中所有重疊的塊進行HOG特征的收集,并將它們結合成最終的特征向量供分類使用。
????
(6)那么一個圖像的HOG特征維數是多少呢?
??????? 順便做個總結:Dalal提出的Hog特征提取的過程:把樣本圖像分割為若干個像素的單元(cell),把梯度方向平均劃分為9個區間(bin),在每個單元里面對所有像素的梯度方向在各個方向區間進行直方圖統計,得到一個9維的特征向量,每相鄰的4個單元構成一個塊(block),把一個塊內的特征向量聯起來得到36維的特征向量,用塊對樣本圖像進行掃描,掃描步長為一個單元。最后將所有塊的特征串聯起來,就得到了人體的特征。例如,對于64*128的圖像而言,每8*8的像素組成一個cell,每2*2個cell組成一個塊,因為每個cell有9個特征,所以每個塊內有4*9=36個特征,以8個像素為步長,那么,水平方向將有7個掃描窗口,垂直方向將有15個掃描窗口。也就是說,64*128的圖片,總共有36*7*15=3780個特征。
HOG維數,16×16像素組成的block,8x8像素的cell
?
注釋:
行人檢測HOG+SVM
總體思路:
1、提取正負樣本hog特征
2、投入svm分類器訓練,得到model
3、由model生成檢測子
4、利用檢測子檢測負樣本,得到hardexample
5、提取hardexample的hog特征并結合第一步中的特征一起投入訓練,得到最終檢測子。
深入研究hog算法原理:
一、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特征(http://blog.csdn.net/carson2005/article/details/7782726),也介紹過SVM分類器(http://blog.csdn.net/carson2005/article/details/6453502?);而本文的目的在于介紹利用Hog特征和SVM分類器來進行行人檢測。
? ? ? ? 在2005年CVPR上,來自法國的研究人員Navneet?Dalal?和Bill?Triggs提出利用Hog進行特征提取,利用線性SVM作為分類器,從而實現行人檢測。而這兩位也通過大量的測試發現,Hog+SVM是速度和效果綜合平衡性能較好的一種行人檢測方法。后來,雖然很多研究人員也提出了很多改進的行人檢測算法,但基本都以該算法為基礎框架。因此,Hog+SVM也成為一個里程表式的算法被寫入到OpenCV中。在OpenCV2.0之后的版本,都有Hog特征描述算子的API,而至于SVM,早在OpenCV1.0版本就已經集成進去了;OpenCV雖然提供了Hog和SVM的API,也提供了行人檢測的sample,遺憾的是,OpenCV并沒有提供樣本訓練的sample。這也就意味著,很多人只能用OpenCV自帶的已經訓練好的分類器來進行行人檢測。然而,OpenCV自帶的分類器是利用Navneet?Dalal和Bill?Triggs提供的樣本進行訓練的,不見得能適用于你的應用場合。因此,針對你的特定應用場景,很有必要進行重新訓練得到適合你的分類器。本文的目的,正在于此。
重新訓練行人檢測的流程:
(1)準備訓練樣本集合;包括正樣本集和負樣本集;根據機器學習的基礎知識我們知道,要利用機器學習算法進行樣本訓練,從而得到一個性能優良的分類器,訓練樣本應該是無限多的,而且訓練樣本應該覆蓋實際應用過程中可能發生的各種情況。(很多朋友,用10來個正樣本,10來個負樣本進行訓練,之后,就進行測試,發現效果沒有想象中的那么好,就開始發牢騷,抱怨。。。對于這些人,我只能抱歉的說,對于機器學習、模式識別的認識,你還處于沒有入門的階段);實際應用過程中,訓練樣本不可能無限多,但無論如何,三五千個正樣本,三五千個負樣本,應該不是什么難事吧?(如果連這個都做不到,建議你別搞機器學習,模式識別了;訓練素材都沒有,怎么讓機器學習到足夠的信息呢?)
(2)收集到足夠的訓練樣本之后,你需要手動裁剪樣本。例如,你想用Hog+SVM來對商業步行街的監控畫面中進行行人檢測,那么,你就應該用收集到的訓練樣本集合,手動裁剪畫面中的行人(可以寫個簡單程序,只需要鼠標框選一下,就將框選區域保存下來)。
(3)裁剪得到訓練樣本之后,將所有正樣本放在一個文件夾中;將所有負樣本放在另一個文件夾中;并將所有訓練樣本縮放到同樣的尺寸大小。OpenCV自帶的例子在訓練時,就是將樣本縮放為64*128進行訓練的;
(4)提取所有正樣本的Hog特征;
(5)提取所有負樣本的Hog特征;
(6)對所有正負樣本賦予樣本標簽;例如,所有正樣本標記為1,所有負樣本標記為0;
(7)將正負樣本的Hog特征,正負樣本的標簽,都輸入到SVM中進行訓練;Dalal在論文中考慮到速度問題,建議采用線性SVM進行訓練。這里,不妨也采用線性SVM;
(8)SVM訓練之后,將結果保存為文本文件。
(9)線性SVM進行訓練之后得到的文本文件里面,有一個數組,叫做support?vector,還有一個數組,叫做alpha,有一個浮點數,叫做rho;將alpha矩陣同support?vector相乘,注意,alpha*supportVector,將得到一個列向量。之后,再該列向量的最后添加一個元素rho。如此,變得到了一個分類器,利用該分類器,直接替換opencv中行人檢測默認的那個分類器(cv::HOGDescriptor::setSVMDetector()),就可以利用你的訓練樣本訓練出來的分類器進行行人檢測了。
下面給出樣本訓練的參考代碼:
[cpp]?view plaincopy
[cpp]?view plaincopy
總結
以上是生活随笔為你收集整理的利用Hog特征和SVM分类器进行行人检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT简介
- 下一篇: OpenCV的HOG+SVM训练程序注意