# 基于 OpenCV 的人脸识别实战:从基础到进阶
基于 OpenCV 的人脸识别实战:从基础到进阶
在当今数字化时代,人脸识别技术已经广泛应用于生活的方方面面,从手机解锁到安防监控,再到各种智能系统的身份验证。今天,我将通过一系列代码示例,详细讲解如何使用 OpenCV 实现人脸识别,从基础的图像处理到不同算法的应用,逐步深入,带你领略人脸识别的魅力。
一、OpenCV 简介
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,它提供了大量的图像和视频处理功能。其中,人脸识别是 OpenCV 的一个重要应用领域。通过 OpenCV,我们可以轻松地实现人脸检测、识别等功能,而无需深入了解复杂的底层算法原理。
二、基础:图像处理与数据准备
在进行人脸识别之前,我们需要准备一些人脸图像作为训练数据。这些图像可以是同一人物的多张照片,也可以是不同人物的照片。为了方便处理,我们通常将图像转换为灰度图像,并调整其大小以保持一致。以下是代码示例:
import cv2
import numpy as np
images = []
a = cv2.imread('lss1.png', 0) # 读取图像,0 表示以灰度模式读取
a = cv2.resize(a, (120, 180)) # 调整图像大小
b = cv2.imread('lss2.png', 0)
b = cv2.resize(b, (120, 180))
c = cv2.imread('cdl1.png', 0)
c = cv2.resize(c, (120, 180))
d = cv2.imread('cdl2.png', 0)
d = cv2.resize(d, (120, 180))
images.append(a)
images.append(b)
images.append(c)
images.append(d)
在上述代码中,我们读取了四张人脸图像(lss1.png、lss2.png、cdl1.png、cdl2.png),并将它们转换为灰度图像,同时调整大小为 120×180 像素。这些图像将作为我们的人脸识别模型的训练数据。
三、人脸识别算法:EigenFace

EigenFace 是一种经典的人脸识别算法,它基于主成分分析(PCA)来提取人脸图像的特征。在 OpenCV 中,我们可以使用 cv2.face.EigenFaceRecognizer_create() 方法创建一个 EigenFace 识别器。以下是使用 EigenFace 算法进行人脸识别的代码示例:
labels = [0, 0, 1, 1] # 为每张图像分配标签,0 表示刘诗诗,1 表示陈都灵
pre_image = cv2.imread('lss.png', 0) # 读取待识别的图像
pre_image = cv2.resize(pre_image, (120, 180)) # 调整图像大小
recognizer = cv2.face.EigenFaceRecognizer_create(threshold=10000) # 创建 EigenFace 识别器,设置阈值为 10000
recognizer.train(images, np.array(labels)) # 使用训练数据训练识别器
label, confidence = recognizer.predict(pre_image) # 对待识别的图像进行预测
dic = {0: '刘诗诗', 1: '陈都灵', -1: '无法识别'} # 创建一个字典,将标签映射为人物名称
print('这人是:', dic[label])
print('置信度为:', confidence)
在上述代码中,我们首先为训练图像分配了标签(labels),然后创建了一个 EigenFace 识别器,并使用训练数据(images 和 labels)对其进行了训练。接着,我们对一张待识别的图像(lss.png)进行了预测,得到了识别结果(人物名称)和置信度。
四、进阶:FisherFace 算法与中文显示

FisherFace 算法是另一种经典的人脸识别算法,它在 EigenFace 的基础上进行了改进,通过线性判别分析(LDA)进一步优化了特征提取。在 OpenCV 中,我们可以使用 cv2.face.FisherFaceRecognizer_create() 方法创建一个 FisherFace 识别器。此外,为了在图像上显示中文识别结果,我们可以使用 Pillow 库来实现中文文本的绘制。以下是代码示例:
# 导入必要的库
import cv2 # OpenCV库,用于图像处理和计算机视觉任务
import numpy as np # NumPy库,用于数值计算,特别是数组操作
from PIL import Image, ImageDraw, ImageFont # PIL库,用于图像处理,特别是处理中文文本
# 定义函数 cv2AddChineseText,用于在图像上添加中文文本
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
""" 向图片中添加中文 """
if (isinstance(img, np.ndarray)): # 判断输入图像是否为OpenCV的numpy数组格式
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 将OpenCV格式的图像转换为PIL格式
draw = ImageDraw.Draw(img) # 创建一个绘图对象,用于在图像上绘制文本
# 定义字体样式,使用simsun字体,字体大小为textSize,编码为utf-8
fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")
draw.text(position, text, textColor, font=fontStyle) # 在指定位置绘制文本
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR) # 将PIL格式的图像转换回OpenCV格式
# 定义函数 image_re,用于读取和调整图像大小
def image_re(image):
a = cv2.imread(image, 0) # 以灰度模式读取图像
a = cv2.resize(a, (120, 180)) # 将图像调整为120x180大小
images.append(a) # 将调整后的图像添加到全局列表images中
# 初始化一个空列表,用于存储训练图像
images = []
# 调用image_re函数,加载四张训练图像
image_re('lss1.png')
image_re('lss2.png')
image_re('cdl1.png')
image_re('cdl2.png')
# 定义训练图像的标签,0表示刘诗诗,1表示陈都灵
labels = [0, 0, 1, 1]
# 读取并调整预处理图像的大小
pre_image = cv2.imread('lss.png', 0) # 以灰度模式读取预处理图像
pre_image = cv2.resize(pre_image, (120, 180)) # 将图像调整为120x180大小
# 创建Fisher Face人脸识别器,设置阈值为5000
recognizer = cv2.face.FisherFaceRecognizer_create(threshold=5000)
# 使用训练图像和标签训练人脸识别器
recognizer.train(images, np.array(labels))
# 使用训练好的识别器对预处理图像进行预测
label, confidence = recognizer.predict(pre_image)
# 定义一个字典,将标签映射为对应的中文名称
dic = {0: '刘诗诗', 1: '陈都灵', -1: '无法识别'}
print('这人是:', dic[label]) # 打印预测结果
print('置信度为:', confidence) # 打印置信度
# 在预处理图像上添加中文文本
image = cv2AddChineseText(cv2.imread('lss.png').copy(), dic[label], (10, 30), textColor=(255, 0, 0))
# 显示图像
cv2.imshow('xx', image)
# 等待用户按键,按任意键关闭窗口
cv2.waitKey(0)
在上述代码中,我们使用了 FisherFace 算法进行人脸识别,并通过自定义的 cv2AddChineseText() 函数在图像上添加了中文识别结果。cv2AddChineseText() 函数利用 Pillow 库实现了 OpenCV 图像与 Pillow 图像之间的转换,并绘制了中文文本。
五、拓展:LBPH 算法

LBPH(Local Binary Patterns Histograms)算法是一种基于局部二值模式特征的人脸识别算法。它通过计算图像的局部纹理特征来提取人脸特征,对光照变化和表情变化具有一定的鲁棒性。在 OpenCV 中,我们可以使用 cv2.face.LBPHFaceRecognizer_create() 方法创建一个 LBPH 识别器。以下是使用 LBPH 算法进行人脸识别的代码示例:
import cv2
import numpy as np
images = []
images.append(cv2.imread('zjl1.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('zjl2.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('zxc1.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('zxc2.png', cv2.IMREAD_GRAYSCALE))
labels = [0, 0, 1, 1]
dic = {0: '周杰伦', 1: '周星驰', -1: '无法识别'}
predict_image = cv2.imread('zjl.png', cv2.IMREAD_GRAYSCALE)
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.train(images, np.array(labels))
label, confidence = recognizer.predict(predict_image)
print('这人是', dic[label])
print('置信度', confidence)
在上述代码中,我们使用了 LBPH 算法对周杰伦和周星驰的人脸图像进行了识别。通过训练数据(images 和 labels),我们训练了一个 LBPH 识别器,并对一张待识别的图像(zjl.png)进行了预测,得到了识别结果和置信度。
六、总结
通过上述代码示例,我们详细介绍了如何使用 OpenCV 实现人脸识别,从图像处理与数据准备,到不同人脸识别算法(EigenFace、FisherFace、LBPH)的应用,再到中文显示的实现。在实际应用中,我们可以根据具体需求选择合适的算法,并对代码进行优化和扩展,以实现更高效、更准确的人脸识别系统。希望本文对你有所帮助,也欢迎你在评论区留言交流,共同探索人脸识别技术的更多可能性!
如果你
更多推荐

所有评论(0)