1. 程式人生 > >OpenCV3計算機視覺+Python(五)

OpenCV3計算機視覺+Python(五)

haar dem 布爾 色彩 XML 閾值 有意 這就是 功能

人臉檢測和識別

本章將介紹Haar級聯分類器,通過對比分析相鄰圖像區域來判斷給定圖像或子圖像與已知對象是否匹配。本章將考慮如何將多個Haar級聯分類器構成一個層次結構,即一個分類器能識別整體區域(如人臉),而其他的分類器可識別小的區域(眼睛、鼻子和嘴)。

Haar級聯的概念

當談到目標分類和位置跟蹤時,希望精確定位什麽?什麽才是目標的可識別部分?

攝影作品(甚至是來自網絡攝像頭的圖像)可能包含很多令人愉悅的細節。但是,由於燈光、視角、視距、攝像頭抖動以及數字噪聲的變化,圖像細節變得不穩定。人們在分類時不會受這些物理細節方面差異的影響。

提取出圖像的細節對產生穩定分類結果和跟蹤結果很有用。這些提取的結果被稱為特征,專業的表述為:從圖像數據中提取特征。雖然任意像素都可能影響多個特征,但特征應該比像素數少得多。兩個圖像的相似程度可以通過它們對應特征的歐式距離來度量。

例如,距離可能以空間坐標或顏色坐標來定義。類Haar特征是一種用於實現實時人臉跟蹤的特征。文獻《Robust Real-Time Face Detection,Paul Viola and Michael Jones,Kluwer Academic Publishers,2001》首次采用這種特征來進行人臉檢測。每個類Haar特征都描述了相鄰圖像區域的對比模式。例如,邊、頂點和細線都能生成具有判別性的特征。

對給定的圖像,特征可能會因區域大小而有所不同,區域大小也可被稱為窗口大小。即使窗口大小不一樣,僅在尺度上不同的兩幅圖像也應該有相似的特征。因此,能為不同大小的窗口生成特征非常有用。這些特征集合稱為級聯。Haar級聯具有尺度不變性,換句話說,它在尺度變化上具有魯棒性。OpenCV提供了尺度不變Haar級聯的分類器和跟蹤器,並可將其保存成指定的文件格式。

OpenCV的Haar級聯不具有旋轉不變性。例如,Haar級聯不認為倒置的人臉圖像和直立的人臉圖像一樣,而側面的人臉圖像與正面的人臉圖像也不一樣。更可通過多種圖像變換和多種窗口大小來提高Haar級聯的旋轉魯棒性,但這樣會變得很復雜,而且會耗費更多計算資源。

獲取Haar級聯數據

在OpenCV3源代碼的副本中會有一個文件夾data/haarcascades.該文件夾包含了所有OpenCV的人臉檢測的XML文件,並將haarcascades文件夾中的所有文件復制到cascades文件夾中:

haarcascade_profileface.xml

haarcascade_righteye_2splits.xml

haarcascade_russian_plate_number.xml

haarcascade_smile.xml

haarcascade_upperbody.xml

從文件名可知這些級聯是用於人臉、眼睛、鼻子和嘴的跟蹤。這些文件需要正面、直立的人臉圖像。在稍後創建人臉檢測器時會使用這些文件。有了很大的耐心以及強大的計算機,就可以創建自己的級聯,並訓練這些級聯來檢測各種對象。

使用OpenCV進行人臉檢測

在靜態圖像或視頻中檢測人臉的操作非常相似。視頻人臉檢測只是從攝像頭讀出每幀圖像,然後采用靜態圖像中的人臉檢測方法進行檢測。當然,視頻人臉檢測還涉及其他的概念,例如跟蹤,而靜態圖像中的人臉檢測就沒有這樣的概念,但它們基本理論是一致的。

靜態圖像中的人臉檢測

人臉檢測首先是加載圖像並檢測人臉,這也是最基本的一步。為了使所得到的結果有意義,可在原始圖像的人臉周圍繪制矩形框。

現在,項目中已經包含了haarcascades文件夾的內容,下面創建一個基本的腳本來實現人臉檢測。

import cv2
filename=3.jpg
def detect(filename):
    face_cascade=cv2.CascadeClassifier(haarcascade_frontalface_default.xml)
    face_cascade.load(C:/Users/yif/Anaconda3/envs/tensorflow/Lib/site-packages/opencv_python-3.4.0.dist-info/haarcascades/haarcascade_frontalface_default.xml)
    img=cv2.imread(filename)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces=face_cascade.detectMultiScale(gray,1.3,5)
    for (x,y,w,h) in faces:
        img=cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    cv2.namedWindow(Vikings Detected)
    cv2.imshow(Vikings Detected,img)
    cv2.waitKey()

detect(filename)

註意:

face_cascade=cv2.CascadeClassifier(haarcascade_frontalface_default.xml)

face_cascade.load(C:/Users/yif/Anaconda3/envs/tensorflow/Lib/site-packages/opencv_python-3.4.0.dist-info/haarcascades/haarcascade_frontalface_default.xml)

該變量為CascadeClassifier對象

face_cascade.detectMultiScale傳遞參數是scaleFactor和minNeighbors,它們分別表示人臉檢測過程中每次叠代時圖像的壓縮率以及每個人臉矩形保留近鄰數目的最小值。

檢測操作的返回值為人臉矩形數組。函數cv2.rectangle允許通過坐標來繪制矩形(x和y表示左上角的坐標,w和h表示人臉矩形的寬度和高度)

通過依次提取faces變量中的值來找到人臉,並在人臉周圍繪制藍色矩形,這是在原始圖像而不是圖像的灰色版本上進行繪制。


視頻中的人臉檢測

在視頻的幀上重復這個過程就能完成視頻(如攝像頭的輸入或視頻文件)中的人臉檢測。

該腳本將執行以下任務:打開攝像頭,讀取幀,檢測幀中的人臉,掃描檢測到的人臉中的眼睛,對人臉繪制藍色的矩形框,對眼睛繪制綠色的矩形框。

import cv2
def detect():
    face_cascade=cv2.CascadeClassifier(haarcascade_frontalface_default.xml)
    eye_cascade=cv2.CascadeClassifier(haarcascade_eye.xml)
    face_cascade.load(C:/Users/yif/Anaconda3/envs/tensorflow/Lib/site-packages/opencv_python-3.4.0.dist-info/haarcascades/haarcascade_frontalface_default.xml)
    eye_cascade.load(C:/Users/yif/Anaconda3/envs/tensorflow/Lib/site-packages/opencv_python-3.4.0.dist-info/haarcascades/haarcascade_eye.xml)
    camera=cv2.VideoCapture(0)
    while(True):
        ret,frame=camera.read()
        gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        faces=face_cascade.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in faces:
            img=cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)

            roi_gray=gray[y:y+h,x:x+w]
            eyes=eye_cascade.detectMultiScale(roi_gray,1.03,5,0,(40,40))
            for (ex,ey,ew,eh)in eyes:
                cv2.rectangle(img,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
            cv2.imshow("camera",frame)

    camera.release()
    cv2.destroyAllWindows()
if __name__=="__main__":
    detect()

首先用detect函數加載Haar級聯文件,由此可以執行人臉檢測。

然後打開一個VideoCapture目標(初始化攝像頭)。VideoCapture構造函數的參數用來表示要使用的攝像頭

接下來捕獲幀。read()函數會返回兩個值:第一個值為布爾值,用來表明是否成功讀取幀,第二個值為幀本身。捕捉到幀後,將其轉換為灰度圖像。這個操作很有必要。

與靜態圖像的例子一樣,對具有灰度色彩空間的幀調用detectMultiScale

在眼睛檢測中還有另外幾個參數,因為眼睛是在確定了人臉的基礎上,在比較小的圖像上確定眼睛。

同樣用循環輸出檢測眼睛的結果,並在其周圍繪制綠色的矩形框

人臉識別

人臉檢測是OpenCV的一個很不錯的功能,它是人臉識別的基礎。什麽是人臉識別?其實就是一個程序能識別給定圖像或視頻中的人臉。實現這一目標的方法之一(OpenCV也采用這種方法)是用一系列分好類的圖像(人臉數據庫)來訓練程序,並基於這些圖像來進行識別。

這就是OpenCV及其人臉識別模塊進行人臉識別的過程。

人臉識別模塊的另一個重要特征是:每個識別都具有轉置信評分,因此可在實際應用中通過對其設置閾值來進行篩選。

人臉識別所需要的人臉可以通過兩種方式來得到:自己獲得圖像或從人臉數據庫免費獲得可用的人臉圖像

1.生成人臉識別數據

下面繼續介紹生成圖像的腳本。這裏需要一些包含不同表情的圖像,但是,必須確保樣本圖像滿足如下條件:

1)圖像是灰度格式,後綴名為.pgm

2)圖像形狀為正方形

3)圖像大小要一樣

import cv2
def generate():
    face_cascade=cv2.CascadeClassifier(haarcascade_frontalface_default.xml)
    eye_cascade=cv2.CascadeClassifier(haarcascade_eye.xml)
    face_cascade.load(C:/Users/yif/Anaconda3/envs/tensorflow/Lib/site-packages/opencv_python-3.4.0.dist-info/haarcascades/haarcascade_frontalface_default.xml)
    eye_cascade.load(C:/Users/yif/Anaconda3/envs/tensorflow/Lib/site-packages/opencv_python-3.4.0.dist-info/haarcascades/haarcascade_eye.xml)
    camera=cv2.VideoCapture(0)
    count=0
    while(True):
        ret,frame=camera.read()
        gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        faces=face_cascade.detectMultiScale(gray,1.3,5)
        for (x,y,w,h)in faces:
            img=cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)

            f=cv2.resize(gray[y:y+h,x:x+w],(200,200))
            cv2.imwrite(./data/%s.pgm%str(count),f)
            count+=1
        cv2.imshow("camera",frame)
        if (cv2.waitKey(int(1000/12)))&(0xff==ord("q")):
            break
    camera.release()
    cv2.destroyAllWindows()
if __name__=="__main__":
    generate()


2.人臉識別

OpenCV3有三種人臉識別的方法,它們分別基於三種不同的算法:Eigenfaces、Fisherfaces和Local Binary Pattern

OpenCV3計算機視覺+Python(五)