計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

Kervin_Chan發表於2019-03-01

一、Haar特徵原理綜述

Haar特徵是一種反映影象的灰度變化的,畫素分模組求差值的一種特徵。它分為三類:邊緣特徵、線性特徵、中心特徵和對角線特徵。用黑白兩種矩形框組合成特徵模板,在特徵模板內用 黑色矩形畫素和 減去 白色矩形畫素和來表示這個模版的特徵值。例如:臉部的一些特徵能由矩形模組差值特徵簡單的描述,如:眼睛要比臉頰顏色要深,鼻樑兩側比鼻樑顏色要深,嘴巴比周圍顏色要深等。但矩形特徵只對一些簡單的圖形結構,如邊緣、線段較敏感,所以只能描述在特定方向(水平、垂直、對角)上有明顯畫素模組梯度變化的影象結構。

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

如上圖A、B、D模組的影象Haar特徵為:v=Sum白-Sum黑 C 模組的影象Haar特徵為:v=Sum白(左)+Sum白(右)-2*Sum黑 這裡要保證白色矩形模組中的畫素與黑色矩形的模組的畫素數相同,所以乘2

對於一幅影象來說,可以通過通過改變特徵模板的大小和位置,可窮舉出大量的特徵來表示一幅影象。上圖的特徵模板稱為“特徵原型”;特徵原型在影象子視窗中擴充套件(平移伸縮)得到的特徵稱為“矩形特徵”;矩形特徵的值稱為“特徵值”。例如在24*24大小的影象中可以以座標(0,0)開始寬為20高為20矩形模版計算上圖A特徵,也可以以座標(0,2)開始寬為20高為20矩形模版計算上圖A特徵,也可以以座標(0,0)開始寬為22高為22矩形模版計算上圖A特徵,這樣矩形特徵值隨著類別、大小和位置的變化,使得很小的一幅很小的影象含有非常多的矩形特徵。矩形特徵值是矩形模版類別、矩形位置和矩形大小這三個因素的函式。

二、AdaBoost分類器

AdaBoost是典型的Boosting演算法,屬於Boosting家族的一員。在說AdaBoost之前,先說說Boosting提升演算法。
Boosting演算法是將“弱學習演算法“提升為“強學習演算法”的過程,主要思想是“三個臭皮匠頂個諸葛亮”。一般來說,找到弱學習演算法要相對容易一些,然後通過反覆學習得到一系列弱分類器,組合這些弱分類器得到一個強分類器。Boosting演算法要涉及到兩個部分,加法模型和前向分步演算法。加法模型就是說強分類器由一系列弱分類器線性相加而成。一般組合形式如下:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

其中,h(x;am) 就是一個個的弱分類器,am是弱分類器學習到的最優引數,βm就是弱學習在強分類器中所佔比重,P是所有am和βm的組合。這些弱分類器線性相加組成強分類器。

前向分步就是說在訓練過程中,下一輪迭代產生的分類器是在上一輪的基礎上訓練得來的。也就是可以寫成這樣的形式:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

由於採用的損失函式不同,Boosting演算法也因此有了不同的型別,AdaBoost就是損失函式為指數損失的Boosting演算法。

AdaBoost 原理理解 基於Boosting的理解,對於AdaBoost,我們要搞清楚兩點:

每一次迭代的弱學習h(x;am)有何不一樣,如何學習? 弱分類器權值βm如何確定? 對於第一個問題,AdaBoost改變了訓練資料的權值,也就是樣本的概率分佈,其思想是將關注點放在被錯誤分類的樣本上,減小上一輪被正確分類的樣本權值,提高那些被錯誤分類的樣本權值。然後,再根據所採用的一些基本機器學習演算法進行學習,比如邏輯迴歸。

對於第二個問題,AdaBoost採用加權多數表決的方法,加大分類誤差率小的弱分類器的權重,減小分類誤差率大的弱分類器的權重。這個很好理解,正確率高分得好的弱分類器在強分類器中當然應該有較大的發言權。

例項解釋

為了加深理解,我們來舉一個例子。

有如下的訓練樣本,我們需要構建強分類器對其進行分類。x是特徵,y是標籤。

序號 0 1 2 3 4 5 6 7 8 9 10
x 0 1 2 3 4 5 6 7 8 9 10
y 1 1 1 -1 -1 -1 1 1 1 -1

令權值分佈D1=(w1,1,w1,2,…,w1,10)

並假設一開始的權值分佈是均勻分佈:w1,i=0.1,i=1,2,…,10

現在開始訓練第一個弱分類器。我們發現閾值取2.5時分類誤差率最低,得到弱分類器為:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

當然,也可以用別的弱分類器,只要誤差率最低即可。這裡為了方便,用了分段函式。得到了分類誤差率e1=0.3。

第二步計算(G1(x)在強分類器中的係數

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

這個公式先放在這裡,下面再做推導。

第三步更新樣本的權值分佈,用於下一輪迭代訓練。由公式:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

得到新的權值分佈,從各0.1變成了:

D2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)

可以看出,被分類正確的樣本權值減小了,被錯誤分類的樣本權值提高了。

第四步得到第一輪迭代的強分類器:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

以此類推,經過第二輪……第N輪,迭代多次直至得到最終的強分類器。迭代範圍可以自己定義,比如限定收斂閾值,分類誤差率小於某一個值就停止迭代,比如限定迭代次數,迭代1000次停止。這裡資料簡單,在第3輪迭代時,得到強分類器:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

的分類誤差率為0,結束迭代。

F(x)=sign(F3(x))就是最終的強分類器。

演算法流程

總結一下,得到AdaBoost的演算法流程:

輸入:訓練資料集

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

其中,

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)
迭代次數M

1. 初始化訓練樣本的權值分佈:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

2.對於m=1,2,…,M
(a)使用具有權值分佈Dm的訓練資料集進行學習,得到弱分類器Gm(x)
(b)計算Gm(x)在訓練資料集上的分類誤差率:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

(c)計算Gm(x)在強分類器中所佔的權重:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

(d)更新訓練資料集的權值分佈(這裡,zm是歸一化因子,為了使樣本的概率分佈和為1):

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

3.得到最終分類器:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

公式推導

現在我們來搞清楚上述公式是怎麼來的。

假設已經經過m−1輪迭代,得到Fm−1(x),根據前向分步,我們可以得到:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

我們已經知道AdaBoost是採用指數損失,由此可以得到損失函式:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

這時候,Fm−1(x)是已知的,可以作為常量移到前面去:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

其中,

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)
敲黑板!這個就是每輪迭代的樣本權重!依賴於前一輪的迭代重分配。

是不是覺得還不夠像?那就再化簡一下:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

現在夠像了吧?ok,我們繼續化簡Loss:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

公式變形之後,炒雞激動!

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)
這個不就是分類誤差率em嗎???!重寫一下,

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

Ok,這樣我們就得到了化簡之後的損失函式。接下來就是求導了。

對αm求偏導,令

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

得到:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

AdaBoost分析原文連結:https://www.cnblogs.com/ScorpioLu/p/8295990.html

三、例項

detectMultiScale()

引數

  • InputArray image,待檢測圖片,一般為灰度影象加快檢測速度;
  • std::vector< Rect > & objects,被檢測物體的矩形框向量組;為輸出量,如人臉檢測矩陣Mat
  • double scaleFactor,表示在前後兩次相繼的掃描中,搜尋視窗的比例係數。預設為1.1即每次搜尋視窗依次擴大10%;一般設定為1.1
  • int minNeighbors,表示構成檢測目標的相鄰矩形的最小個數(預設為3個)。 如果組成檢測目標的小矩形的個數和小於 min_neighbors - 1 都會被排除。 如果min_neighbors 為 0, 則函式不做任何操作就返回所有的被檢候選矩形框, 這種設定值一般用在使用者自定義對檢測結果的組合程式上;
  • int flags,要麼使用預設值,要麼使用CV_HAAR_DO_CANNY_PRUNING,如果設定為CV_HAAR_DO_CANNY_PRUNING,那麼函式將會使用Canny邊緣檢測來排除邊緣過多或過少的區域,因此這些區域通常不會是人臉所在區域;
  • Size minSize,最小尺寸,用來限制得到的目標區域的範圍。
  • Size maxSize,最大尺寸,用來限制得到的目標區域的範圍。
import cv2
import numpy as np
face_xml = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_xml = cv2.CascadeClassifier('haarcascade_eye.xml')
# 載入檔案
# 檔案來源:https://juejin.im/post/5afd25b66fb9a07aa34a775f
img = cv2.imread('timg.jpg')
# 載入圖片
cv2.imshow('src',img)
# 列印圖片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 進行灰色處理
faces = face_xml.detectMultiScale(gray,1.3,5)
# 檢測出圖片的人臉
print('face=',len(faces))
# 列印檢測出了多少個人臉

for (x,y,w,h) in faces:
# 繪製每一個人臉
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    # 給人臉繪製矩形
    roi_face = gray[y:y+h,x:x+w]
    roi_color = img[y:y+h,x:x+w]
    # 識別人臉
    eyes = eye_xml.detectMultiScale(roi_face)
    # 識別眼睛
    print('eye=',len(eyes))
    # 列印檢測出了多少個眼睛
    for (e_x,e_y,e_w,e_h) in eyes:
        cv2.rectangle(roi_color,(e_x,e_y),(e_x+e_w,e_y+e_h),(0,255,0),2)
        # 給眼睛繪製矩形
cv2.imshow('dst',img)
# 列印繪製後圖片
cv2.waitKey(0)
複製程式碼

原圖:

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)
結果:

face= 4
eye= 2
eye= 2
eye= 1
eye= 2
複製程式碼

計算機視覺—人臉識別(Haar特徵+Adaboost分類器)(7)

相關文章