利用OpenCV 和 Dlib 实现年龄性别猜测

打印 上一主题 下一主题

主题 1943|帖子 1943|积分 5829

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
弁言

在计算机视觉领域,人脸检测与属性分析是一项基础且重要的技能。本文将详细介绍怎样利用OpenCV和深度学习模子实现一个实时的人脸检测体系,该体系不仅能定位人脸位置,还能猜测性别和年龄段。这个体系可以广泛应用于智能监控、人机交互、广告投放等场景。
1.体系架构

本体系由三个核心模块组成:

  • 人脸检测模块:定位图像中的人脸位置
  • 性别辨认模块:猜测检测到的人脸性别
  • 年龄猜测模块:估计检测到的人脸年龄段
2.代码剖析

2.1 模子初始化

  1. # 加载预训练模型
  2. faceNet = cv2.dnn.readNet("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
  3. ageNet = cv2.dnn.readNet("age_net.caffemodel", "deploy_age.prototxt")
  4. genderNet = cv2.dnn.readNet("gender_net.caffemodel", "deploy_gender.prototxt")
  5. # 定义年龄段和性别分类标签
  6. ageList = ['0-2岁','4-6岁','8-12岁','15-20岁','25-32岁','38-43岁','48-53岁','60-100岁']
  7. genderList = ['男性','女性']
复制代码
这里我们加载了三个预训练模子:


  • 人脸检测模子(基于SSD框架)
  • 年龄猜测模子(Caffe格式)
  • 性别辨认模子(Caffe格式)
2.2 核心函数实现

(1) 人脸检测函数 getBoxes()

  1. def getBoxes(net, frame):
  2.     # 图像预处理
  3.     blob = cv2.dnn.blobFromImage(frame, 1.0, (300,300), [104,117,123], True, False)
  4.    
  5.     # 模型推理
  6.     net.setInput(blob)
  7.     detections = net.forward()
  8.    
  9.     # 解析检测结果
  10.     faceBoxes = []
  11.     for i in range(detections.shape[2]):
  12.         confidence = detections[0,0,i,2]
  13.         if confidence > 0.7:  # 置信度阈值
  14.             # 坐标转换
  15.             x1 = int(detections[0,0,i,3] * frameWidth)
  16.             y1 = int(detections[0,0,i,4] * frameHeight)
  17.             x2 = int(detections[0,0,i,5] * frameWidth)
  18.             y2 = int(detections[0,0,i,6] * frameHeight)
  19.             faceBoxes.append([x1,y1,x2,y2])
  20.             
  21.             # 绘制人脸框
  22.             cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)
  23.     return frame, faceBoxes
复制代码
这段代码界说了一个名为 getBoxes 的函数,用于通过深度学习模子检测图像中的人脸并返回人脸边界框。以下是详细剖析:

1.函数功能


  • 输入

    • net:预加载的深度学习模子(通常是Caffe或TensorFlow格式的SSD、YOLO等人脸检测模子)
    • frame:输入的图像帧(OpenCV格式的BGR图像)

  • 输出

    • 返回两个值:

      • 绘制了人脸框的图像帧(frame
      • 检测到的人脸边界框列表(faceBoxes,每个框格式为 [x1, y1, x2, y2]



2.关键步骤剖析
(1) 图像预处理
  1. blob = cv2.dnn.blobFromImage(frame, 1.0, (300,300), [104,117,123], True, False)
复制代码


  • 作用:将输入图像转换为深度学习模子所需的Blob格式
  • 参数阐明

    • 1.0:缩放因子(保持原图亮度)
    • (300,300):模子要求的输入尺寸(SSD模子常用)
    • [104,117,123]:BGR通道的均值(用于归一化)
    • True:交换R和B通道(OpenCV用BGR,模子通常必要RGB)
    • False:不裁剪图像

(2) 模子推理
  1. net.setInput(blob)
  2. detections = net.forward()
复制代码


  • detections结构
    返回一个4维数组,格式为(batch_size, 1, num_detections, 7),其中:

    • 最后一个维度7包罗:[_, _, confidence, x1_norm, y1_norm, x2_norm, y2_norm]
    • 坐标是归一化后的值(0~1之间)

(3) 剖析检测结果
  1. for i in range(detections.shape[2]):
  2.     confidence = detections[0,0,i,2]  # 获取置信度
  3.     if confidence > 0.7:  # 过滤低置信度检测
  4.         # 将归一化坐标转换为实际像素坐标
  5.         x1 = int(detections[0,0,i,3] * frameWidth)
  6.         y1 = int(detections[0,0,i,4] * frameHeight)
  7.         x2 = int(detections[0,0,i,5] * frameWidth)
  8.         y2 = int(detections[0,0,i,6] * frameHeight)
  9.         faceBoxes.append([x1,y1,x2,y2])
复制代码


  • 置信度阈值:0.7(可调解,值越高检测越严格)
  • 坐标转换:将模子输出的归一化坐标乘以图像宽/高,得到实际像素坐标
(4) 绘制人脸框
  1. cv2.rectangle(frame, (x1,y1), (x2,y2), (0,255,0), int(round(frameHeight/150)), 6)
复制代码


  • (0,255,0):绿色框(BGR格式)
  • frameHeight/150:动态调解框线粗细(基于图像高度)
  • 6:线型(实线)

3. 典范应用场景
  1. # 示例用法
  2. net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000.caffemodel")
  3. frame = cv2.imread("test.jpg")
  4. processed_frame, boxes = getBoxes(net, frame)
  5. cv2.imshow("Detection", processed_frame)
复制代码


  • 必要预加载的模子文件(如Caffe的.prototxt和.caffemodel)

4. 输出示例
假设检测到一个人脸:


  • faceBoxes:[[120, 80, 320, 280]]
    (表示人脸框左上角(120,80),右下角(320,280))
  • frame:原始图像上绘制了绿色矩形框

5. 注意事项

  • 模子选择
    需确保net与输入的Blob尺寸匹配(这里是300x300的SSD模子)。
  • 性能优化
    高分辨率图像可先缩放到公道尺寸再检测。
  • 阈值调解
    confidence > 0.7可根据实际场景调解(值越高漏检越多,但误检越少)。

6.总结
这段代码实现了一个基于深度学习的人脸检测流水线,完成了从图像预处理、模子推理到结果剖析的全过程,是构建实时人脸辨认、心情分析等体系的核心组件之一。

(2) 中文文本显示函数

  1. def cv2AddChineseText(img, text, position, textColor=(0,255,0), textSize=30):
  2.     # 将OpenCV图像转换为PIL格式
  3.     img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
  4.     draw = ImageDraw.Draw(img)
  5.    
  6.     # 加载中文字体
  7.     fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")
  8.     draw.text(position, text, textColor, font=fontStyle)
  9.    
  10.     # 转换回OpenCV格式
  11.     return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
复制代码
3. 主循环流程

  1. cap = cv2.VideoCapture(0)
  2. while True:
  3.     _, frame = cap.read()
  4.     frame = cv2.flip(frame, 1)  # 镜像处理
  5.    
  6.     # 人脸检测
  7.     frame, faceBoxes = getBoxes(faceNet, frame)
  8.    
  9.     # 对每个检测到的人脸进行属性分析
  10.     for faceBox in faceBoxes:
  11.         x1,y1,x2,y2 = faceBox
  12.         face = frame[y1:y2, x1:x2]
  13.         
  14.         # 性别预测
  15.         blob = cv2.dnn.blobFromImage(face, 1.0, (277,277), mean)
  16.         genderNet.setInput(blob)
  17.         gender = genderList[genderNet.forward()[0].argmax()]
  18.         
  19.         # 年龄预测
  20.         ageNet.setInput(blob)
  21.         age = ageList[ageNet.forward()[0].argmax()]
  22.         
  23.         # 显示结果
  24.         result = f"{gender},{age}"
  25.         frame = cv2AddChineseText(frame, result, (x1,y1-30))
  26.    
  27.     cv2.imshow("Face Analysis", frame)
  28.     if cv2.waitKey(1) == 27:  # ESC键退出
  29.         break
复制代码
4.关键技能点


  • 模子选择

    • 人脸检测:利用轻量级的SSD模子
    • 性别/年龄辨认:利用Caffe框架的CNN模子

  • 图像预处理

    • 均值减法归一化
    • 尺寸调解
    • BGR到RGB通道转换

  • 性能优化

    • 置信度阈值过滤(0.7)
    • 动态调解检测框线宽

5.总结

本文介绍了一个完整的实时人脸属性分析体系,从模子加载、图像预处理到属性猜测和结果显示。该体系展示了怎样将多个深度学习模子集成到一个实用的应用中。可以根据实际需求调解模子参数、优化性能或扩展功能。
完整代码已在上文给出,发起在实际应用中:

  • 根据场景调解置信度阈值
  • 考虑添加异常处理机制
  • 对模子输出进行后处理以提高正确性

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表