注意:本文引用自专业人工智能社区Venus AI
更多AI知识请参考原站 ([www.aideeplearning.cn])
性别和年龄检测 Python 项目
首先介绍性别和年龄检测的高级Python项目中使用的专业术语
什么是计算机视觉?
计算机视觉是使计算机能够像人类一样查看和识别数字图像和视频的研究领域。它面临的挑战很大程度上源于对生物视觉的有限理解。计算机视觉涉及获取、处理、分析和理解数字图像,以从现实世界中提取高维数据,从而生成可用于做出决策的符号或数字信息。该过程通常包括对象识别、视频跟踪、运动估计和图像恢复等实践。
什么是 OpenCV?
OpenCV是开源计算机视觉的缩写。顾名思义,它是一个开源计算机视觉和机器学习库。该库能够处理实时图像和视频,同时还具有分析功能。它支持深度学习框架Tensorflow、Caffe 和 PyTorch。
什么是CNN?
CNN即卷积神经网络,是一种广泛用于图像识别和处理的深度神经网络 (DNN) 。它具有输入层和输出层以及多个隐藏层,其中许多是卷积层。在某种程度上,CNN 是正则化的多层感知器。
性别和年龄检测——目标
构建一个性别和年龄检测器,可以在 Adience 数据集上使用深度学习模型来大致猜测图片中人(脸部)的性别和年龄。
性别和年龄检测——关于该项目
在这个 Python 项目中,我们将使用深度学习从单张脸部图像中准确识别一个人的性别和年龄。我们将使用Tal Hassner 和 Gil Levi训练的模型。预测的性别可以是“男性”和“女性”之一,预测的年龄可以是以下范围之一 – (0 – 2)、(4 – 6)、(8 – 12)、(15 – 20) 、(25 – 32)、(38 – 43)、(48 – 53)、(60 – 100)(最终 softmax 层中的 8 个节点)。由于化妆、灯光、障碍物和面部表情等因素,很难从单张图像中准确猜测出确切的年龄。因此,我们将其视为分类问题,而不是回归问题。项目的结果展示动态图如下所示,请点击观看:
ev_20240225_131028
CNN 架构
这个 python 项目的卷积神经网络很简单,有 3 个卷积层:
- 卷积层:96 个节点,卷积核大小 7
- 卷积层:256 个节点,卷积核大小 5
- 卷积层:384 个节点,卷积核大小 3
它有 2 个全连接层,每个层有 512 个节点,以及一个 softmax 类型的最终输出层。
要开始 python 项目,我们将:
- 检测人脸
- 分为男/女
- 分为 8 个年龄范围之一
- 将结果放在图像上并显示
数据集
对于这个 python 项目,我们将使用 Adience 数据集;该数据集可在公共领域使用,您可以在此处找到它。该数据集作为人脸照片的基准,包含各种现实世界的成像条件,如噪声、照明、姿势和外观。这些图像是从 Flickr 相册中收集的,并根据知识共享 (CC) 许可进行分发。它共有 26,580 张照片,涉及 8 个年龄段(如上所述)的 2,284 名拍摄对象,大小约为 1GB。我们将使用的模型已经在此数据集上进行了训练。
先决条件
您需要安装 OpenCV (cv2) 才能运行该项目。可以用 pip- 来做到这一点
pip install opencv-python
您需要的其他包是 math 和 argparse,它们是标准 Python 库的一部分。
项目的目录结构
项目的目录结构如下:
- opencv_face_ detector.pbtxt
- opencv_face_ detector_uint8.pb
- Age_deploy.prototxt
- Age_net.caffemodel
- gander_deploy.prototxt
- gander_net.caffemodel
- main.py
- 一示例的图片
关于上述文件类型的解释:
- .pb文件:这是一个TensorFlow用于保存模型的文件格式。它包含了模型的结构(也就是神经网络的架构)和模型训练后的权重(即模型在训练过程中学到的信息)。使用这个文件,我们可以运行一个已经训练好的模型来进行面部检测。
- .pbtxt文件:与.pb文件类似,但它以文本格式存储protobuf数据,而不是二进制格式。这使得文件内容可以直接阅读和编辑,但通常大小会更大。
- TensorFlow文件:TensorFlow是一个流行的机器学习框架,用于创建和训练神经网络。.pb和.pbtxt文件都是TensorFlow用来保存模型的文件格式。
- .prototxt文件:这些文件用于描述神经网络的结构,即网络中每一层应该如何构建。这对于构建用于年龄和性别识别的模型特别重要。
- .caffemodel文件:这种文件格式是Caffe框架的一部分,另一个流行的机器学习框架。.caffemodel文件保存了训练后的模型参数,即网络每一层的权重和偏置。这对于运行已经训练好的年龄和性别识别模型至关重要。
注意:上述这些文件是博主将项目编译之后得到的结果,而不是原始项目代码。这些文件类型通常用于存储训练好的模型和它们的配置,而不是用于存储原始的源代码。原代码详见Github:https://github.com/eranid/adience_align/tree/master
main.py脚本详解:
导入库:
-
import cv2
: 导入 OpenCV 库,用于计算机视觉相关任务。 -
import math
: 导入数学库,提供数学运算支持。 -
import argparse
: 导入参数解析库,用于解析命令行参数。
import cv2
import math
import argparse
highlightFace 函数:
- 这个函数用于在图像中突出显示人脸。
-
frame
: 要处理的图像。 -
conf_threshold
: 用于确定检测是否有效的置信度阈值。 - 函数首先创建图像的副本,然后根据图像的尺寸生成一个 blob(神经网络输入)。
- 使用提供的神经网络 (
net
) 对 blob 进行前向传播,以检测图像中的人脸。 - 检测到的每个人脸都被添加到
faceBoxes
列表中,并在图像上绘制矩形框以突出显示人脸。 - 返回处理后的图像和检测到的人脸框列表。
def highlightFace(net, frame, conf_threshold=0.7):
frameOpencvDnn=frame.copy()
frameHeight=frameOpencvDnn.shape[0]
frameWidth=frameOpencvDnn.shape[1]
blob=cv2.dnn.blobFromImage(frameOpencvDnn, 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>conf_threshold:
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(frameOpencvDnn, (x1,y1), (x2,y2), (0,255,0), int(round(frameHeight/150)), 8)
return frameOpencvDnn,faceBoxes
解析命令行参数:
- 使用
argparse
库来解析命令行输入的参数。这里解析了--image
参数,允许用户指定一个图像文件的路径。 - 若不指定,默认使用摄像头采集当前画面进行实时检测。
parser=argparse.ArgumentParser()
parser.add_argument('--image')
args=parser.parse_args()
加载模型:
- 指定了用于人脸检测、年龄和性别预测的模型文件的路径。
- 使用
cv2.dnn.readNet
从这些路径加载对应的模型。 -
MODEL_MEAN_VALUES
: 在预处理图像时用于归一化的均值。 -
ageList
和genderList
: 分别包含年龄范围和性别类别的列表。
faceProto="opencv_face_detector.pbtxt"
faceModel="opencv_face_detector_uint8.pb"
ageProto="age_deploy.prototxt"
ageModel="age_net.caffemodel"
genderProto="gender_deploy.prototxt"
genderModel="gender_net.caffemodel"
MODEL_MEAN_VALUES=(78.4263377603, 87.7689143744, 114.895847746)
ageList=['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']
genderList=['Male','Female']
faceNet=cv2.dnn.readNet(faceModel,faceProto)
ageNet=cv2.dnn.readNet(ageModel,ageProto)
genderNet=cv2.dnn.readNet(genderModel,genderProto)
处理视频流:
- 使用
cv2.VideoCapture
打开视频源(从文件或摄像头)。 - 在一个循环中读取每一帧图像,并使用
highlightFace
函数检测人脸。
video=cv2.VideoCapture(args.image if args.image else 0)
性别和年龄预测:
- 对于检测到的每个人脸,截取人脸区域并为性别和年龄预测网络准备输入 blob。
- 运行性别和年龄预测网络,并从
genderList
和ageList
中获取预测结果。 - 将预测结果(性别和年龄)打印出来,并在图像上绘制包含这些信息的文本。
- 使用
cv2.imshow
显示带有预测结果的图像。 - 循环持续进行,直到用户按键中断。
padding=20
while cv2.waitKey(1)<0:
hasFrame,frame=video.read()
if not hasFrame:
cv2.waitKey()
break
resultImg,faceBoxes=highlightFace(faceNet,frame)
if not faceBoxes:
print("No face detected")
for faceBox in faceBoxes:
face=frame[max(0,faceBox[1]-padding):
min(faceBox[3]+padding,frame.shape[0]-1),max(0,faceBox[0]-padding)
:min(faceBox[2]+padding, frame.shape[1]-1)]
blob=cv2.dnn.blobFromImage(face, 1.0, (227,227), MODEL_MEAN_VALUES, swapRB=False)
genderNet.setInput(blob)
genderPreds=genderNet.forward()
gender=genderList[genderPreds[0].argmax()]
print(f'Gender: {gender}')
ageNet.setInput(blob)
agePreds=ageNet.forward()
age=ageList[agePreds[0].argmax()]
print(f'Age: {age[1:-1]} years')
cv2.putText(resultImg, f'{gender}, {age}', (faceBox[0], faceBox[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,255,255), 2, cv2.LINE_AA)
cv2.imshow("Detecting age and gender", resultImg)
性别和年龄检测的 Python 项目示例
除了捕获摄像头画面进行检测外,脚本也支持在我们自己的一些图像上尝试这个性别和年龄分类器。
我们将进入命令提示符,使用图像选项运行脚本并指定要分类的图像:
输入:
pthon main.py --image girl2.jpg
输出:
资源:
在这个 python 项目中,我们实现了一个 CNN 来从单张脸部图片或视频流中检测性别和年龄。
项目代码压缩包和项目的数据集,请原站 ([www.aideeplearning.cn])
如果需要项目的原代码,请访问github:
GilLevi/AgeGenderDeepLearning on GitHub.
© 版权声明
文章版权归作者所有,未经允许,请勿转载,私自转载将严厉追究法律责任。