想要能人臉識別,咱們須要訓練一個識別器處理。訓練的話就須要以前已經標註好的訓練集,在前一篇文章中,咱們建立了一個已經標註好的訓練集。如今,是時候用這個訓練集來訓練一我的臉識別器了。固然,是用OpenCV Python。python
首先,咱們在(前一篇文章的)同目錄下建立一個叫Python文件,名爲trainner.py,用於編寫數據集生成腳本。同目錄下,建立一個文件夾,名爲trainner,用於存放咱們訓練後的識別器。數組
如今,項目目錄大概如此:app
其餘亂七八糟的文件、目錄,都是以前的文章中建立的。函數
在開始以前,咱們先安裝一個Python庫,Pillow:優化
pip install pillow
編寫訓練程序須要先作是:ui
其實就是這樣:spa
import cv2 import os import numpy as np from PIL import Image
如今咱們初始化識別器和人臉檢測器:code
recognizer = cv2.face.LBPHFaceRecognizer_create() # 有多是 recognizer = cv2.createLBPHFaceRecognizer() detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
若是face.LBPHFaceRecognizer_create或createLBPHFaceRecognizer顯示不存在,則須要下載opencv-contrib-python:xml
pip install opencv-contrib-python
固然用IDE的也行:圖片
恩,如今咱們來建立一個函數,用於從數據集文件夾中獲取訓練圖片,而後從圖片的文件名中獲取到這個素材相應的id。須要remind的是,根據前文,圖片的格式是User.id.samplenumber
。
給函數起個名字,就叫get_images_and_labels吧(Python不建議用駝峯),而後參數須要有素材的文件夾:
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') image_id = int(os.path.split(image_path)[-1].split(".")[1]) faces = detector.detectMultiScale(image_np) for (x, y, w, h) in faces: face_samples.append(image_np[y:y + h, x:x + w]) ids.append(image_id)
以上代碼,使用了Image.open(image_path).convert(‘L’)
經過圖片路徑並將其轉換爲灰度圖片。
接下來咱們經過image_np = np.array(image, 'uint8')
將圖片轉換成了Numpy數組,Numpy數組的邏輯結構和普通的數組無異,可是是通過優化的。
爲了獲取到id,咱們將圖片的路徑分裂一下並獲取相關信息,即image_id = int(os.path.split(image_path)[-1].split(".")[1])
接下來的一個循環for (x, y, w, h) in faces
則是將圖片和id都添加在list中。
再return一下便可。
差很少完成了,如今咱們調用一下這個函數,而後將咱們的數據餵給識別器去訓練吧。
faces, Ids = get_images_and_labels('dataSet') recognizer.train(faces, np.array(Ids)) recognizer.save('trainner/trainner.yml')
如今只要咱們運行這些代碼,程序就會在trainner文件夾中建立一個trainner.yml文件。
這個yml文件,存着咱們的訓練好的數據,之後識別會用到的。
import cv2 import os import numpy as np from PIL import Image # recognizer = cv2.createLBPHFaceRecognizer() detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") recognizer = cv2.face.LBPHFaceRecognizer_create() def get_images_and_labels(path): image_paths = [os.path.join(path, f) for f in os.listdir(path)] face_samples = [] ids = [] 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 image_id = int(os.path.split(image_path)[-1].split(".")[1]) faces = detector.detectMultiScale(image_np) for (x, y, w, h) in faces: face_samples.append(image_np[y:y + h, x:x + w]) ids.append(image_id) return face_samples, ids faces, Ids = get_images_and_labels('dataSet') recognizer.train(faces, np.array(Ids)) recognizer.save('trainner/trainner.yml')
先這樣吧