计算机视觉(opencv)——基于 OpenCV DNN 的实时人脸检测 + 年龄与性别识别

基于 OpenCV DNN 的实时人脸检测与年龄、性别识别系统全解析(含完整源码)

一、项目概述

在计算机视觉领域中,人脸检测 与**人脸属性识别(如年龄、性别)**是最典型的视觉分析任务之一。本文将带你从零构建一个完整的"摄像头实时人脸检测 + 年龄识别 + 性别识别"系统,基于 OpenCV 的 DNN 模块和预训练的 Caffe 模型实现。

系统功能:

  • 自动检测摄像头中的人脸;

  • 实时预测每张人脸的年龄段与性别;

  • 中文可视化输出;

  • 结构清晰、易于扩展(可添加情绪识别、人脸识别等模块)。


二、完整源码

以下是完整的 Python 实现代码,包含详细注释,直接可运行。

复制代码
import cv2
from PIL import Image, ImageDraw, ImageFont
import numpy as np

# =====模型初始化========
# 模型(网络模型/预训练模型):face/age/gender(脸、年龄、性别)
faceProto = "model/opencv_face_detector.pbtxt"
faceModel = "model/opencv_face_detector_uint8.pb"
ageProto = "model/deploy_age.prototxt"
ageModel = "model/age_net.caffemodel"
genderProto = "model/deploy_gender.prototxt"
genderModel = "model/gender_net.caffemodel"

# 加载网络
ageNet = cv2.dnn.readNet(ageModel, ageProto)  # 年龄模型
genderNet = cv2.dnn.readNet(genderModel, genderProto)  # 性别模型
faceNet = cv2.dnn.readNet(faceModel, faceProto)  # 人脸检测模型

# ============变量初始化==============
# 年龄段和性别
ageList = ['0-2岁', '4-6岁', '8-12岁', '15-20岁', '25-32岁', '38-43岁', '48-53岁', '60-100岁']
genderList = ['男性', '女性']
mean = (78.4263377603, 87.7689143744, 114.895847746)  # 模型均值

# ========自定义函数,获取人脸包围框===============
def getBoxes(net, frame):
    frameHeight, frameWidth = frame.shape[:2]  # 获取图像高度、宽度
    blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300),
                                 [104, 117, 123], True, False)
    net.setInput(blob)  # 调用网络模型输入图片
    detections = net.forward()  # 前向传播输出检测结果

    faceBoxes = []
    for i in range(detections.shape[2]):
        confidence = detections[0, 0, i, 2]  # 置信度
        if confidence > 0.7:
            x1 = int(detections[0, 0, i, 3] * frameWidth)
            y1 = int(detections[0, 0, i, 4] * frameHeight)
            x2 = int(detections[0, 0, i, 5] * frameWidth)
            y2 = int(detections[0, 0, i, 6] * frameHeight)
            faceBoxes.append([x1, y1, x2, y2])
            cv2.rectangle(frame, (x1, y1), (x2, y2),
                          (0, 255, 0), int(round(frameHeight / 150)), 6)
    return frame, faceBoxes


def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    """ 向图片中添加中文 """
    if (isinstance(img, np.ndarray)):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    draw = ImageDraw.Draw(img)
    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)


# =========摄像头捕获与预测循环=========
cap = cv2.VideoCapture(0)
while True:
    _, frame = cap.read()
    # frame = cv2.flip(frame, 1) # 镜像处理

    frame, faceBoxes = getBoxes(faceNet, frame)
    if not faceBoxes:
        print("当前镜头中没有人")
        continue

    for faceBox in faceBoxes:
        x1, y1, x2, y2 = faceBox
        face = frame[max(0, y1):min(y2, frame.shape[0]),
                     max(0, x1):min(x2, frame.shape[1])]

        blob = cv2.dnn.blobFromImage(face, 1.0, (227, 227), mean)
        # 性别预测
        genderNet.setInput(blob)
        genderOuts = genderNet.forward()
        gender = genderList[genderOuts[0].argmax()]
        # 年龄预测
        ageNet.setInput(blob)
        ageOuts = ageNet.forward()
        age = ageList[ageOuts[0].argmax()]

        label = "{}, {}".format(gender, age)
        frame = cv2AddChineseText(frame, label, (x1, y1 - 30))
        cv2.imshow("result", frame)

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

cap.release()
cv2.destroyAllWindows()

三、逐段解析与原理讲解

1️⃣ 模型加载

cv2.dnn.readNet() 可加载多种模型格式(Caffe、TensorFlow、ONNX 等)。

DNN 模块是 OpenCV 的轻量推理引擎,可以在 CPU 上直接运行深度学习模型,无需 TensorFlow/PyTorch 环境,非常适合嵌入式或教学场景。

2️⃣ blobFromImage 的意义

cv2.dnn.blobFromImage() 是预处理函数,主要步骤:

  • 调整输入大小(如 227×227)

  • 减去每个通道的均值(mean)

  • 转换通道顺序(BGR→RGB)

  • 生成四维输入张量 [batch, channels, height, width]

这确保输入图像的格式与模型训练时一致,否则输出会失真。

3️⃣ 人脸检测模块

opencv_face_detector_uint8.pb 模型基于 SSD(Single Shot MultiBox Detector)网络结构。

输出 detections 的形状为 [1, 1, N, 7],每个检测包含:

复制代码
[image_id, class_id, confidence, x1, y1, x2, y2]

当置信度大于 0.7 时,才认为检测到人脸。

4️⃣ 中文绘制函数

OpenCV 自带的 cv2.putText() 不支持中文,需借助 Pillow:

  • 把 OpenCV 图像转为 Pillow Image;

  • ImageDraw 绘制文字;

  • 再转回 OpenCV 格式。

字体文件 simsun.ttc 在 Windows 系统中路径为:

复制代码
C:\Windows\Fonts\simsun.ttc

如在 Linux / macOS,需要指定可用中文字体路径。

5️⃣ 年龄与性别预测

输入到 ageNetgenderNet 的数据都是 blob,经前向传播 forward() 输出各类别概率。

年龄模型输出 8 个概率,对应八个年龄段:

复制代码
['0-2', '4-6', '8-12', '15-20', '25-32', '38-43', '48-53', '60-100']

性别模型输出 2 个概率:['Male', 'Female']

我们取最大概率对应类别的索引,匹配列表即得预测结果。


四、运行效果与测试说明

运行程序后,摄像头开启:

  • 检测到人脸会显示绿色矩形框;

  • 框上方标注中文"性别, 年龄段";

  • 没有人脸时会在控制台输出"当前镜头中没有人"。

按下 ESC 即可退出。

测试环境建议:

  • 光线充足;

  • 人脸正对摄像头;

  • 距离 0.5--1 米范围;

  • 分辨率建议 640×480 或 720p。


五、常见问题与解决方案

问题 原因 解决方法
报错找不到模型文件 路径错误或模型未下载 确保路径与脚本一致
中文乱码 字体文件缺失 使用系统字体或改用英文
摄像头打不开 设备占用或索引错误 改用 cv2.VideoCapture(1)
性别识别不准 输入未裁剪人脸 使用裁剪后的人脸区域
延迟高 模型较大 使用 GPU 或 OpenVINO 加速

六、性能优化建议

  1. 模型加速:

    复制代码
    faceNet.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
    faceNet.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)

    在支持 CUDA 的系统上显著加速。

  2. 多线程采集:

    视频采集线程与推理线程分离,可防止阻塞。

  3. 帧率控制:

    若实时性要求不高,可每隔 5 帧进行一次推理。

  4. 轻量模型替换:

    可用 MobileNet 或 ONNX 模型取代 Caffe 模型以提升速度。


七、伦理与隐私声明

  • 隐私保护:本系统仅作技术演示,请勿将人脸数据用于未经授权的采集或识别。

  • 偏差问题:模型在不同种族、光照、角度下可能产生偏差,不适用于安全或法律决策。

  • 数据安全:在生产系统中应遵守《个人信息保护法》等相关法规,明确用途与存储策略。


八、结语与扩展方向

本文展示了如何用简洁的 Python 代码构建一个完整的"人脸检测 + 年龄/性别识别"系统。整个流程使用 OpenCV 的 DNN 模块,无需额外深度学习框架即可实现。

扩展方向包括:

  • 加入 人脸表情识别

  • 添加 人脸关键点定位 提升检测精度;

  • 将系统部署到 Flask Web 服务移动端

  • 利用 ONNX Runtime / TensorRT 实现高性能推理。

通过对该项目的理解,你不仅能掌握人脸属性识别的流程,也能深入理解深度学习模型在视觉任务中的应用方式。

相关推荐
算法打盹中7 小时前
计算机视觉:基于 YOLO 的轻量级目标检测与自定义目标跟踪原理与代码框架实现
图像处理·yolo·目标检测·计算机视觉·目标跟踪
sali-tec9 小时前
C# 基于halcon的视觉工作流-章42-手动识别文本
开发语言·人工智能·算法·计算机视觉·c#·ocr
AndrewHZ13 小时前
【图像处理基石】暗光增强算法入门:从原理到实战(Python+OpenCV)
图像处理·python·opencv·算法·计算机视觉·cv·暗光增强
七元权14 小时前
论文阅读-FoundationStereo
论文阅读·深度学习·计算机视觉·零样本·基础模型·双目深度估计
~光~~17 小时前
【环境配置 安装 】RK3588+Ubuntu20.04+cmake3.22+opencv4.54
opencv·ubuntu·rk3588
研梦非凡17 小时前
ShapeLLM: 用于具身交互的全面3D物体理解
人工智能·深度学习·计算机视觉·3d·架构·数据分析
CoovallyAIHub18 小时前
YOLO26学界首评:四大革新点究竟有多强?
深度学习·算法·计算机视觉
2401_8414956418 小时前
【计算机视觉】霍夫变换函数的参数调整
人工智能·python·算法·计算机视觉·霍夫变换·直线检测·调整策略
bylander19 小时前
【论文阅读】通义实验室,VACE: All-in-One Video Creation and Editing
论文阅读·人工智能·计算机视觉·音视频