Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别
目录
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别
一、简单介绍
二、简单进行人脸训练与识别
1、LBPH(Local Binary Patterns Histograms)算法进行人脸训练和识别
2、实现步骤:
3、判断是谁的人脸:
案例中涉及的关键函数说明如下
1)准备训练数据集:load_training_data(data_dir)
2)预处理图像:preprocess_images(faces)
3)训练 LBPH 人脸识别器:train_lbph(faces, labels)
4)读取测试图像:load_test_image(image_path)
5)预处理测试图像:preprocess_test_image(test_image)
6)进行人脸识别:recognize_face(model, test_image)
7)测试人脸识别器:test_face_recognition(data_dir, test_image_path)
三、简单进行人脸训练与识别案例实现简单步骤
四、注意事项
一、简单介绍
Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。
这里使用 Python 基于 OpenCV 进行视觉图像处理,......
OpenCV 提供了一些已经训练好的级联分类器,这些级联分类器以XML文件的方式保存在以下路径中:
...\Python\Lib\site-packages\cv2\data\
OpenCV提供了一些经过预训练的人脸检测器模型文件,这些文件通常包含在OpenCV的安装包中。你也可以在OpenCV的官方GitHub页面或者OpenCV官方网站的下载页面找到这些模型文件的下载链接。
一般来说,你可以从以下位置获取OpenCV的预训练模型文件:
- OpenCV GitHub Release 页面:在 Releases · opencv/opencv · GitHub 找到你需要的版本,然后在下载的压缩包中找到位于 opencv\data 目录下的人脸检测器模型文件。
- OpenCV 官方网站下载页面:访问 OpenCV 官方网站 Releases - OpenCV ,下载你需要的版本,并在相应的压缩包中查找人脸检测器模型文件。
请确保下载与你使用的OpenCV版本兼容的模型文件。
该案例效果
二、简单进行人脸训练与识别
人脸识别是一种生物特征识别技术,旨在识别和验证人类面部的身份。它利用计算机视觉和模式识别技术来识别人脸图像中的关键特征,并将其与事先存储的人脸模板或数据库中的其他人脸进行比较,以确定是否匹配。人脸识别技术通常包括以下步骤:
人脸检测:首先从图像或视频中检测出人脸的位置,通常使用级联分类器、深度学习模型或其他检测算法来实现。
人脸对齐:将检测到的人脸图像对齐,确保它们具有相似的尺寸、姿态和位置。这一步有助于提高后续特征提取的准确性。
特征提取:从对齐后的人脸图像中提取关键特征,例如人脸的轮廓、眼睛、鼻子、嘴巴等。常用的特征提取方法包括主成分分析(PCA)、局部二值模式(LBP)、深度神经网络等。
特征匹配:将提取的特征与事先存储的人脸模板或数据库中的其他人脸特征进行比较,并计算它们之间的相似度或距离。通常采用的方法包括欧氏距离、余弦相似度等。
决策阶段:根据特征匹配的结果,决定是否识别为已知身份。这一阶段通常会设置一个阈值来判断匹配结果的可信度,如果相似度超过阈值,则识别为已知身份;否则,识别为未知身份或拒绝识别。
人脸识别技术在安全门禁、支付验证、监控系统、社交媒体标记等领域有着广泛的应用。
1、LBPH(Local Binary Patterns Histograms)算法进行人脸训练和识别
LBPH(Local Binary Patterns Histograms)算法是一种用于人脸识别的经典算法,它结合了局部二值模式(Local Binary Patterns,LBP)和直方图统计的技术。下面详细介绍LBPH算法的原理、实现步骤以及判断是谁的人脸的过程:
局部二值模式(LBP):
- LBP 是一种用于纹理分析的特征描述方法。它通过比较像素点与其邻域像素的灰度值来描述图像的局部纹理特征。将每个像素与其邻域像素进行比较,并根据比较结果得到一个二进制数值,将这个数值作为该像素的特征描述。LBP 算法可以有效地捕获图像的纹理信息。
直方图统计:
- 在 LBP 算法的基础上,LBPH 算法将每个图像分割成多个局部区域,并计算每个局部区域的 LBP 特征直方图。这些直方图描述了每个局部区域的纹理分布情况,从而将图像的纹理信息转化为了直方图的形式。
人脸识别:
- 对于训练数据集中的每张人脸图像,LBPH 算法首先提取其局部纹理特征,并计算每个局部区域的 LBP 特征直方图。然后,利用这些直方图作为特征向量进行训练。在识别阶段,LBPH 算法对输入的测试图像进行同样的处理,提取其局部纹理特征,并计算每个局部区域的 LBP 特征直方图。接着,通过比较测试图像的特征向量与训练集中已知人脸的特征向量,利用一定的分类算法(如K最近邻算法)进行匹配和判别,从而确定测试图像属于哪个人。
2、实现步骤:
准备训练数据集:
- 收集包含多个人脸图像的数据集,并为每张图像标注对应的人物标签。
提取局部纹理特征:
- 对于每张人脸图像,利用 LBP 算法提取其局部纹理特征,得到每个局部区域的 LBP 特征描述。
构建特征向量:
- 将每个局部区域的 LBP 特征直方图组合成一个完整的特征向量,作为该图像的特征描述。
训练模型:
- 利用训练数据集中的特征向量,通过一定的机器学习算法(如K最近邻算法、支持向量机等)训练模型,得到人脸识别模型。
人脸识别:
- 对于新的测试图像,同样提取其局部纹理特征,并计算每个局部区域的 LBP 特征直方图。然后,利用训练好的模型对测试图像的特征向量进行匹配和判别,确定其所属的人物标签。
3、判断是谁的人脸:
训练模型:
- 在训练阶段,LBPH 算法利用已知的人脸图像数据集,构建了一个能够将人脸图像特征与对应人物标签关联起来的模型。
测试识别:
- 在识别阶段,LBPH 算法对输入的测试图像提取特征,并利用训练好的模型对其进行匹配和判别。根据匹配结果,确定测试图像属于哪个已知的人物标签。
置信度评估:
- LBPH 算法通常会返回识别结果的置信度(confidence)值,用于评估识别的准确度。较高的置信度值表示模型对于当前图像的识别结果较为自信,而较低的置信度值可能表示模型对于当前图像的识别困难程度较大。
案例中涉及的关键函数说明如下
1)准备训练数据集:load_training_data(data_dir)
参数:
data_dir
(字符串):包含训练图像的目录路径。功能: 该函数用于加载训练数据集。它遍历指定目录下的图像文件,并将每个图像转换为灰度图像。每个图像的路径提供了标签信息,标签即为图像所在的目录名称。
注意事项:
data_dir
应包含不同类别的图像,每个类别的图像应放置在以其类别名称命名的子目录中。2)预处理图像:preprocess_images(faces)
参数:
faces
(列表):包含原始训练图像的灰度图像列表。功能: 该函数用于对训练图像进行预处理。它将每个图像调整为相同的大小(这里是100x100像素)。
注意事项:
- 输入的
faces
列表应包含灰度图像,且每个图像的尺寸可以不同。- 预处理后的图像会覆盖原始图像,因此建议在调用该函数前备份原始图像数据。
3)训练 LBPH 人脸识别器:train_lbph(faces, labels)
参数:
faces
(列表):包含预处理后的训练图像的灰度图像列表。labels
(列表):包含每个训练图像对应的标签列表。功能: 该函数创建 LBPH 人脸识别器,并使用给定的训练数据集进行训练。
注意事项:
faces
和labels
应具有相同的长度,且一一对应。- 训练数据集应包含足够多的样本,并且覆盖各种姿态、光照和表情等变化。
4)读取测试图像:load_test_image(image_path)
参数:
image_path
(字符串):测试图像文件的路径。功能: 该函数用于加载测试图像,并将其转换为灰度图像。
注意事项:
- 输入的测试图像应为灰度图像。
5)预处理测试图像:preprocess_test_image(test_image)
参数:
test_image
(二维数组):灰度测试图像。功能: 该函数用于对测试图像进行预处理,将其调整为与训练图像相同的大小。
注意事项:
- 输入的测试图像应为灰度图像。
- 预处理后的测试图像会覆盖原始图像数据,因此建议在调用该函数前备份原始测试图像数据。
6)进行人脸识别:recognize_face(model, test_image)
参数:
model
(cv2.face_LBPHFaceRecognizer):训练好的 LBPH 人脸识别器。test_image
(二维数组):预处理后的测试图像。功能: 该函数使用训练好的 LBPH 人脸识别器对预处理后的测试图像进行识别,并返回预测的标签和置信度。
注意事项:
- 输入的
test_image
应为预处理后的灰度图像。- 人脸识别器的模型应已经经过训练。
7)测试人脸识别器:test_face_recognition(data_dir, test_image_path)
参数:
data_dir
(字符串):包含训练图像的目录路径。test_image_path
(字符串):测试图像文件的路径。功能: 该函数是主函数,用于测试人脸识别器。它调用了前面定义的各个功能函数,并输出识别结果。
注意事项:
data_dir
应包含不同类别的图像,每个类别的图像应放置在以其类别名称命名的子目录中。- 测试图像应为单个灰度图像文件。
三、简单进行人脸训练与识别案例实现简单步骤
1、准备训练数据
这里使用1文件夹 汤姆汉克斯的头像,2 文件夹皮特的头像
2、待测试的是 2 皮特的头像
3、编写代码
3、运行结果
识别还是对了的,你们也可以试试其他图片
4、编辑代码
python">"""
简单进行人脸训练与识别1、准备训练数据集:2、提取局部纹理特征:3、构建特征向量:4、训练模型:5、人脸识别:
"""import cv2
import os
import numpy as npdef load_training_data(data_dir):"""从指定目录加载训练数据集:param data_dir:(str) 包含训练图像的目录路径:return:tuple 包含训练图像和对应标签的元组 (faces, labels)"""if not isinstance(data_dir, str) or not data_dir.strip():raise ValueError("Invalid data directory path.")faces = [] # 存储人脸图像labels = [] # 存储人脸标签for root, dirs, files in os.walk(data_dir):for file in files:if file.endswith('.jpg') or file.endswith('.png'):img_path = os.path.join(root, file)label = os.path.basename(root)face_img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)if face_img is not None:faces.append(face_img)labels.append(int(label))if not faces or not labels:raise ValueError("No valid training data found in the directory:", data_dir)return faces, labelsdef preprocess_images(faces):"""对图像列表进行预处理,调整图像大小为100x100像素:param faces: (list) 包含人脸图像的列表:return: list 预处理后的人脸图像列表"""if not isinstance(faces, list) or not faces:raise ValueError("Invalid input: faces must be a non-empty list of images.")preprocessed_faces = []for face in faces:if face is not None:face = cv2.resize(face, (100, 100)) # 调整图像大小preprocessed_faces.append(face)return preprocessed_facesdef train_lbph(faces, labels):"""使用 LBPH 算法训练人脸识别器:param faces: (list) 包含训练图像的列表:param labels: (list) 包含训练图像对应标签的列表:return: cv2.face_LBPHFaceRecognizer: 训练完成的 LBPH 人脸识别器模型"""if not isinstance(faces, list) or not faces:raise ValueError("Invalid input: faces must be a non-empty list of images.")if not isinstance(labels, list) or not labels:raise ValueError("Invalid input: labels must be a non-empty list of integers.")if len(faces) != len(labels):raise ValueError("Mismatch in the number of faces and labels.")model = cv2.face.LBPHFaceRecognizer_create()model.train(faces, np.array(labels))return modeldef load_test_image(image_path):"""加载测试图像:param image_path: (str) 测试图像文件路径:return: numpy.ndarray 加载的测试图像"""if not isinstance(image_path, str) or not image_path.strip():raise ValueError("Invalid image path.")test_image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)if test_image is None:raise ValueError("Failed to load test image from path:", image_path)return test_imagedef preprocess_test_image(test_image):"""预处理测试图像,调整大小为100x100像素:param test_image: (numpy.ndarray) 待处理的测试图像:return: numpy.ndarray 预处理后的测试图像"""if test_image is None:raise ValueError("Invalid input: test_image is None.")test_image = cv2.resize(test_image, (100, 100)) # 调整图像大小return test_imagedef recognize_face(model, test_image):"""使用训练好的模型识别人脸:param model: (cv2.face_LBPHFaceRecognizer) 训练完成的 LBPH 人脸识别器模型:param test_image: (numpy.ndarray) 待识别的测试图像:return: tuple 识别结果的标签和置信度 (label, confidence)"""if model is None or not isinstance(model, cv2.face_LBPHFaceRecognizer):raise ValueError("Invalid model: model must be a trained LBPH face recognizer.")if test_image is None:raise ValueError("Invalid input: test_image is None.")label, confidence = model.predict(test_image)return label, confidencedef test_face_recognition(data_dir, test_image_path):"""测试人脸识别器:param data_dir: (str) 包含训练图像的目录路径:param test_image_path: (str) 测试图像文件路径:return: tuple 识别结果的标签和置信度 (label, confidence)"""# 加载训练数据集faces, labels = load_training_data(data_dir)# 预处理训练数据集preprocessed_faces = preprocess_images(faces)# 训练 LBPH 人脸识别器model = train_lbph(preprocessed_faces, labels)# 读取测试图像test_image = load_test_image(test_image_path)# 预处理测试图像preprocessed_test_image = preprocess_test_image(test_image)# 进行人脸识别label, confidence = recognize_face(model, preprocessed_test_image)return label, confidence# 测试人脸识别器
if __name__ == "__main__":data_dir = "Images/Face/Train"test_image_path = "Images/Face/Test/Test_Peter.png"label, confidence = test_face_recognition(data_dir, test_image_path)print("Predicted label:", label)print("Confidence:", confidence)