使用Haar Cascade 進行人臉識別

2021-08-09 14:02:08 字數 2741 閱讀 5714

學完了deeplearnning.ai 的卷積神經網路課程之後,為了更直觀的理解人臉識別,我想使用opencv來實現人臉識別。(以下為譯文)

基於haar特徵的cascade分類器(classifiers) 是paul viola和 michael jone在2023年,**」rapid object detection using a boosted cascade of ****** features」中提出的一種有效的物品檢測(object detect)方法。它是一種機器學習方法,通過許多正負樣例中訓練得到cascade方程,然後將其應用於其他。

現在讓我們來看以下人臉識別是如何工作的。首先,演算法需要許多正樣例(包含人臉的)和負樣例(不包含人臉的)來訓練分類器。然後我們要從這些中獲取特徵(extract features)。如下所示為haar 特徵獲取的方式。和卷積核(conventional kernel)類似,每個特徵由白方塊下的畫素和減去黑方塊的畫素和來得到。

每個核(kernel)所有可能的尺寸和位置計算得到了大量特徵。(想象一下有多少特徵?24x24尺寸的滑動視窗特徵數就超過160000)。對於每個特徵我們都需要計算白方塊和黑方塊的畫素和。為了解決大量計算的問題,有人引入了積分影象(intergal images)的概念。它大大簡化了畫素和的計算,大約只需要畫素數目數量級的運算,每次運算只涉及到4個畫素。很棒吧?這讓一切都變得超級快。

在我們計算的所有特徵中,大部分特徵是無關緊要的。比如下圖這個例子。 頂上一行表示兩個不錯的特徵,第乙個特徵似乎是根據眼睛所在位置通常比臉頰和鼻子更黑來選擇,而第二個特徵選擇的依據則是眼睛比鼻樑要黑。因此,相同的視窗用於臉頰或者其他部位時就沒有意義了。那麼我們如何從超過16萬個的特徵中選擇最好的特徵呢?我們可以使用adaboost來實現。

因此,我們將每個特徵都應用於所有訓練集中,對於每個特徵,找出人臉分類效果最好的閾值。顯然,分類會有誤分類,我們選擇分類錯誤率最小的那些特徵,也就是說這些特徵可以最好的將人臉和非人臉區分開。(實際上沒有那麼簡單,每個初始時給定相同的權重。每次分類後,提公升被分類錯誤的權重。然後再根據新的權重分類,計算出新的錯誤率和新的權重,直到錯誤率或迭代次數達到要求即停止(譯註:實際上就是adaboost的流程))。

最終的分類器是這些弱分類器的加權和。之所以稱之為弱分類器是因為每個分類器不能單獨分類,但是將他們聚集起來就形成了強分類器。**表明,只需要200個特徵的分類器在檢測中的精確度達到了95%。最終的分類器大約有6000個特徵。(將超過160000個特徵減小到6000個,這是非常大的進步了)

假設現在你有一張,使用24x24的滑動視窗,將6000個特徵應用於來檢測是否為人臉。嗯….這是不是有點效率低下,浪費時間?確實是的,不過作者自有妙計。

事實上,一張中大部分的區域都不是人臉。如果能找到乙個簡單的方法能夠檢測某個視窗是不是人臉區域,如果該視窗不是人臉區域,那麼就只看一眼便直接跳過,也就不用進行後續處理了,這樣就能集中精力判別那些可能是人臉的區域。

為此,有人引入了cascade 分類器。它不是將6000個特徵都用在乙個視窗,而是將特徵分為不同的階段,然後乙個階段乙個階段的應用這些特徵(通常情況下,前幾個階段只有很少量的特徵)。如果視窗在第乙個階段就檢測失敗了,那麼就直接捨棄它,無需考慮剩下的特徵。如果檢測通過,則考慮第二階段的特徵並繼續處理。如果所有階段的都通過了,那麼這個視窗就是人臉區域。

作者的檢測器將6000+的特徵分為了38個階段,前五個階段分別有1,10,25,25,50個特徵(前文圖中提到的兩個特徵實際上是adaboost中得到的最好的兩個特徵)。根據作者所述,平均每個子視窗只需要使用6000+個特徵中的10個左右。

以上就是viola-jones 人臉識別的工作原理簡述,閱讀其**可以得到更多的細節。

opencv 既可以作為檢測器也可以進行訓練。如果你打算訓練自己的分類器識別任意的物品,比如車,飛機等。你可以用opencv 創造乙個。完整的細節在:cascade classifier training¶中。

這裡我們只說如何使用它的檢測器功能。opencv已經包含許多訓練好的分類器,比如臉、眼、微笑等。這些xml檔案儲存在opencv/data/haarcascades/資料夾中。讓我們用opencv建立乙個臉部和眼部檢測器吧!

首先我們需要載入需要的xml分類器。然後在灰度模式下載入我們的輸入檔案。

現在我們就能從中找到人臉了。如果識別出人臉,會以rect(x,y,w,h)的形式返回臉部的位置,然後我們可以用乙個矩形網格標識人臉,然後在這個矩形網格之間應用眼部識別(因為眼睛一定在臉上!)

結果如下圖所示。(譯註:使用opencv自帶的人臉識別時,當人臉角度有些傾斜時很難識別到人臉,以後有機會希望可以研究並解決這個問題)

使用with進行回溯

with dept deptid,pdeptid as select udepid,uparentid from oa.dbo.depinfo where udepid in select p.udepid from oa.dbo.postinfo as p inner join oa.dbo.us...

使用進行Google攻擊

使用進行google攻擊 google是乙個功能強大的搜尋引擎,通過預定義命令,可以查詢出令人難以置信的結果。利用google搜尋智慧型搜尋,甚至可以進入部分遠端伺服器獲取機密 搜尋敏感資訊,造成資訊洩露。本文從安全角度,對google這一工具進行深度資訊挖掘。google高階搜尋語法 討論goog...

使用JUnit進行測試

junit 被用來測試 並且它是由能夠測試不同條件的斷言方法 assertion method 組成,如下所示 assertequals a,b 測試a是否等於b a和b是原始型別數值 primitive value 或者必須為實現比較而具有equal方法 assertfalse a 測試a是否為f...