1. 程式人生 > >走近人臉檢測(1)——基本流程

走近人臉檢測(1)——基本流程

人臉檢測的任務就是判斷給定的影象上是否存在人臉,如果人臉存在,就給出全部人臉所處的位置及其大小。由於人臉檢測在實際應用中的重要意義,早在上世紀70年代就已經有人開始研究,然而受當時落後的技術條件和有限的需求所影響,直到上世紀90年代,人臉檢測技術才開始加快向前發展的腳步,在新世紀到來前的最後十年間,湧現出了大量關於人臉檢測的研究工作,這時期設計的很多人臉檢測器已經有了現代人臉檢測技術的影子,例如可變形模板的設計(將人臉按照五官和輪廓劃分成多個相互連線的區域性塊)、神經網路的引入(作為判斷輸入是否為人臉的分類模型)等。這些早期的工作主要關注於檢測正面的人臉,基於簡單的底層特徵如物體邊緣、影象灰度值等來對影象進行分析,結合關於人臉的先驗知識來設計模型和演算法(如五官、膚色),並開始引入一些當時已有的的模式識別方法。    

雖然早期關於人臉檢測的研究工作離實際應用的要求還有很遠,但其中進行檢測的流程已經和現代的人臉檢測方法沒有本質區別。給定一張輸入影象,要完成人臉檢測這個任務,我們通常分成三步來進行:  

  1.選擇影象上的某個(矩形)區域作為一個觀察視窗;   

 2.在選定的視窗中提取一些特徵對其包含的影象區域進行描述;   

 3.根據特徵描述來判斷這個視窗是不是正好框住了一張人臉。   

檢測人臉的過程就是不斷地執行上面三步,直到遍歷所有需要觀察的視窗。如果所有的視窗都被判斷為不包含人臉,那麼就認為所給的影象上不存在人臉,否則就根據判斷為包含人臉的視窗來給出人臉所在的位置及其大小。    

那麼,如何來選擇我們要觀察的視窗呢?所謂眼見為實,要判斷影象上的某個位置是不是一張人臉,必須要觀察了這個位置之後才知道,因此,選擇的視窗應該覆蓋影象上的所有位置。顯然,最直接的方式就是讓觀察的視窗在影象上從左至右、從上往下一步一步地滑動,從影象的左上角滑動到右下角——這就是所謂的滑動視窗正規化,你可以將它想象成是福爾摩斯(檢測器)在拿著放大鏡(觀察視窗)仔細觀察案發現場(輸入影象)每一個角落(滑動)的過程。 

人臉檢測發展:從VJ到深度學習(上)

別看這種用視窗在影象上進行掃描的方式非常簡單粗暴,它的確是一種有效而可靠的視窗選擇方法,以至於直到今天,滑動視窗正規化仍然被很多人臉檢測方法所採用,而非滑動視窗式的檢測方法本質上仍然沒有擺脫對影象進行密集掃描的過程。    

對於觀察視窗,還有一個重要的問題就是:視窗應該多大?我們認為一個視窗是一個人臉視窗當且僅當其恰好框住了一張人臉,即視窗的大小和人臉的大小是一致的,視窗基本貼合人臉的外輪廓。    

人臉檢測發展:從VJ到深度學習(上)

那麼問題來了,即使是同一張影象上,人臉的大小不僅不固定,而且可以是任意的,這樣怎麼才能讓觀察視窗適應不同大小的人臉呢?一種做法當然是採用多種不同大小的視窗,分別去掃描影象,但是這種做法並不高效。換一個角度來看,其實也可以將影象縮放到不同的大小,然後用相同大小的視窗去掃描——這就是所謂的構造影象金字塔的方式。影象金字塔這一名字非常生動形象,將縮放成不同大小的影象按照從大到小的順序依次往上堆疊,正好就組成了一個金字塔的形狀。

人臉檢測發展:從VJ到深度學習(上)

通過構建影象金字塔,同時允許視窗和人臉的貼合程度在小範圍內變動,我們就能夠檢測到不同位置、不同大小的人臉了。另外需要一提的是,對於人臉而言,我們通常只用正方形的觀察視窗,因此就不需要考慮視窗的長寬比問題了。    

選好了視窗,我們開始對視窗中的影象區域進行觀察,目的是收集證據——真相只有一個,我們要依靠證據來挖掘真相!在處理影象的過程中,這個收集證據的環節我們稱之為特徵提取,特徵就是我們對影象內容的描述。由於機器看到的只是一堆數值,能夠處理的也只有數值,因此對於影象所提取的特徵具體表示出來就是一個向量,稱之為特徵向量,其每一維是一個數值,這個數值是根據輸入(影象區域)經由某些計算(觀察)得到的,例如進行求和、相減、比較大小等。總而言之,特徵提取過程就是從原始的輸入資料(影象區域顏色值排列組成的矩陣)變換到對應的特徵向量的過程,特徵向量就是我們後續用來分析和尋找真相的證據。   

特徵提取之後,就到了決斷的時刻:判別當前的視窗是否恰好包含一張人臉。我們將所有的視窗劃分為兩類,一類是恰好包含人臉的視窗,稱之為人臉視窗,剩下的都歸為第二類,稱之為非人臉視窗,而最終判別的過程就是一個對當前觀察視窗進行分類的過程。因為我們的證據是由數值組成的特徵向量,所以我們是通過可計算的數學模型來尋找真相的,用來處理分類問題的數學模型我們通常稱之為分類器,分類器以特徵向量作為輸入,通過一系列數學計算,以類別作為輸出——每個類別會對應到一個數值編碼,稱之為這個類別對應的標籤,如將人臉視窗這一類編碼為1,而非人臉視窗這一類編碼為-1;分類器就是一個將特徵向量變換到類別標籤的函式。    

考慮一個最簡單的分類器:將特徵向量每一維上的數值相加,如果得到的和超過某個數值,就輸出人臉視窗的類別標籤1,否則輸出非人臉視窗的類別標籤-1。記特徵向量為,

人臉檢測發展:從VJ到深度學習(上)

分類器為函式f(x),那麼有:    

人臉檢測發展:從VJ到深度學習(上)

這裡的t就是前面所說的“某個數值”,其決定了分類器在給定特徵向量下的輸出結果,我們稱其為分類器的引數。不同形式和型別的分類器會有不同的引數,一個分類器可以有一個或者多個引數,引數或者其取值不同則對應到不同的分類器。選定了一個分類器之後,緊接著的一個問題就是:引數該怎麼設定?具體到我們正在考慮的情況,就是:t的值該如何選取?   

要做出選擇,就要有一個目標,在分類問題中,目標當然就是儘可能正確地進行分類,即分類的準確率儘可能高。然而,儘管我們對目標非常明確,我們也仍然沒法給出一個最優的引數取值,因為我們並不使用機器所採用的二進位制語言系統,我們並不懂什麼才是對機器最好的。於是我們只有一種選擇:把我們的目標告訴機器,舉一些例子向其進行解釋,然後讓機器自己去學習這個引數,最後我們給機器設計一場考試,測試其是否滿足了我們的要求。我們從一些影象上選出一部分人臉和非人臉視窗的樣例,用對應的類別標籤對其進行標註,然後將這些樣例劃分成兩個集合,一個集合作為分類器學習所使用的訓練集,另一個集合作為最終考查分類器能力的測試集,同時我們設定一個目標:希望分類的準確率能夠在80%以上。    

學習過程開始時,我們先給分類器的引數設定一個初始值,然後讓分類器通過訓練集中帶有“答案”(類別標籤)的樣例,不斷去調整自己引數的取值,以縮小其實際的分類準確率和目標準確率之間的差距。當分類器已經達到了預先設定的目標或者其它停止學習的條件——期末考試的時間是不會因為你沒有學好而推遲的,或者分類器覺得自己已經沒有辦法再調整了,學習過程就停止了,這之後我們可以考查分類器在測試集上的準確率,以此作為我們評判分類器的依據。這一過程中,分類器調整自己引數的方式和分類器的型別、設定的目標等都有關,由於這部分內容超出了本文所討論的範疇,也並不影響讀者對人臉檢測方法的理解,因此不再展開進行講述。    

在確定了選擇視窗的策略,設計好了提取特徵的方式,並學習了一個針對人臉和非人臉視窗的分類器之後,我們就獲得了構建一個人臉檢測系統所需要的全部關鍵要素——還有一些小的環節相比之下沒有那麼重要,這裡暫且略去。    

由於採用滑動視窗的方式需要在不同大小的影象上的每一個位置進行人臉和非人臉視窗的判別,而對於一張大小僅為480*320的輸入影象,視窗總數就已經高達數十萬,面對如此龐大的輸入規模,如果對單個視窗進行特徵提取和分類的速度不夠快,就很容易使得整個檢測過程產生巨大的時間開銷,也確實就因為如此,早期所設計的人臉檢測器處理速度都非常慢,一張影象甚至需要耗費數秒才能處理完成——視訊的播放速度通常為每秒25幀影象,這給人臉檢測投入現實應用帶來了嚴重的障礙。