前言:因为我要做选修课的关于ai的项目,所以整个代码其实是摘录自hwtl0703598这个csdn博客主的python人脸识别源码,不过也在调试的过程过发现了那位博客主的一些代码的问题,并改善了,我会在整篇文章后端指出改正,基本上是可以配好环境后直接使用。
简要概述之LBPH是什么?
LBPH(Local Binary PatternsHistograms)局部二进制编码直方图,建立在LBPH基础之上的人脸识别法基本思想如下:首先以每个像素为中心,判断与周围像素灰度值大小关系,对其进行二进制编码,从而获得整幅图像的LBP编码图像;再将LBP图像分为个区域,获取每个区域的LBP编码直方图,继而得到整幅图像的LBP编码直方图,通过比较不同人脸图像LBP编码直方图达到人脸识别的目的,其优点是不会受到光照、缩放、旋转和平移的影响。
PS:OpenCV提供了三种人脸识别的方法,分别是LBPH方法、EigenFishfaces方法、Fisherfaces方法。
为什么要使用LBPH而不是其他?
LBPH:将检测到的人脸分为小单元, 并将其与模型中的对应单元进行比较, 对每个区域的匹配值产生一个直方图。 由于这种方法的灵活性, LBPH是唯一允许模型样本人脸和检测到的人脸在形状、 大小上可以不同的人脸识别算法。
人脸识别的步骤
准备工作:
人脸录入流程:
- step1:利用opencv的VideoCapture函数打开摄像头并获取视频流。
- step2:获取视频流的每一帧的图像,将图像转成灰度图,在图像上利用opencv人脸检测器去检测人脸,并在人脸上画个框,保存框里面的人脸的图像到自己选定的图像文件夹,保存200张左右,实际是训练越多,识别的成功率也越高。
- step3:最后保存完200张图像,程序自动结束,释放摄像头缓存并关闭窗口。
PS:每张人脸需要转成灰度图,图像灰度化的目的是为了简化矩阵,提高运算速度,这里是提高识别效率。
人脸录入完整代码
import cv2
cap = cv2.VideoCapture(0)
face_detector = cv2.CascadeClassifier('D:/opencv\sources/data/haarcascades/haarcascade_frontalface_default.xml')
face_id = input('User data input,Look at the camera and wait ...')
count = 0
while cap.isOpened():
ret, frame = cap.read()
if ret is True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
else:
break
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))
count += 1
cv2.imwrite("D:/opencv_test/" + str(face_id) + '.' + str(count) + '.jpg', gray[y:y + h, x:x + w])
cv2.imshow('image', frame)
k = cv2.waitKey(1)
if k == 27:
break
elif count >= 200:
break
cap.release()
cv2.destroyAllWindows()
代码解析:
效果展示1
效果展示2
人脸数据集训练流程
- step1:给出保存好的人脸图像文件夹的路径,遍历该路径下所有的图片,通过os函数,导入图片的名字和图像进face_samples和ids两个list数组,图片通过numpy中的array函数转成数组。
- step2:调用LBPH人脸识别器,将图像数组和对应的图像名进行训练,并将结果保存到trainer/trainer.yml这个文件下。
人脸训练完整代码
import os
import cv2
import numpy as np
from PIL import Image
path = 'D:/opencv_test/'
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier('D:/opencv\sources/data/haarcascades/haarcascade_frontalface_default.xml')
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:
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])
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')
代码解析:
人脸识别流程:
人脸识别完整代码
import cv2
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
face_cascade = cv2.CascadeClassifier("D:/opencv\sources/data/haarcascades/haarcascade_frontalface_default.xml")
font = cv2.FONT_HERSHEY_SIMPLEX
idnum = 0
cam = cv2.VideoCapture(0)
cam.set(6, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
names = ['linluocheng','zhupengcheng']
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]
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(10)
if k == 27:
break
cam.release()
cv2.destroyAllWindows()
代码解析:
效果展示图 1
效果展示图2