项目概述:
本地摄像头采集人脸数据集,通过训练得到trainingData.yml模型,加载haarcascade_frontalface_default.xml实现人脸识别。haarcascade_frontalface_default.xml
文件并不是一个完整的人脸识别模型,而是一个用于检测正脸(frontal face)的 Haar 特征级联分类器文件。具体来说,这个 XML 文件包含了经过训练的级联分类器,用于在图像中快速定位和识别人脸区域。这种级联分类器主要基于 Haar 特征,通过使用一系列特征模板来区分对象。该分类器主要用于人脸检测任务,识别出输入图像中可能存在的人脸区域。
haarcascade_frontalface_default.xml文件下载地址:
opencv/data/haarcascades/haarcascade_frontalface_default.xml at master · kipr/opencv · GitHub
1、数据采集
使用在线sqlite3(SQL Online Compiler - Next gen SQL Editor)创建数据库。
CREATE TABLE students(
Id int,
Name varchar(20),
age INT
);
'''
数据采集 dataset_creater.py
'''
import cv2
import sqlite3
faceDetect = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 摄像头中面部识别
cam = cv2.VideoCapture(0) # 打开默认的第一个摄像头
def inserttoupdate(Id, Name, age):
conn = sqlite3.connect("sqlite.db")
cmd = "SELECT * FROM STUDENTS WHERE ID=" + str(Id)
cursor = conn.execute(cmd)
isRecordExist = 0
for row in cursor:
isRecordExist = 1
if isRecordExist == 1:
conn.execute("UPDATE STUDENTS SET NAME =?,AGE=? WHERE ID=?", (Name, age, Id))
else:
conn.execute("INSERT INTO STUDENTS (ID,NAME,AGE) VALUES (?,?,?)", (Id, Name, age))
conn.commit()
conn.close()
# 向sqlite3数据库中插入数据
Id = input('输入用户的ID:')
Name = input('输入用户的姓名:')
age = input('输入用户的年龄')
inserttoupdate(Id, Name, age)
sampleNum = 0 # 假设数据集中没有样本
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceDetect.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
sampleNum = sampleNum + 1 # 如果检测到了人脸+1
cv2.imwrite("dataset/User." + str(Id) + "." + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.waitKey(100)
cv2.namedWindow('Face', cv2.WINDOW_NORMAL)
cv2.imshow('Face', img) # 显示网络摄像头中检测到的面孔
if cv2.waitKey(5) & 0xFF == 27: # 按ESC退出
break
cam.release()
cv2.destroyAllWindows()
2、数据训练
'''
数据训练 trainer.py
'''
import os
import cv2
import numpy as np
from PIL import Image
recognizer = cv2.face.LBPHFaceRecognizer_create() # 创建 LBPH 人脸识别器
path = "dataset"
def getImagesWithID(path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # 获取图像路径
faces = []
IDs = []
for imagePath in imagePaths:
faceImg = Image.open(imagePath).convert('L') # 打开并转换为灰度图像
faceNp = np.array(faceImg, 'uint8')
ID = int(os.path.split(imagePath)[-1].split(".")[1]) # 从文件名中提取ID
print(ID)
faces.append(faceNp)
IDs.append(ID)
cv2.imshow("Training", faceNp) # 在窗口中显示训练图像
cv2.waitKey(100)
return np.array(IDs), faces
Ids, faces = getImagesWithID(path)
recognizer.train(faces, Ids) # 使用图像数据进行训绋
recognizer.save('recognizer/trainingData.yml') # 保存训练好的模型
cv2.destroyAllWindows() # 关闭所有 OpenCV 窗口
运行以上代码中如果出现以下错误:
AttributeError: module 'cv2' has no attribute 'face'
可以重新 pip install opencv-contrib-python
3、人脸分析
'''
人脸分析 detect.py
'''
import cv2
import sqlite3
facedetector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cam = cv2.VideoCapture(0)
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('recognizer/trainingData.yml')
def getprofile(id):
conn = sqlite3.connect("sqlite.db")
cmd = "SELECT * FROM STUDENTS WHERE ID=" + str(id)
cursor = conn.execute(cmd)
profile = None
for row in cursor:
profile = row
conn.close()
return profile
id = 0
while True:
ret, im = cam.read() # 从摄像头捕获一帧图像,ret 表示是否成功读取帧,im 是捕获的图像。
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
faces = facedetector.detectMultiScale(gray, 1.2, 5)
for (x, y, w, h) in faces:
cv2.rectangle(im, (x, y), (x + w, y + h), (225, 0, 0), 2)
id, conf = recognizer.predict(gray[y:y + h, x:x + w])
profile = getprofile(id)
print(profile)
if profile is not None:
cv2.putText(im, "Name:" + str(profile[1]), (x, y + h + 20), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 127), 2)
cv2.putText(im, "Age:" + str(profile[2]), (x, y + h + 45), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 255), 2)
cv2.imshow('Face', im)
if cv2.waitKey(5) & 0xFF == 27: # 按ESC退出
break
cam.release()
cv2.destroyAllWindows()
在人脸识别代码中:
facedetector
是使用的人脸检测器对象,通常是一个基于 Haar 特征的级联分类器。在这段代码中,facedetector
是通过加载名为 'haarcascade_frontalface_default.xml' 的 XML 文件创建的。该 XML 文件包含了训练好的模型,用于检测图像中的人脸。具体来说,这个级联分类器可以根据预先训练好的数据集,通过对输入图像进行特征匹配和分类来识别出人脸。detectMultiScale()
方法用于在图像中检测多个尺度的目标(在这种情况下是人脸)。在 detectMultiScale()
方法中,传入的参数包括灰度图像、每次缩小图像的尺寸比例因子以及定义人脸大小的参数。这个方法会返回检测到的人脸区域的坐标和尺寸,以便后续对每个人脸区域进行识别和处理。总之,facedetector
对象是用于检测输入图像中人脸的重要组件,通过使用 Haar 特征和级联分类器技术,在实时视频流中定位并识别人脸。recognizer.predict()
方法返回两值:识别出的人脸 ID 和与该 ID 相关的置信度(confidence)。
-
Person ID:
-
这是表示识别出的人脸属于哪个个体的标识符。
-
在训练期间,每个被识别的人脸都会分配一个唯一的 ID。
-
通过这个 ID,可以在数据库中查找对应的个人信息。
-
-
Confidence (置信度):
-
置信度是指识别系统对预测结果的自信程度或确定性水平。
-
通常用数值来表示,越低表示系统认为识别可能不太可靠,而较高的值则表示系统更有信心认为识别结果准确。
-
对于人脸识别系统,置信度越低表示系统对于该识别结果的可靠性存在疑问。
-
因此,recognizer.predict()
返回的两个值可以帮助我们了解识别出的人脸属于哪个个体,并提供了一个指标来评估系统对该识别结果的确定程度。
最后识别结果: