最簡單的python 人臉檢測

本篇文章是最基本的人臉檢測,沒有複雜的算法,只是簡單的運用了這三個庫opencv,numpy,pillow。

 

一.開發環境搭建
我們使用Python自帶的IDLE進行編程,我使用的電腦是Windows系統,代碼在win7 64位,win10 64位這兩種電腦上驗證過。Python版本爲3.xx,需要使用的庫有opencv,numpy,pillow。這三個庫分別使用pip按照即可,指令分別爲;
1)opencv;pip install opencv-python
2)numpy;pip install numpy
3)pillow;pip install pillow

所有的文件夾

face_pic  存檔獲取的照片

轉爲灰度圖片

本文的路徑採用自動獲取絕對路徑

 

在Python的安裝目錄,按照這個路徑依次打開文件夾Lib→site-packages→cv2→data,複製文件“haarcascade_frontalface_default.xml”,“haarcascade_frontalcatface.xml”到face_identity文件夾,這兩個是分類器,用於進行人臉檢測。

然後放到我們準備新建的文件夾中,這裏我已經整好了,

 


 

注意 

如果提示“module' object has no attribute 'face'”

解決方法:可以輸入 pip install opencv-contrib-python解決,如果提示需要commission,可以在後面加上 --user,即 pip install opencv-contrib-python --user

 

廢話不多說,上代碼

'''
本程序用於產生800張灰度圖片素材用於後續訓練人臉識別系統
'''

#-----獲取人臉樣本-----
import cv2
import os
#調用筆記本內置攝像頭,參數爲0,如果有其他的攝像頭可以調整參數爲1,2
cap = cv2.VideoCapture(0)
#調用人臉分類器,獲取絕對路徑
face_xml_location=os.path.join('.','haarcascade_frontalface_default.xml')
face_detector = cv2.CascadeClassifier(face_xml_location)

#爲即將錄入的臉標記一個id
face_id = input('\n User data input,Look at the camera and wait ...')
#sampleNum用來計數樣本數目
count = 0

while True:    
    #從攝像頭讀取圖片
    success,img = cap.read()    
    #轉爲灰度圖片,減少程序符合,提高識別度
    if success is True: 
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
    else:   
        break
    #檢測人臉,將每一幀攝像頭記錄的數據帶入OpenCv中,讓Classifier判斷人臉
    #其中gray爲要檢測的灰度圖像,1.3爲每次圖像尺寸減小的比例,5爲minNeighbors
    faces = face_detector.detectMultiScale(gray, 1.3, 5)

    #框選人臉,for循環保證一個能檢測的實時動態視頻流
    for (x, y, w, h) in faces:
        #xy爲左上角的座標,w爲寬,h爲高,用rectangle爲人臉標記畫框
        cv2.rectangle(img, (x, y), (x+w, y+w), (255, 0, 0))
        #成功框選則樣本數增加
        count += 1  
        #保存圖像,把灰度圖片看成二維數組來檢測人臉區域
        #(這裏是建立了data的文件夾,當然也可以設置爲其他路徑或者調用數據庫)
        cv2.imwrite("face_pic/User."+str(face_id)+'.'+str(count)+'.jpg',gray[y:y+h,x:x+w]) 
        #顯示圖片
        cv2.imshow('image',img)       
        #保持畫面的連續。waitkey方法可以綁定按鍵保證畫面的收放,通過q鍵退出攝像
    k = cv2.waitKey(1)        
    if k == '27':
        break        
        #或者得到800個樣本後退出攝像,這裏可以根據實際情況修改數據量,實際測試後800張的效果是比較理想的
    elif count >= 50:
        break

#關閉攝像頭,釋放資源
cap.realease()
cv2.destroyAllWindows()

ID用來標示不同人的模型照片

爲了方便也可以修改不同的文件夾

經過我的思考決定還是放上照片吧

 

接下來最重要的一步來了

開始模型的分析建立

import cv2
import os
import numpy as np
from PIL import Image
#導入pillow庫,用於處理圖像
#設置之前收集好的數據文件路徑
#獲取分類器的路徑
face_xml_location=os.path.join('.','haarcascade_frontalface_default.xml')
print('',face_xml_location)
#調用熟悉的人臉分類器
detector = cv2.CascadeClassifier(face_xml_location)
#初始化識別的方法
recognizer = cv2.face.LBPHFaceRecognizer_create()
#創建一個函數,用於從數據集文件夾中獲取訓練圖片,並獲取id
#注意圖片的命名格式爲User.id.sampleNum

def get_images_and_labels(path):
    image_paths = [os.path.join(path, f) for f in os.listdir(path)]
    #新建連個list用於存放
    face_samples = []
    ids = []
#遍歷圖片路徑,導入圖片和id添加到list中
    for image_path in image_paths:
        #通過圖片路徑將其轉換爲灰度圖片
        image = Image.open(image_path).convert('L')
        #將圖片轉化爲數組
        image_np = np.array(image, 'uint8')
        if os.path.split(image_path)[-1].split(".")[-1] != 'jpg':
            continue
        #爲了獲取id,將圖片和路徑分裂並獲取
        image_id = int(os.path.split(image_path)[-1].split(".")[1])
        faces = detector.detectMultiScale(image_np)
        #將獲取的圖片和id添加到list中
        for (x, y, w, h) in faces:
            face_samples.append(image_np[y:y + h, x:x + w])
            ids.append(image_id)
            print('',image_id)
    return face_samples, ids
#調用函數並將數據餵給識別器訓練
print('Training...')

tain_data_location=os.path.join('.','train_data','train.yml')
face_data_location=os.path.join('.','face_pic')
faces, Ids = get_images_and_labels(face_data_location)
#訓練模型
recognizer.train(faces, np.array(Ids))
recognizer.save(tain_data_location)

 根據分類器解析  獲取的模型信息倍存放在

 

 

最後是我們的人臉檢測代碼

 

import cv2
import numpy as np
import os
#準備好識別方法
recognizer = cv2.face.LBPHFaceRecognizer_create()
#使用之前訓練好的模型
train_data_location=os.path.join('.','train_data','train.yml')
recognizer.read(train_data_location)
#再次調用人臉分類器
face_xml_location=os.path.join('.','haarcascade_frontalface_default.xml')
face_cascade = cv2.CascadeClassifier(face_xml_location)
#加載一個字體,用於識別後,在圖片上標註出對象的名字
font = cv2.FONT_HERSHEY_SIMPLEX
#打開攝像頭
camera = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX

while True:
    ret, im = camera.read()
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    #識別人臉
    faces = face_cascade.detectMultiScale(gray, 1.2, 5)
    #校驗
    for (x, y, w, h) in faces:
        cv2.rectangle(im, (x - 50, y - 50), (x + w + 50, y + h + 50), (225, 0, 0), 2)
        img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
        #計算出結果
        if confidence < 40:
            print('',img_id)
            if img_id == 1:
                img_id = 'wei'
                confidence = "{0}%",format(round(100-confidence))
            elif img_id == 2:
                img_id = '2'
                confidence = "{0}%",format(round(100-confidence))
        else:
            img_id = "Unknown"
            #輸出結果和用戶名
        cv2.putText(im, str(img_id), (x, y + h), font, 1, (0, 255, 0), 1)
        cv2.putText(im,str(confidence),(x+50,y+h-50),font,2,(255,0,0),1)
        #圖片顯示
    cv2.imshow('im', im)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break
#釋放資源
camera.release()
cv2.destroyAllWindows()

confidence是置信度,就是預測這個頭像爲用戶id的可信度爲conf%

越小越精確

 

識別不到我們的訓練模型太少了

加到300個照片  開始訓練

牛逼  

 

 

再來一次 800個模型  置信度<30

 

我曹  達不到30以下  對此我還拿了手機補光,可求刺眼

最後 

import cv2
import numpy as np
import os
#準備好識別方法
recognizer = cv2.face.LBPHFaceRecognizer_create()
#使用之前訓練好的模型
train_data_location=os.path.join('.','train_data','train.yml')
recognizer.read(train_data_location)
#再次調用人臉分類器
face_xml_location=os.path.join('.','haarcascade_frontalface_default.xml')
face_cascade = cv2.CascadeClassifier(face_xml_location)
#加載一個字體,用於識別後,在圖片上標註出對象的名字
font = cv2.FONT_HERSHEY_SIMPLEX
#打開攝像頭
camera = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX

while True:
    ret, im = camera.read()
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    #識別人臉
    faces = face_cascade.detectMultiScale(gray, 1.2, 5)
    #校驗
    for (x, y, w, h) in faces:
        cv2.rectangle(im, (x - 50, y - 50), (x + w + 50, y + h + 50), (225, 0, 0), 2)
        img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
        #計算出結果
        if confidence < 40:
            print('',img_id)
            if img_id == 1:
                img_id = 'wei'
                confidence = "{zhixindu}%",format(round(100-confidence))
            elif img_id == 2:
                img_id = '2'
                confidence = "{0}%",format(round(100-confidence))
        else:
            img_id = "Unknown"
            #輸出結果和用戶名
        cv2.putText(im, str(img_id), (x, y + h), font, 1, (0, 255, 0), 1)
        cv2.putText(im,str(confidence),(x+50,y+h-50),font,2,(255,0,0),1)
        #圖片顯示
    cv2.imshow('im', im)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break
#釋放資源
camera.release()
cv2.destroyAllWindows()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章