一、資料收集
import cv2
cap = cv2.VideoCapture(0)
face_detector = cv2.CascadeClassifier('bbb.xml')
face_id = input('為當前人物輸入一個整數id:') # id號用于標識同一個人,并用于生成圖片名,
print('準備進行人臉捕獲,請面對攝像頭,捕獲完成會自動關閉視窗,請等待...')
count = 0 # 這個變數用于生成遞增的檔案名
while True:
ok, img = cap.read() # 從攝像頭讀取圖片,成功則回傳圖片給變數img,同時回傳成功標記給變數ok
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉為灰度圖片
faces = face_detector.detectMultiScale(gray, 1.3, 5) # 檢測圖中人臉,周邊特征點設為5,以增加準確率
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0,0,255),4)
count += 1 # 數字遞增,用于下面的檔案命名
# 下行,保存影像到指定目錄,檔案名為數字遞增,最末的gray[…]是在灰度圖中“只要臉”,此外注意一下斜線/有些機子可能是\
cv2.imwrite("Facedata/User." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])
cv2.imshow('ceshi', img)
k = cv2.waitKey(1)
if k == 27: # 按下esc鍵退出攝像
break
elif count >= 100: # 得到400張樣本照片后退出拍攝,經測驗是至少要四百張圖片,才能有較高的正確識別率
break
cap.release() #關攝像頭,釋放資源
cv2.destroyAllWindows() #關視窗,釋放資源
二、機器訓練
import numpy as np
from PIL import Image
import os
import cv2
path = 'Facedata'# 人臉圖片保存的路徑
recognizer = cv2.face.LBPHFaceRecognizer_create() # 呼叫LBPH識別器
detector = cv2.CascadeClassifier("bbb.xml")# 呼叫分類器
def getImagesAndLabels(path): # 自定義的函式,傳入的引數是圖片檔案夾
imagePaths = [os.path.join(path, f) for f in os.listdir(path)]#獲取每張圖片的完整名稱,形成串列
faceSamples = [] # 空串列,準備獲取臉部特征
ids = [] # 空串列,準備獲取人的ID號
for imagePath in imagePaths: #在檔案名串列中回圈
PIL_img = Image.open(imagePath).convert('L') #用pillow打開圖片,引數L表示轉換為矩陣
img_numpy = np.array(PIL_img, 'uint8') # 將圖片資料處理為8位整數灰度值,并用np處理成數值矩陣
id = int(os.path.split(imagePath)[-1].split(".")[1]) #用英文句號切分檔案名,從中取出人的id號
faces = detector.detectMultiScale(img_numpy)# 獲取圖片中的人臉
for (x, y, w, h) in faces:
faceSamples.append(img_numpy[y:y + h, x: x + w]) #將人臉加入臉部特征串列
ids.append(id) #將id號加入所有id的串列
return faceSamples, ids #回傳臉部特征與所有id串列
print('正在對人臉進行學習,需要一定的時間,請等待 ...')
faces, ids = getImagesAndLabels(path)# 呼叫自定義的函式,獲取所有人的臉部特征與id串列
recognizer.train(faces, np.array(ids)) # 這里才是機器學習,對臉部特征與關聯的id號進行處理
recognizer.write(r'face_trainer/trainer.yml')#將學習結果保存為yml文本。提醒一下,這地方的/線,某些機子上是\線
print("{0} 張臉的訓練與學習完畢, 程式結束。".format(len(np.unique(ids))))#列印出id的數量
三、視頻識別標注
import cv2
識別器 = cv2.face.LBPHFaceRecognizer_create()
識別器.read('face_trainer/trainer.yml') # 讀取機器學習與訓練之后的結果,內容是每個id的特征
人臉特征 = cv2.CascadeClassifier("bbb.xml")
默認字體 = cv2.FONT_HERSHEY_SIMPLEX
人名串列 = ['xu','wang','lei','zhang'] # 按采集時的id順序,填寫人名,訓練了幾人這里就寫幾人
攝像頭 = cv2.VideoCapture(0)
while True:
ok, img = 攝像頭.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = 人臉特征.detectMultiScale(gray,1.2, 5)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
id號, 置信度 = 識別器.predict(gray[y:y+h, x:x+w]) # 回傳人名id號,以及置信度
if 置信度 < 100:
人名 = 人名串列[id號] # 從人名串列中,取得id號對應的人名
相似度 = "{0}%".format(round(100 - 置信度))# 相似度的計算,是用100減去置信度
else:
人名 = "unknown"
相似度 = "{0}%".format(round(100 - 置信度))
cv2.putText(img, str(人名), (x+5, y-5), 默認字體, 1, (0,255,0), 4)
cv2.putText(img, str(相似度), (x+5, y+h-5), 默認字體, 1, (0, 0, 255), 2)
cv2.imshow('camera', img)
k = cv2.waitKey(10)
if k == 27: # 必須按下ESC鍵才能關閉視窗,否則持續死回圈,程式不會結束
break
攝像頭.release()
cv2.destroyAllWindows()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/283136.html
上一篇:python找不到編譯器
