人脸识别三部曲
- 首先看目录结构
- 图像信息采集 采集图片.py
- 模型训练 训练模型.py
- 人脸识别 人脸识别.py
- 效果
首先看目录结构
引用文121本
opencv
│ 采集图片.py
│ 训练模型.py
│ 人脸识别.py
│
└───trainer
│ │ trainer.yml
│
└───data
│ └───00_Wang
│ │ 0_00001.jpg
│ │ 0_00002.jpg
│ │ ...
│
│ └───01_Liu
│ │ 1_00001.jpg
│ │ 1_00001.jpg
│ │ ...
│
图像信息采集 采集图片.py
开始运行时,输入待录入的人脸姓名。 按下s键后,开始录入人脸图像,录入两百张后,结束程序。
import cv2
import shutil
import os
"采集图片.py "
path = "./data/"
file_num = len(os.listdir(path))
name = input('input name:\n')
name_dir = os.path.join(path,str(file_num).zfill(2)+ "_"+name)
if os.path.exists(name_dir): # 存在则清空,不存在则重建
shutil.rmtree(name_dir)
os.makedirs(name_dir)
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
count = 0
while cap.isOpened():
ret, frame = cap.read()
if ret is True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + w), (255, 0, 0))
cv2.imshow('image', frame)
k = cv2.waitKey(1) & 0xFF # 按键判断
if (k == ord('s')): # 保存
count += 1
cv2.imwrite(name_dir + "/" + str(file_num) + "_" + str(count).zfill(5) + ".jpg", gray)
print("success to save " + str(file_num) + "_" + str(count).zfill(5) + ".jpg")
elif count >= 200:
break
elif k == ord(' '): # 退出
break
cap.release()
cv2.destroyAllWindows()
模型训练 训练模型.py
import os
import cv2
import numpy as np
from PIL import Image
" 训练模型.py "
path = "./data/"
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
def get_images_and_labels(path):
image_paths = []
name_dirs = [os.path.join(path, f) for f in os.listdir(path)]
for i in range(0, len(name_dirs) ):
print("name_dirs[{0}] : ".format(i) , name_dirs[i])
image_paths += [os.path.join(name_dirs[i], f) for f in os.listdir(name_dirs[i])]
face_samples = []
ids = []
for image_path in image_paths:
img = Image.open(image_path).convert('L')
img_np = np.array(img, 'uint8')
if os.path.split(image_path)[-1].split(".")[-1] != 'jpg':
continue
id = int((os.path.split(image_path)[-1].split(".")[0])[0])
faces = detector.detectMultiScale(img_np)
for (x, y, w, h) in faces:
face_samples.append(img_np[y:y + h, x:x + w])
ids.append(id)
return face_samples, ids
faces, ids = get_images_and_labels(path)
recognizer.train(faces, np.array(ids))
recognizer.save('trainer/trainer.yml')
人脸识别 人脸识别.py
import cv2
import os
"人脸识别.py "
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
font = cv2.FONT_HERSHEY_SIMPLEX
idnum = 0
cam = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cam.set(6, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
path = "./data/"
names = []
for name in os.listdir(path):
names.append(name.split("_")[1])
print(names)
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.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 < 80:
idum = names[idnum-1]
confidence = "{0}%".format(round(100 - confidence))
else:
idum = "unknown"
confidence = "{0}%".format(round(100 - confidence))
cv2.putText(img, str(idum), (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(1) & 0xFF # 按键判断
if k == ord(' '): # 退出
break
cam.release()
cv2.destroyAllWindows()