项目概述:
本地摄像头采集人脸数据集,通过训练得到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 cv2import sqlite3faceDetect = 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 = 0for row in cursor:isRecordExist = 1if 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 # 如果检测到了人脸+1cv2.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退出breakcam.release()cv2.destroyAllWindows()
2、数据训练
'''数据训练 trainer.py'''import osimport cv2import numpy as npfrom PIL import Imagerecognizer = 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]) # 从文件名中提取IDprint(ID)faces.append(faceNp)IDs.append(ID)cv2.imshow("Training", faceNp) # 在窗口中显示训练图像cv2.waitKey(100)return np.array(IDs), facesIds, 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 cv2import sqlite3facedetector = 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 = Nonefor row in cursor:profile = rowconn.close()return profileid = 0while 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退出breakcam.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()
返回的两个值可以帮助我们了解识别出的人脸属于哪个个体,并提供了一个指标来评估系统对该识别结果的确定程度。
最后识别结果: