人脸采集训练识别

发布于:2024-05-07 ⋅ 阅读:(29) ⋅ 点赞:(0)

项目概述:

       本地摄像头采集人脸数据集,通过训练得到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)。

  1. Person ID:

    • 这是表示识别出的人脸属于哪个个体的标识符。

    • 在训练期间,每个被识别的人脸都会分配一个唯一的 ID。

    • 通过这个 ID,可以在数据库中查找对应的个人信息。

  2. Confidence (置信度):

    • 置信度是指识别系统对预测结果的自信程度或确定性水平。

    • 通常用数值来表示,越低表示系统认为识别可能不太可靠,而较高的值则表示系统更有信心认为识别结果准确。

    • 对于人脸识别系统,置信度越低表示系统对于该识别结果的可靠性存在疑问。

因此,recognizer.predict() 返回的两个值可以帮助我们了解识别出的人脸属于哪个个体,并提供了一个指标来评估系统对该识别结果的确定程度。

最后识别结果: