《OpenCV》—— 人脸识别

发布于:2025-03-04 ⋅ 阅读:(12) ⋅ 点赞:(0)

人脸识别

人脸识别是一种基于人的面部特征信息进行身份识别的生物识别技术。它通过摄像头等设备采集含有人脸的图像或视频流,然后对图像中的人脸特征进行提取和分析,与预先存储的人脸模板进行比对,从而判断出人脸的身份。

工作原理

在这里插入图片描述

人脸特征识别器

在这里插入图片描述

LBPH算法

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

EigenFaces算法

在这里插入图片描述

FisherFaces算法

在这里插入图片描述

实例

分别对三种人脸特征识别器对人脸进行识别。

训练图片:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


测试图片:
在这里插入图片描述

LBPH算法
# 导入OpenCV库,用于计算机视觉任务,如图像读取、处理和人脸识别等操作
import cv2
# 导入NumPy库,它是Python中用于科学计算的基础库,这里主要用于处理标签数据
import numpy as np

# 创建一个空列表images,用于存储训练用的人脸图像
images = []

# 读取名为 'c_luo.png' 的图像,并将其转换为灰度图像
# cv2.IMREAD_GRAYSCALE 表示以灰度模式读取图像,灰度图像只有一个通道,能减少计算量
# 将读取的灰度图像添加到 images 列表中
images.append(cv2.imread('c_luo.png', cv2.IMREAD_GRAYSCALE))
# 同理,读取 'c_luo1.png' 并转换为灰度图像后添加到 images 列表
images.append(cv2.imread('c_luo1.png', cv2.IMREAD_GRAYSCALE))
# 读取 'mu_ba_pei.png' 并转换为灰度图像后添加到 images 列表
images.append(cv2.imread('mu_ba_pei.png', cv2.IMREAD_GRAYSCALE))
# 读取 'mu_ba_pei1.png' 并转换为灰度图像后添加到 images 列表
images.append(cv2.imread('mu_ba_pei1.png', cv2.IMREAD_GRAYSCALE))

# 创建一个标签列表 labels,用于标识每个训练图像对应的人物
# 0 表示 'c罗',1 表示 '姆巴佩',列表中元素顺序与 images 列表中图像顺序对应
labels = [0, 0, 1, 1]

# 创建一个字典 dic,用于将标签数字映射到对应的人物名称
# -1 表示无法识别的情况
dic = {0: 'c罗', 1: '姆巴佩', -1: '无法识别'}

# 读取待预测的图像 'mu_ba_pei2.png',并将其转换为灰度图像
predict_image = cv2.imread('mu_ba_pei2.png', cv2.IMREAD_GRAYSCALE)

# 创建一个基于局部二值模式直方图(LBPH)的人脸识别器对象
# LBPH 是一种常用的人脸识别算法,它对光照变化有较好的鲁棒性
recognizer = cv2.face.LBPHFaceRecognizer_create()

# 使用训练图像和对应的标签对人脸识别器进行训练
# np.array(labels) 将标签列表转换为 NumPy 数组,以满足 train 方法的输入要求
recognizer.train(images, np.array(labels))

# 使用训练好的人脸识别器对预测图像进行识别
# label 是识别结果对应的标签,confidence 是识别的置信度
# 置信度越低,表示识别结果越可靠
label, confidence = recognizer.predict(predict_image)

# 根据识别结果的标签,从字典中查找对应的人物名称并打印
print('这人是:', dic[label])
# 打印识别的置信度
print('置信度:', confidence)

结果:
在这里插入图片描述

EigenFaces算法
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont

# 初始化一个空列表,用于存储训练用的人脸图像
images = []

# 读取图像 'c_luo.png',并以灰度模式读取(参数 0 等同于 cv2.IMREAD_GRAYSCALE)
a = cv2.imread('c_luo.png', 0)
# 将图像 a 调整为 200x200 的大小,确保所有训练图像尺寸一致
a = cv2.resize(a, (200, 200))

# 读取图像 'c_luo1.png',并以灰度模式读取
b = cv2.imread('c_luo1.png', 0)
# 将图像 b 调整为 200x200 的大小
b = cv2.resize(b, (200, 200))

# 读取图像 'mu_ba_pei.png',并以灰度模式读取
c = cv2.imread('mu_ba_pei.png', 0)
# 将图像 c 调整为 200x200 的大小
c = cv2.resize(c, (200, 200))

# 读取图像 'mu_ba_pei1.png',并以灰度模式读取
d = cv2.imread('mu_ba_pei1.png', 0)
# 将图像 d 调整为 200x200 的大小
d = cv2.resize(d, (200, 200))

# 把处理好的图像添加到 images 列表中
images.append(a)
images.append(b)
images.append(c)
images.append(d)

# 定义每个训练图像对应的标签,0 代表 'c罗',1 代表 '姆巴佩'
labels = [0, 0, 1, 1]

# 读取待预测的图像 'mu_ba_pei2.png',并以灰度模式读取
pre_image = cv2.imread('mu_ba_pei2.png', 0)
# 将待预测图像调整为 200x200 的大小,与训练图像尺寸一致
pre_image = cv2.resize(pre_image, (200, 200))

# 创建一个基于特征脸(EigenFace)的人脸识别器对象
# 特征脸算法是一种经典的人脸识别方法,通过主成分分析(PCA)提取人脸的主要特征
recognizer = cv2.face.EigenFaceRecognizer_create()

# 使用训练图像和对应的标签对人脸识别器进行训练
# np.array(labels) 将标签列表转换为 NumPy 数组,以满足 train 方法的输入要求
recognizer.train(images, np.array(labels))

# 使用训练好的人脸识别器对预测图像进行识别
# label 是识别结果对应的标签,confidence 是识别的置信度
label, confidence = recognizer.predict(pre_image)

# 创建一个字典,将标签数字映射到对应的人物名称
dic = {0: 'c罗', 1: '姆巴佩'}

# 打印识别结果对应的人物名称
print('这人是:', dic[label])
# 打印识别的置信度
print('置信度为:', confidence)

# 读取原始的彩色图像 'mu_ba_pei2.png'
image = cv2.imread('mu_ba_pei2.png')

# 将 OpenCV 的 BGR 格式图像转换为 PIL 的 RGB 格式图像
# 因为 PIL 库处理图像时使用 RGB 格式
pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

# 创建一个可绘制的对象,用于在 PIL 图像上绘制文本
draw = ImageDraw.Draw(pil_image)

# 加载中文字体,这里使用 'simhei.ttf' 字体,字号为 20
# 确保系统中存在该字体文件,否则会报错
font = ImageFont.truetype('simhei.ttf', 20)

# 在 PIL 图像上指定位置 (10, 30) 绘制中文文本,文本内容为识别结果对应的人物名称
# fill=(0, 0, 255) 表示文本颜色为蓝色
draw.text((10, 30), dic[label], font=font, fill=(0, 0, 255))

# 将绘制好文本的 PIL 图像转换回 OpenCV 的 BGR 格式图像
result_image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)

# 显示处理后的图像,窗口名称为 'xx'
cv2.imshow('xx', result_image)

# 等待用户按下任意按键
cv2.waitKey(0)

# 关闭所有 OpenCV 打开的窗口,释放相关资源
cv2.destroyAllWindows()

结果:
在这里插入图片描述

FisherFaces算法
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont

def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=20):
    """ 向图片中添加中文 """
    # 判断输入的 img 是否为 OpenCV 格式的图片(即 numpy.ndarray 类型)
    if (isinstance(img, np.ndarray)):
        # 如果是 OpenCV 格式,将其从 BGR 颜色空间转换为 RGB 颜色空间,
        # 并将其转换为 PIL 库可以处理的 Image 对象
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    
    # 在 img 图片上创建一个绘图对象,用于后续绘制文本
    draw = ImageDraw.Draw(img)
    
    # 定义字体的格式,使用 "simsun.ttc" 字体文件,指定字体大小为 textSize,
    # 并设置编码为 UTF - 8 以支持中文显示
    fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")
    
    # 在指定的 position 位置,使用指定的 textColor 颜色和 fontStyle 字体绘制文本
    draw.text(position, text, textColor, font=fontStyle)
    
    # 将绘制好文本的 PIL 图片转换回 numpy.ndarray 类型,并将颜色空间从 RGB 转换回 BGR,
    # 以符合 OpenCV 的要求
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

# 初始化一个空列表,用于存储训练用的人脸图像
images = []

# 读取图像 'c_luo.png',并以灰度模式读取(参数 0 等同于 cv2.IMREAD_GRAYSCALE)
a = cv2.imread('c_luo.png', 0)
# 将图像 a 调整为 200x200 的大小,确保所有训练图像尺寸一致
a = cv2.resize(a, (200, 200))

# 读取图像 'c_luo1.png',并以灰度模式读取
b = cv2.imread('c_luo1.png', 0)
# 将图像 b 调整为 200x200 的大小
b = cv2.resize(b, (200, 200))

# 读取图像 'mu_ba_pei.png',并以灰度模式读取
c = cv2.imread('mu_ba_pei.png', 0)
# 将图像 c 调整为 200x200 的大小
c = cv2.resize(c, (200, 200))

# 读取图像 'mu_ba_pei1.png',并以灰度模式读取
d = cv2.imread('mu_ba_pei1.png', 0)
# 将图像 d 调整为 200x200 的大小
d = cv2.resize(d, (200, 200))

# 把处理好的图像添加到 images 列表中
images.append(a)
images.append(b)
images.append(c)
images.append(d)

# 定义每个训练图像对应的标签,0 代表 'c罗',1 代表 '姆巴佩'
labels = [0, 0, 1, 1]

# 读取待预测的图像 'mu_ba_pei2.png',并以灰度模式读取
pre_image = cv2.imread('mu_ba_pei2.png', 0)
# 将待预测图像调整为 200x200 的大小,与训练图像尺寸一致
pre_image = cv2.resize(pre_image, (200, 200))

# 创建一个基于 Fisher 脸的人脸识别器对象
# Fisher 脸算法结合了线性判别分析(LDA),可以在低维空间中找到最具区分性的特征
recognizer = cv2.face.FisherFaceRecognizer_create()

# 使用训练图像和对应的标签对人脸识别器进行训练
# np.array(labels) 将标签列表转换为 NumPy 数组,以满足 train 方法的输入要求
recognizer.train(images, np.array(labels))

# 使用训练好的人脸识别器对预测图像进行识别
# label 是识别结果对应的标签,confidence 是识别的置信度
label, confidence = recognizer.predict(pre_image)

# 创建一个字典,将标签数字映射到对应的人物名称
dic = {0: 'c罗', 1: '姆巴佩'}

# 打印识别结果对应的人物名称
print('这人是:', dic[label])
# 打印识别的置信度
print('置信度为:', confidence)

# 读取原始的彩色图像 'mu_ba_pei2.png',并使用 copy() 方法复制一份,
# 避免修改原始图像
# 调用 cv2AddChineseText 函数,在图像上添加识别结果的中文文本,
# 文本位置为 [10, 30]
aa = cv2AddChineseText(cv2.imread('mu_ba_pei2.png').copy(), dic[label], [10, 30])

# 显示处理后的图像,窗口名称为 'xx'
cv2.imshow('xx', aa)

# 等待用户按下任意按键
cv2.waitKey(0)

结果:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到