OpenCV学习:CNN 人脸检测

OpenCV学习:CNN 人脸检测

前言 :前面几篇我们学习了 dlib 的 HOG 人脸检测器、68 个关键点检测、轮廓绘制、表情识别,以及疲劳检测。这些内容全部基于 dlib 的 HOG 检测器。本篇我们再来认识 dlib 的另一种人脸检测器------CNN 人脸检测器。它使用卷积神经网络(Convolutional Neural Network)替代传统的 HOG 特征,对小脸、侧脸、遮挡人脸的检测效果更好,准确率更高,是 dlib 中精度最高的人脸检测方案。

目录

  • 一、dlib 的两种人脸检测器
  • 二、CNN 人脸检测原理
  • 三、模型文件说明
  • 四、返回值结构详解
  • 五、完整代码
  • 六、CNN 与 HOG 对比
  • 七、参数调优建议
  • 八、总结

一、dlib 的两种人脸检测器

dlib 提供了两种人脸检测器,各有特点:

检测器 原理 优点 缺点
HOG 检测器 HOG 特征 + 线性分类器 速度快,CPU 即可运行 对小脸、侧脸、遮挡效果一般
CNN 检测器 卷积神经网络 准确率高,对小脸、侧脸效果好 速度较慢,GPU 上运行更快

1.1 HOG 检测器回顾

python 复制代码
detector = dlib.get_frontal_face_detector()

这是我们前面几篇用到的检测器,速度快,适合实时场景。但在实际使用中,HOG 检测器也有明显的短板:

  • 小脸检测难:图像中占比很小的脸容易漏检
  • 侧脸检测差:正脸检测效果最好,侧脸效果明显下降
  • 遮挡敏感:人脸被口罩、眼镜、帽子遮挡时容易检测失败

1.2 CNN 检测器

python 复制代码
detector = dlib.cnn_face_detection_model_v1("mmod_human_face_detector.dat")

CNN 检测器使用 MMOD(Max-Margin Object Detection) 算法,通过卷积神经网络自动学习人脸特征,能有效解决 HOG 检测器的上述短板。

"MMOD" 是什么? MMOD 是 dlib 作者 Davis King 提出的一种目标检测算法,其核心思想是让预测框与真实框之间的"边缘"最大化,从而提升检测精度。它不需要区域提议(RPN),直接对整张图进行检测,速度比 R-CNN 类算法快。

二、CNN 人脸检测原理

2.1 基本原理

CNN 检测器通过多层卷积和池化操作,自动从图像中提取人脸特征,然后使用全连接层判断每个位置是否包含人脸,并回归出人脸的边界框。

层级 作用
卷积层 提取边缘、纹理、五官等局部特征
池化层 降低特征图尺寸,减少计算量
全连接层 综合特征进行判别和边框回归

2.2 相比 HOG 的优势

优势 说明
特征学习能力强 神经网络可以自动学习复杂的特征,比人工设计的 HOG 特征更丰富
多尺度检测 通过上采样和不同尺度的特征图,能检测到更小的人脸
抗遮挡 即使部分人脸被遮挡,CNN 仍能通过其他部位识别
侧脸检测 训练数据中包含了大量侧脸样本,检测效果更好

2.3 代价

代价 说明
计算量大 卷积操作比 HOG 计算更耗时
内存占用高 模型文件约 700KB,运行时需要更多内存
无 GPU 时速度慢 纯 CPU 环境下,一帧可能需要几百毫秒

三、模型文件说明

3.1 模型下载

CNN 人脸检测需要预训练模型 mmod_human_face_detector.dat,可从 dlib 官方渠道下载。

3.2 模型信息

项目 说明
文件名 mmod_human_face_detector.dat
大小 约 700KB
格式 dlib 专用的二进制格式
训练数据 大量带标注的人脸图片
检测精度 比 HOG 检测器高很多

3.3 模型调用

python 复制代码
detector = dlib.cnn_face_detection_model_v1(r"models\mmod_human_face_detector.dat")
  • cnn_face_detection_model_v1:dlib 提供的 CNN 人脸检测模型类
  • 传入参数:模型文件路径

四、返回值结构详解

4.1 HOG 检测器的返回值

python 复制代码
faces = hog_detector(img, 0)
for face in faces:
    x1 = face.left()   # face 直接就是 rectangle 对象
    y1 = face.top()

HOG 检测器直接返回 rectangle 对象列表 ,所以可以直接调用 left()top() 等方法。

4.2 CNN 检测器的返回值

python 复制代码
faces = cnn_detector(img, 0)
for d in faces:
    rect = d.rect      # 必须先取 .rect 属性
    x1 = rect.left()   # 再调用方法
    y1 = rect.top()

CNN 检测器返回的是 mmod_rectangle 对象列表,每个对象包含:

属性 说明
.rect 人脸矩形框(rectangle 对象)
.confidence 该检测结果的置信度

为什么这么设计? 因为 MMOD 算法不仅要给出人脸位置,还要给出置信度,所以用一个包装类来同时携带这两个信息。

4.3 两种检测器对比

检测器 返回值 获取坐标方式
HOG rectangle 直接 face.left()
CNN mmod_rectangle d.rect,再 rect.left()

注意 :如果直接用 CNN 检测器返回的对象调用 left() 会报错。

五、完整代码

python 复制代码
import dlib
import cv2

# ==================== 加载 CNN 人脸检测器 ====================
# cnn_face_detection_model_v1 是 dlib 提供的 CNN 检测器
# 它使用卷积神经网络进行人脸检测,比 HOG 检测器精度更高
# 参数:模型文件路径
cnn_face_detector = dlib.cnn_face_detection_model_v1(r"models\mmod_human_face_detector.dat")

# ==================== 读取图片 ====================
img = cv2.imread(r"photo\faces.png")
# 缩小图片:CNN 检测计算量大,缩小图片可以显著加快检测速度
# fx=0.2, fy=0.2 表示宽高都缩小到原来的 20%
img = cv2.resize(img, None, fx=0.2, fy=0.2)

# ==================== 执行人脸检测 ====================
# 参数 2:上采样次数
#   - 0:不上采样,速度最快,适合人脸较大的场景
#   - 1:上采样一次,适合人脸较小的场景
#   - 2:上采样两次,适合人脸非常小的场景,但速度最慢
# 返回值 faces:mmod_rectangle 对象列表,需要通过 .rect 属性获取矩形
faces = cnn_face_detector(img, 2)

# ==================== 绘制人脸框 ====================
for d in faces:
    # 从 mmod_rectangle 对象中取出 rect 属性(这才是 rectangle 对象)
    rect = d.rect

    # 获取人脸矩形的四个边界坐标
    left = rect.left()       # 左边界 x 坐标
    top = rect.top()         # 上边界 y 坐标
    right = rect.right()     # 右边界 x 坐标
    bottom = rect.bottom()   # 下边界 y 坐标

    # 绘制人脸框
    # pt1:矩形左上角坐标;pt2:矩形右下角坐标
    # color=(0, 255, 0):绿色;thickness=3:线条粗细
    cv2.rectangle(img, pt1=(left, top), pt2=(right, bottom),
                  color=(0, 255, 0), thickness=3)

    # 打印置信度(mmod_rectangle 独有的属性)
    print(f"检测到人脸,置信度: {d.confidence:.2f}")

# ==================== 显示结果 ====================
cv2.imshow("result", img)
k = cv2.waitKey()  # 等待按键,按任意键退出
cv2.destroyAllWindows()

六、CNN 与 HOG 对比

对比维度 HOG 检测器 CNN 检测器
原理 HOG 特征 + 线性分类器 卷积神经网络(MMOD)
准确率 一般 更高
速度 快(几十毫秒) 较慢(几百毫秒,CPU 环境)
小脸检测 一般 更好
侧脸检测 一般 更好
遮挡处理 一般 更好
返回值 直接返回 rectangle 返回 mmod_rectangle(需 .rect
返回值附带信息 有置信度(confidence
模型文件 内置(无需下载) 需要下载 .dat 文件
适用场景 实时检测、CPU 环境 高精度场景、GPU 环境

七、参数调优建议

7.1 上采样次数

上采样次数 效果 建议场景
0 速度最快,小脸容易漏检 人脸较大的近景图片
1 速度适中,精度较好 一般场景
2 精度最高,速度最慢 人脸很小的远景图片

7.2 图像预处理

建议 说明
缩小图像 CNN 计算量大,缩小图像能显著提升速度
灰度转换 虽然 CNN 可以处理彩色图,但灰度图速度更快
降低分辨率 人脸检测不需要太高的分辨率,适当降低即可

7.3 使用场景建议

场景 推荐检测器
实时摄像头 HOG(速度快)
照片人脸检测 CNN(精度高)
小脸/侧脸多的图片 CNN(HOG 容易漏检)
无 GPU 环境 HOG 或缩小图片后的 CNN

八、总结

核心函数速查

函数 用途
dlib.cnn_face_detection_model_v1(path) 加载 CNN 人脸检测模型
detector(img, upsample) 执行检测,返回人脸列表
d.rect 从检测结果中取出矩形对象
d.confidence 获取该检测结果的置信度
rect.left() / top() / right() / bottom() 获取矩形边界坐标
cv2.rectangle() 绘制人脸框

两种检测器返回值速查

检测器 返回值 获取坐标方式 是否有置信度
HOG rectangle 直接 face.left()
CNN mmod_rectangle d.rect,再 rect.left() 是(d.confidence

注意事项

要点 说明
模型文件 mmod_human_face_detector.dat 需提前下载
上采样参数 值越大检测越细,但速度越慢
图片尺寸 CNN 计算量大,建议缩小图片加快检测
返回值差异 CNN 检测器需要 .rect 属性获取坐标
使用场景 CNN 精度高,HOG 速度快,按需选择
置信度 CNN 检测器独有的 confidence 属性可用于进一步筛选

系列直达

相关推荐
AI的探索之旅1 天前
97 个 OpenCV 实例(三十):双目立体,从标定到点云
人工智能·opencv·计算机视觉
yyk333241 天前
OpenCV中的疲劳检测
opencv
宿州派大星1 天前
【Python实战】:基于 OpenCV + dlib 的传统换脸术原理与实战
opencv·python3.11·dlib
陈年老古董1 天前
MediaPipe 姿态检测与脸部关键点检测
笔记·python·opencv·学习·dlib
a3535413821 天前
DFT到FFT的推导
opencv
别动我齐刘海1 天前
ROS2 Jazzy + C++ 实战路线——ros2_control
c++·人工智能·python·opencv·机器学习·机器人·github
浔溺1 天前
al+大数据每日学习笔记41
opencv·计算机视觉
江畔柳前堤2 天前
字节跳动·大模型应用知识手册
前端·人工智能·深度学习·opencv·目标检测·重构·transformer
棣廷2 天前
初识OpenCV——Dlib CNN人脸检测
人工智能·深度学习·opencv