opencv+python+pycharm實現人臉識別
目錄
前言
前期准備
人臉檢測
樣本采集
樣本訓練
結語
前言
本人本科在校大二學生,編程小菜鳥。近期做了期末課程設計,我選擇的題目就是人臉識別。第一次寫博客,想把做系統的整個過程記錄下來,方便后續使用。我是站在巨人的肩膀上做成人臉識別的,下面是我參考的博客。
https://www.cnblogs.com/xp12345/p/9818435.html(最終參考)
https://blog.csdn.net/WALRE_HUNTER_RICO/article/details/88361212
前期准備
Pycharm(需要安裝一些第三方包)
Opencv340(版本最好不要太高,版本會影響程序運行)
人臉檢測
上代碼來(未知大神的)
import numpy as np
import cv2
# 人臉識別分類器
faceCascade = cv2.CascadeClassifier(r'F:/face_test01/haarcascade_frontalface_default.xml')
# 識別眼睛的分類器
eyeCascade = cv2.CascadeClassifier(r'F:/face_test01/haarcascade_eye.xml')
# 開啟攝像頭
cap = cv2.VideoCapture(0)
ok = True
result = []
while ok:
# 讀取攝像頭中的圖像,ok為是否讀取成功的判斷參數
ok, img = cap.read()
# 轉換成灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 人臉檢測
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(32, 32)
)
# 在檢測人臉的基礎上檢測眼睛
for (x, y, w, h) in faces:
fac_gray = gray[y: (y+h), x: (x+w)]
result = []
eyes = eyeCascade.detectMultiScale(fac_gray, 1.3, 2)
# 眼睛坐標的換算,將相對位置換成絕對位置
for (ex, ey, ew, eh) in eyes:
result.append((x+ex, y+ey, ew, eh))
# 畫矩形
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
for (ex, ey, ew, eh) in result:
cv2.rectangle(img, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)
cv2.imshow('video', img)
k = cv2.waitKey(1)
if k == 27: # press 'ESC' to quit
break
cap.release()
cv2.destroyAllWindows()
注:注意上面兩個分類器的路徑要改成自己文件所在路徑
樣本采集
上代碼!(大神的)
import cv2
import os
# 調用筆記本內置攝像頭,所以參數為0,如果有其他的攝像頭可以調整參數為1,2
cap = cv2.VideoCapture(0)
# CascadeClassifier,是Opencv中做人臉檢測的時候的一個級聯分類器
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_id = input('\n enter user id:')
print('\n Initializing face capture. Look at the camera and wait ...')
count = 0
while True:
# 從攝像頭讀取圖片
sucess, img = cap.read()
# 轉為灰度圖片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 檢測人臉
faces = face_detector.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+w), (255, 0, 0))
count += 1
# 保存圖像
cv2.imwrite("Facedata/User." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])
cv2.imshow('image', img)
# 保持畫面的持續。
k = cv2.waitKey(1)
if k == 27: # 通過esc鍵退出攝像
break
elif count >= 1000: # 得到1000個樣本后退出攝像
break
# 關閉攝像頭
cap.release()
cv2.destroyAllWindows()
注:1.在運行該程序前,請先創建一個Facedata文件夾並和你的程序放在一個文件夾下。
(友情提示:請將程序和文件打包放在一個叫人臉識別的文件夾下。可以把分類器也放入其中。)
2.程序運行過程中,會提示你輸入id,請從0開始輸入,即第一個人的臉的數據id為0,第二個人的臉的數據id為1,運行一次可收集一張人臉的數據。(這個很重要,將會影響到后面人臉識別中人名列表)
3.程序運行時間可能會比較長,可能會有幾分鍾,如果嫌長,可以將1000改為100。
4.關於訓練樣本,我訓練了15000張,三個人。有一個問題還沒弄明白:樣本數量變多(例如訓練兩萬)是,在后面人臉識別時會報錯。
如果實在等不及,可按esc退出,但可能會導致數據不夠模型精度下降。
訓練樣本
上代碼(大神的)
import numpy as np
from PIL import Image
import os
import cv2
# 人臉數據路徑
path = "F:/face_test01/Facedata"
# 使用OpenCV中LBPH算法的方法建立人臉數據模型
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
def getImagesAndLabels(path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # join函數的作用?
faceSamples = []
ids = []
for imagePath in imagePaths:
PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
img_numpy = np.array(PIL_img, 'uint8') # 圖片格式轉換
id = int(os.path.split(imagePath)[-1].split(".")[1])
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)
return faceSamples, ids
print('Training faces. It will take a few seconds. Wait ...')
faces, ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
recognizer.write(r'face_trainer\trainer.yml')
print("{0} faces trained. Exiting Program".format(len(np.unique(ids))))
注:運行該程序前,請在人臉識別文件夾下創建face_trainer文件夾,並修改文件路徑。(1處)
人臉檢測
代碼(大神的)
import cv2
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('face_trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath)
font = cv2.FONT_HERSHEY_SIMPLEX
idnum = 0
names = ['Allen', 'Bob']
cam = cv2.VideoCapture(0)
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(int(minW), int(minH))
)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
idnum, confidence = recognizer.predict(gray[y:y+h, x:x+w])
if confidence < 100:
idnum = names[idnum]
confidence = "{0}%".format(round(100 - confidence))
else:
idnum = "unknown"
confidence = "{0}%".format(round(100 - confidence))
cv2.putText(img, str(idnum), (x+5, y-5), font, 1, (0, 0, 255), 1)
cv2.putText(img, str(confidence), (x+5, y+h-5), font, 1, (0, 0, 0), 1)
cv2.imshow('camera', img)
k = cv2.waitKey(10)
if k == 27:
break
cam.release()
cv2.destroyAllWindows()
注:names列表中存儲人的名字,若該人id為0則他的名字在第一位,id位1則排在第二位,以此類推。另外,這兒很容易出現這個錯誤:

這個問題我想有兩個原因:
1.在前面采集樣本輸入ID時,輸了字母,而不是索引數字(0,1,…)。
2.訓練人數與列表中數量不對應。
結語
總體來說,由於站在巨人的肩膀上,用了網上的開源代碼,並且基本不需要改動,所以做出整個人臉識別系統還是比較容易和快速的。我所做的工作就是針對出現的小問題,例如文件路徑等做些調試。最后真的很感謝網上程序員們,他們無私的分享給我們這些小白撐起了一片天。
————————————————
版權聲明:本文為CSDN博主「csbn60」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/csbn60/article/details/106858652/
