python中使用Opencv進行人臉檢測


這兩天學習了人臉識別,看了學長寫的代碼,邊看邊碼邊理解搞完了一邊,再又是自己靠着理解和記憶硬碼了一邊,感覺還是很生疏,就只能來寫個隨筆加深一下印象了。

關於人臉識別,首先需要了解的是級聯分類器CascadeClassifier,它可以它既可以是Haar特征,也可以是LBP特征的分類器,可以加載OpenCV所提供的庫當中的.xml文件,文件存放在anaconda\pkgs\libopencv-3.4.1-h875b8b8_3\Library\etc的haarcascades文件夾中,包含了許多個.xml文件,分別有不同的用途。而在使用級聯分類器進行人臉檢測時,需要調用 .detectMultiScale 方法,其中的參數為

  img:傳入圖像
  object:被檢測的物體的矩形框向量組
  scaleFactor:表示前后兩次相繼的掃描中,搜索窗口的比例系數。默認為1.1,即每次搜索窗口擴大10%
  minNegihbors,表示構成檢測目標的相鄰矩形的最小個數(默認為3個)
  flags:要么使用默認值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果設置為CV_HAAR_DO_CANNY_PRUNING,那么函數會使用Canny邊緣檢測來排除邊緣過多或者過少的區域,這些通常不會是人臉所在區域
  minSize和maxSize:用來限制得到的目標區域的范圍

其輸出為一個vector矩陣,保存人臉的坐標和大小,需要注意的是,傳入的圖像必須為灰度圖像,因為級聯分類器檢測需要接收灰度圖像。

 

1.首先是靜態圖片中的人臉檢測

這部分並不算難,看着注釋應該也可以看懂,就不多做解釋。

def StaticDetect(filename):
    '''
    靜態圖像的人臉檢測
    '''
    #創建一個級聯分類器,加載一個 .xml文件,它既可以是Haar特征,也可以是LBP特征的分類器
    face_casecade=cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')
    
    #加載圖像
    img=cv2.imread(filename,cv2.IMREAD_COLOR)
    #轉換為灰度圖像
    gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    '''
    detectMultiScale進行人臉檢測
    傳入參數為args:
                    img:傳入圖像
                    object:被檢測的物體的矩形框向量組
                    scaleFactor:表示前后兩次相繼的掃描中,搜索窗口的比例系數。默認為1.1,即每次搜索窗口擴大10%
                    minNegihbors,表示構成檢測目標的相鄰矩形的最小個數(默認為3個)
                    flags:要么使用默認值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果設置為CV_HAAR_DO_CANNY_PRUNING,那么函數會使用Canny邊緣檢測來排除邊緣過多或者過少的區域,這些通常不會是人臉所在區域
                    minSize和maxSize:用來限制得到的目標區域的范圍
    輸出為:vector保存各個人臉的坐標、大小(用矩形表示)
    '''
    faces=face_casecade.detectMultiScale(gray_img,1.2,5)
    for (x,y,w,h) in faces:
        #在原圖上繪制矩形
        img=cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    cv2.namedWindow('Face_Detected')
    cv2.imshow('Face_Detected',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

檢測的結果如下圖,圖片是我從網上隨便找的一張圖,如果有任何侵犯的地方,請及時聯系我,會即刻刪除。我們可以發現結果並不是太好,有許多漏檢,由於是初學則不做過多改正嘗試,可以嘗試修改級聯分類器中的文件以及搜索窗口比例系數來改變檢測准確度。

 

2.動態人臉檢測

這一部分采用了兩個級聯分類器,一個檢測面部,一個檢測眼睛,需要注意的是,眼睛的檢測是在人臉檢測后再進行檢測,即先從大的人臉開始畫出矩形再到眼睛畫出的矩形。檢測眼睛時可以把眼鏡摘下,會准確很多。

def Video_detected():
    '''
    從視頻中進行人臉檢測
    '''
    #創建一個級聯分類器,家在一個  .xml文件它既可以是Haar特征,也可以是LBP特征的分類器
    face_cascade=cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')
    eye_cascade=cv2.CascadeClassifier('./haarcascades/haarcascade_eye.xml')
    
    #打開攝像頭
    camera=cv2.VideoCapture(0)
    cv2.namedWindow('Dynamic')
    
    while(True):
        #讀取一幀圖像   ret
        ret,frame=camera.read()
        #判斷圖片讀取是否成功
        if ret:
            gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
            #人臉檢測
            faces=face_cascade.detectMultiScale(gray_img,1.3,5)
            for (x,y,w,h) in faces:
                #在原圖上繪制矩形
                cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)   #藍色
                roi_gray=gray_img[y:y+h,x:x+w]
                #眼睛檢測
                eyes=eye_cascade.detectMultiScale(roi_gray,1.1,5,0,(40,40))
                for (ex,ey,ew,eh) in eyes:
                    cv2.rectangle(frame,(ex+x,ey+y),(ex+x+ew,ey+y+eh),(0,255,0),2)      #綠色
                
            cv2.imshow('Dynamic',frame)
            #如果按下q鍵則退出
            if cv2.waitKey(10) & 0xff==ord('q'):
                break
    camera.release()
    cv2.destroyAllWindows()

檢測結果如下圖,可以發現對象不多的時候,人臉檢測還是挺准確的,嘗試過后,動態情況下多個人臉也是可以檢測出來的。我們可以發現,在眼睛的檢測中多了幾個參數,這些參數是由於眼睛比較小,並且有鼻子等造成的陰影可能會產生假陽性,因此通過限制檢測的眼睛大小為40*40可以去除假陽性的影響。后續可以嘗試不同的參數的檢測精度,這里就不多做描述。 

這里附上原博客的連接:https://www.cnblogs.com/zyly/p/9410563.html

 

2018.10.28

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM