Skip to content

基于OpenCv的人脸识别

人脸识别步骤

人脸采集

采集人脸图片的方法多种多样,可以直接从网上下载数据集,可以从视频中提取图片,还可以从摄像头实时的采集图片。

人脸检测方法

人脸检测在实际中主要用于人脸识别的预处理,即在图像中准确标定出人脸的位置和大小。人脸图像中包含的模式特征十分丰富,如直方图特征、颜色特征、模板特征、结构特征及Haar特征等。人脸检测就是把这其中有用的信息挑出来,并利用这些特征实现人脸检测。

人脸图像预处理

对于人脸的图像预处理是基于人脸检测结果,对图像进行处理并最终服务于特征提取的过程。系统获取的原始图像由于受到各种条件的限制和随机 干扰,往往不能直接使用,必须在图像处理的早期阶段对它进行灰度校正、噪声过滤等图像预处理。对于人脸图像而言,其预处理过程主要包括人脸图像的光线补 偿、灰度变换、直方图均衡化、归一化、几何校正、滤波以及锐化等。

人脸特征提取

人脸识别系统可使用的特征通常分为视觉特征、像素统计特征、人脸图像变换系数特征、人脸图像代数 特征等。人脸特征提取就是针对人脸的某些特征进行的。人脸特征提取,也称人脸表征,它是对人脸进行特征建模的过程。人脸特征提取的方法归纳起来分为两大 类:一种是基于知识的表征方法;另外一种是基于代数特征或统计学习的表征方法。

匹配与识别

提取的人脸图像的特征数据与数据库中存储的特征模板进行搜索匹配,通过设定一个阈值,当相似度超过这一阈值,则把匹配得到的结果输 出。人脸识别就是将待识别的人脸特征与已得到的人脸特征模板进行比较,根据相似程度对人脸的身份信息进行判断。这一过程又分为两类:一类是确认,是一对一 进行图像比较的过程,另一类是辨认,是一对多进行图像匹配对比的过程。

关于OpenCv

Opencv是一个开源的的跨平台计算机视觉库,内部实现了图像处理和计算机视觉方面的很多通用算法,对于python而言,在引用opencv库的时候需要写为import cv2。其中,cv2是opencv的C++命名空间名称,使用它来表示调用的是C++开发的opencv的接口

目前人脸识别有很多较为成熟的方法,这里调用OpenCv库,而OpenCV又提供了三种人脸识别方法,分别是LBPH方法、EigenFishfaces方法、Fisherfaces方法。本文采用的是LBPH(Local Binary Patterns Histogram,局部二值模式直方图)方法。在OpenCV中,可以用函数cv2.face.LBPHFaceRecognizer_create()生成LBPH识别器实例模型,然后应用cv2.face_FaceRecognizer.train()函数完成训练,最后用cv2.face_FaceRecognizer.predict()函数完成人脸识别。

CascadeClassifier,是Opencv中做人脸检测的时候的一个级联分类器。并且既可以使用Haar,也可以使用LBP特征。其中Haar特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征。它分为三类:边缘特征、线性特征、中心特征和对角线特征。

使用OpenCV和Haar级联分类器

安装 OpenCV

sh
pip install opencv-python
pip install opencv-python-headless  # 如果不需要显示功能
pip install opencv-contrib-python  # 如果需要额外功能

python示例代码

python
import cv2
import numpy as np

# 加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 加载图像
# image_path = "C:/Users/hjh/Pictures/2023-01-26073120.jpg"
image_path = "example.jpg"  # 替换为你的图片路径
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转为灰度图

# 检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

if len(faces) == 0:
    print("未检测到人脸!")
    exit()  # 退出程序
else:
    print(f"检测到 {len(faces)} 张人脸")

# 绘制检测到的人脸
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)

# 提取特征码(示例:使用 LBPH 特征)
# 初始化 LBPHFaceRecognizer
recognizer = cv2.face.LBPHFaceRecognizer_create()

# 创建一个样本和标签列表(通常用于训练和识别)
sample_face = gray[y:y+h, x:x+w]  # 截取人脸区域
recognizer.train([sample_face], np.array([0]))  # 训练模型

# 提取特征码
features = recognizer.getHistograms()
print("Extracted Features:", features)

# 显示结果
# 创建一个可调整大小的窗口
cv2.namedWindow("Detected Faces", cv2.WINDOW_NORMAL)
height, width = image.shape[:2]
cv2.resizeWindow("Detected Faces", width, height)
cv2.imshow("Detected Faces", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

注意事项

某些 Python 库或环境对中文路径的支持不够友好。

匹配人脸

你可以通过计算特征向量之间的距离(如欧几里得距离)来进行人脸匹配,从而识别同一个人。

python
# 假设 features_from_db 是从数据库读取的特征,current_features 是当前提取的特征
# features = np.array([[0.05215419, 0.01133787, 0.0, ..., 0.09070295]], dtype=np.float32)
distance = np.linalg.norm(current_features - features_from_db)
print(f"当前特征与数据库特征的欧几里得距离: {distance}")

欧几里得距离(Euclidean Distance)用于计算两个点之间的“直线”距离,公式如下:

其中:

  • ( x_i ) 和 ( y_i ) 是特征向量 (x) 和 (y) 的第 (i) 个分量。
  • (n) 是特征向量的维度。

粤ICP备20009776号