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的置信度值有不同含义
相关推荐
manyikaimen2 分钟前
博派智能-运动控制技术-PSO(位置同步输出)
图像处理·计算机视觉·机器人·视觉检测·运动控制·pso·点胶
woai33648 分钟前
JVM学习-基础篇-垃圾回收
java·jvm·学习
深蓝海拓18 分钟前
S7-1500学习笔记:Array数据类型
笔记·学习·plc
Xudde.8 小时前
班级作业笔记报告0x04
笔记·学习·安全·web安全·php
晓晓hh9 小时前
JavaSE学习——迭代器
java·开发语言·学习
EDPJ9 小时前
当图像与文本 “各说各话” —— CLIP 中的模态鸿沟与对象偏向
深度学习·计算机视觉
421!10 小时前
GPIO工作原理以及核心
开发语言·单片机·嵌入式硬件·学习
charlee4410 小时前
最小二乘问题详解17:SFM仿真数据生成
c++·计算机视觉·sfm·数字摄影测量·无人机航测
AI成长日志10 小时前
【笔面试算法学习专栏】双指针专题·简单难度两题精讲:167.两数之和II、283.移动零
学习·算法·面试
Fleshy数模10 小时前
OpenCV 实时人脸检测实战:从视频文件到人脸框标注
人工智能·opencv·计算机视觉