OpenCV 学习:人脸识别与表情检测

文章目录


一、静态图像人脸检测

OpenCV提供了基于Haar特征的人脸检测器,可以快速在静态图片中定位人脸位置:

python 复制代码
import cv2

# 读取图像并转换为灰度图
image = cv2.imread('people.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 加载预训练的人脸检测分类器
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 检测人脸
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=15, minSize=(8, 8))

print("发现{}张人脸!".format(len(faces)))
print("其位置分别是:", faces)

# 在原图上绘制矩形框标记人脸
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 显示结果
cv2.imshow("result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键参数解析:

  • scaleFactor=1.05:图像金字塔的缩放比例。值越小检测越精细但速度越慢,值越大检测越快但可能漏检
  • minNeighbors=15:每个候选矩形应该保留的邻近矩形数量。值越高误检越少,但可能漏掉真实人脸
  • minSize=(8, 8):检测目标的最小尺寸,过滤掉过小的误检区域

二、实时视频流人脸检测

将上述技术应用到摄像头实时视频流中:

python 复制代码
import cv2

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# 打开摄像头(0表示默认摄像头)
cap = cv2.VideoCapture(0)

while True:
    ret, image = cap.read()
    if not ret:
        break

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=15, minSize=(8, 8))

    for (x, y, w, h) in faces:
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

    cv2.imshow("Face Detection", image)

    # 按ESC键退出
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

三、人脸与微笑检测结合

在检测人脸的基础上,进一步识别面部表情(微笑):

python 复制代码
import cv2

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
smile = cv2.CascadeClassifier("haarcascade_smile.xml")
cap = cv2.VideoCapture(0)

while True:
    ret, image = cap.read()
    image = cv2.flip(image, 1)  # 水平翻转,让画面像镜子一样

    if ret is None:
        break

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=15, minSize=(5, 5))

    for (x, y, w, h) in faces:
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

        # 提取人脸区域(ROI)
        roi_grayscale = gray[y:y + h, x:x + w]
        cv2.imshow('Face', roi_grayscale)

        # 在人脸区域内检测微笑
        smiles = smile.detectMultiScale(roi_grayscale, scaleFactor=1.5, minNeighbors=25, minSize=(50, 50))

        for (sx, sy, sw, sh) in smiles:
            a = x + sx  # 转换回原图坐标系
            b = y + sy
            cv2.rectangle(image, (a, b), (a + sw, b + sh), (255, 0, 0), 2)
            cv2.putText(image, "smile", (x, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 255, 255), 2)

    cv2.imshow('Face and Smile Detection', image)
    key = cv2.waitKey(25)
    if key == 27:  # ESC键退出
        break

cap.release()
cv2.destroyAllWindows()

微笑检测参数说明:

  • scaleFactor=1.5:相对较大的缩放比例,因为微笑特征比人脸特征变化小
  • minNeighbors=25:较高的阈值,减少误将其他表情识别为微笑
  • minSize=(50, 50):限定最小微笑区域,避免检测到过小的纹理变化

四、基于LBPH的人脸识别

LBPH(Local Binary Patterns Histograms)是一种基于局部纹理特征的人脸识别算法:

python 复制代码
import cv2
import numpy as np

# 准备训练图像(灰度图)
images = []
images.append(cv2.imread('hg1.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('hg2.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('pyy1.png', cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread('pyy2.png', cv2.IMREAD_GRAYSCALE))

# 对应的标签:0代表hg,1代表pyy
labels = [0, 0, 1, 1]
dic = {0: 'hg', 1: 'pyy', -1: '无法识别'}

# 待识别的图像
predict_image = cv2.imread('hg.png', cv2.IMREAD_GRAYSCALE)

# 创建LBPH识别器,设置阈值为80
recognizer = cv2.face.LBPHFaceRecognizer_create(threshold=80)

# 训练模型
recognizer.train(images, np.array(labels))

# 进行预测
label, confidence = recognizer.predict(predict_image)
print('这人是:', dic[label])
print('置信度:', confidence)

LBPH算法特点:

  • threshold=80:识别阈值,低于此值才认为是已知人脸
  • confidence值:越小表示匹配度越高,0表示完美匹配
  • 优点:对光照变化不敏感,计算速度快

五、基于特征脸(EigenFace)的人脸识别

EigenFace是基于PCA(主成分分析)的人脸识别方法:

python 复制代码
import cv2
import numpy as np

images = []

# 加载并统一图像尺寸
a = cv2.imread('hg1.png', 0)  # 0表示灰度模式
a = cv2.resize(a, (120, 180))
b = cv2.imread('hg2.png', 0)
b = cv2.resize(b, (120, 180))
c = cv2.imread('pyy1.png', 0)
c = cv2.resize(c, (120, 180))
d = cv2.imread('pyy2.png', 0)
d = cv2.resize(d, (120, 180))

images.append(a)
images.append(b)
images.append(c)
images.append(d)

labels = [0, 0, 1, 1]
pre_image = cv2.imread('pyy3.png', 0)
pre_image = cv2.resize(pre_image, (120, 180))

# 创建EigenFace识别器,设置阈值为5000
recognizer = cv2.face.EigenFaceRecognizer.create(threshold=5000)

recognizer.train(images, np.array(labels))

label, confidence = recognizer.predict(pre_image)
dic = {0: 'hg', 1: 'pyy', -1: 'Unknown'}
print('这人是:', dic[label])
print(f'置信度为:{confidence:.4f}')

# 在图像上显示识别结果
aa = cv2.putText(cv2.imread('pyy2.png').copy(), dic[label], (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow('Result', aa)
cv2.waitKey(0)

EigenFace关键点:

  • 图像尺寸统一:所有训练和测试图像必须调整为相同尺寸
  • threshold=5000:EigenFace的阈值通常设置较大
  • confidence值:与LBPH不同,EigenFace的置信度值有不同含义
相关推荐
stm32 菜鸟3 小时前
nucleo-f411re学习记录-12,Wifi模块ESP8684
学习
AI人工智能+4 小时前
基于深度学习的银行回单识别技术,成为连接物理票据与数字财务系统的桥梁
深度学习·计算机视觉·ocr·银行回单识别
stm32 菜鸟5 小时前
nucleo-f411re学习记录-9,双轴XY摇杆传感器
学习
南子北游5 小时前
Python学习(基础语法1)
开发语言·python·学习
Atri厨7 小时前
X86存储器的段描述符学习随笔
学习
星幻元宇VR7 小时前
VR航空航天科普设备助力航天知识普及
人工智能·科技·学习·安全·vr·虚拟现实
d111111111d7 小时前
STM32-UART封装问题解析
笔记·stm32·单片机·嵌入式硬件·学习·算法
寒秋花开曾相惜7 小时前
(学习笔记)4.2 逻辑设计和硬件控制语言HCL(4.2.1 逻辑门&4.2.2 组合电路和HCL布尔表达式)
linux·网络·数据结构·笔记·学习·fpga开发
叶子野格8 小时前
《C语言学习:指针》12
c语言·开发语言·c++·学习·visual studio
光影少年8 小时前
前端线上屏幕出现卡顿如何排查?
开发语言·前端·javascript·学习·前端框架·node.js