使用卷积神经网络和openCV预测年龄和性别
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使⽤卷积神经⽹络和openCV预测年龄和性别
作者|Nagesh Singh Chauhan
编译|Flin
来源|towardsdatascience
介绍
年龄和性别是⼈脸的两个重要属性,在社会交往中起着⾮常基础的作⽤,使得从单个⼈脸图像中估计年龄和性别成为智能应⽤中的⼀项重要任务,如访问控制、⼈机交互、执法、营销智能以及视觉监控等。
真实世界⽤例:
最近我遇到了Quividi,它是⼀个⼈⼯智能软件应⽤程序,⽤于根据在线⼈脸分析检测经过的⽤户的年龄和性别,并根据⽬标受众⾃动开始播放⼴告。
另⼀个例⼦可能是AgeBot,它是⼀个Android应⽤程序,通过⼈脸识别从照⽚中确定你的年龄。
它可以猜测你的年龄和性别,同时也可以在⼀张照⽚中找到多张脸,并估计每张脸的年龄。
受上述⽤例的启发,我们将在本⽂中构建⼀个简单的年龄和性别检测模型。
所以让我们从我们的⽤例开始:
⽤例——我们将做⼀些⼈脸识别,⼈脸检测的⼯作,⽽且,我们将使⽤CNN(卷积神经⽹络)从youtube视频中预测年龄和性别,只要视频URL是可以⽤的,你就不需要下载视频。
有趣的部分是CNN在视频⽹址上⽤于年龄和性别预测。
让我们检查⼀个样本:
import pafy
url = 'https:///watch?v=c07IsbSNqfI&feature=youtu.be'
vPafy = pafy.new(url)
print vPafy.title
print vPafy.rating
print vPafy.viewcount
print vPafy.author
print vPafy.length
print vPafy.description
Testing file uploads with Postman (multipart/form-data)
4.87096786499
11478
Valentin Despa
1688
➡ ➡ ➡ Check my online course on Postman. Get it for only $10 (limited supply):
https:///postman-the-complete-guide/?couponCode=YOUTUBE10
I will show you how to debug an upload script and demonstrate it with a tool that can make requests encoded as "multipart/form-data" so that you can send also a file. After this, we will go even further and write tests and begin automating the process.
Here is the Git repository containing the files used for this tutorial:
https:///vdespa/postman-testing-file-uploads
要遵循的步骤:
1. 从YouTube获取视频URL。
2. 使⽤Haar级联的⼈脸检测
3. CNN的性别识别
4. CNN的年龄识别
1.从YouTube获取视频⽹址:
获取Youtube视频URL并尝试使⽤pafy获取视频的属性,如上所述。
2. 使⽤Haar级联⼈脸检测:
这是我们⼤多数⼈⾄少听说过的⼀部分。
OpenCV/JavaCV提供了直接的⽅法来导⼊Haar级联并使⽤它们来检测⼈脸。
我不会深⼊解释这⼀部分。
你们可以参考我之前的⽂章来了解更多关于使⽤OpenCV进⾏⼈脸检测的信息。
⽂章地址:
3. CNN的性别识别:
使⽤OpenCV的fisherfaces实现的性别识别⾮常流⾏,你们中的⼀些⼈可能也尝试过或阅读过它。
但是,在这个例⼦中,我将使⽤不同的⽅法来识别性别。
2015年,以⾊列两名研究⼈员Gil Levi和Tal Hassner引⼊了这种⽅法。
我在这个例⼦中使⽤了他们训练的CNN模型。
我们将使⽤OpenCV的dnn包,它代表“深度神经⽹络”。
在dnn包中,OpenCV提供了⼀个名为Net的类,可以⽤来填充神经⽹络。
此外,这些软件包还⽀持从知名的深度学习框架(如caffe、
tensorflow和torch)导⼊神经⽹络模型。
我前⾯提到的研究⼈员已经将他们的CNN模型发布为caffe模型。
因此,我们将使⽤CaffeImporter将该模型导⼊到我们的应⽤程序中。
4. CNN的年龄识别
这与性别识别部分很相似,只是对应的prototxt⽂件和caffe模型⽂件是"deploy_agenet.prototxt"和”age_net.caffemodel”. 此外,CNN在该CNN中的输出层(概率层)由8个年龄层的8个值组成(“0-2”、“4-6”、“8-13”、“15-20”、“25-32”、“38-43”、“48-53”和“60-”)
Caffe模型具有2个相关⽂件,
1. prototxt: 这⾥是CNN的定义。
这个⽂件定义了神经⽹络的各个层,每个层的输⼊、输出和函数。
2. caffemodel: 包含训练神经⽹络(训练模型)的信息。
让我们开始编码我们的模型吧。
源代码:
import cv2
import numpy as np
import pafy
#url of the video to predict Age and gender
url = 'https:///watch?v=c07IsbSNqfI&feature=youtu.be'
vPafy = pafy.new(url)
play = vPafy.getbest(preftype="mp4")
cap = cv2.VideoCapture(play.url)
cap.set(3, 480) #set width of the frame
cap.set(4, 640) #set height of the frame
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
age_list = ['(0, 2)', '(4, 6)', '(8, 12)', '(15, 20)', '(25, 32)', '(38, 43)', '(48, 53)', '(60, 100)']
gender_list = ['Male', 'Female']
def load_caffe_models():
age_net = cv2.dnn.readNetFromCaffe('deploy_age.prototxt', 'age_net.caffemodel')
gender_net = cv2.dnn.readNetFromCaffe('deploy_gender.prototxt', 'gender_net.caffemodel')
return(age_net, gender_net)
def video_detector(age_net, gender_net):
font = cv2.FONT_HERSHEY_SIMPLEX
while True:
ret, image = cap.read()
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
if(len(faces)>0):
print("Found {} faces".format(str(len(faces))))
for (x, y, w, h )in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (255, 255, 0), 2)
#Get Face
face_img = image[y:y+h, h:h+w].copy()
blob = cv2.dnn.blobFromImage(face_img, 1, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
#Predict Gender
gender_net.setInput(blob)
gender_preds = gender_net.forward()
gender = gender_list[gender_preds[0].argmax()]
print("Gender : " + gender)
#Predict Age
age_net.setInput(blob)
age_preds = age_net.forward()
age = age_list[age_preds[0].argmax()]
print("Age Range: " + age)
overlay_text = "%s %s" % (gender, age)
cv2.putText(image, overlay_text, (x, y), font, 1, (255, 255, 255), 2, cv2.LINE_AA)
cv2.imshow('frame', image)
#0xFF is a hexadecimal constant which is 11111111 in binary.
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if __name__ == "__main__":
age_net, gender_net = load_caffe_models()
video_detector(age_net, gender_net)
现在让我们⼀起来理解代码:
步骤1:导⼊所有必需的库。
import cv2
import numpy as np
import pafy
步骤2:获取Youtube视频URL并创建⼀个对象“play”,该对象包含webm/mp4格式的视频的最佳分辨率。
url = 'https:///watch?v=c07IsbSNqfI&feature=youtu.be'
vPafy = pafy.new(url)
play = vPafy.getbest(preftype="mp4")
第三步:通常,我们必须⽤相机捕捉现场的视频流。
OpenCV提供了⼀个⾮常简单的接⼝。
我们可以从相机中捕捉视频,将其转换成灰度视频并显⽰出来。
只是⼀个简单的开始。
要捕获视频,需要创建视频捕获对象。
它的参数可以是设备索引或视频⽂件的名称。
设备索引只是指定哪个摄像机的数字。
通常会连接⼀个摄像头(如我的情况)。
所以我只传递0(或-1)。
可以通过传递1等来选择第⼆个摄影机。
之后,你可以逐帧捕获。
cap = cv2.VideoCapture(0) #if you are using webcam
但在我的例⼦中,我正在读取⼀个在线视频URL,为此,我将把“play”对象传递给VideoCapture()。
cap = cv2.VideoCapture(play.url)
步骤4:使⽤set()设置视频帧的⾼度和宽度。
cap.set(propId, value),这⾥3是宽度的propertyId,4是⾼度的propertyId。
cap.set(3, 480) #set width of the frame
cap.set(4, 640) #set height of the frame
步骤5:创建3个单独的列表,⽤于存储Model_Mean_值、年龄和性别。
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
age_list = ['(0, 2)', '(4, 6)', '(8, 12)', '(15, 20)', '(25, 32)', '(38, 43)', '(48, 53)', '(60, 100)']
gender_list = ['Male', 'Female']
第六步:我定义了⼀个函数来加载caffemodel和prototxt的年龄和性别检测器,这些基本上都是预先训练好的CNN模型来进⾏检测。
def load_caffe_models():
age_net = cv2.dnn.readNetFromCaffe('deploy_age.prototxt', 'age_net.caffemodel')
gender_net = cv2.dnn.readNetFromCaffe('deploy_gender.prototxt', 'gender_net.caffemodel')
return(age_net, gender_net)
步骤7:现在我们将执⾏⼈脸检测、年龄检测和性别检测,并为此在你的主函数内创建⼀个函数video_detector(age_net,gender_net),并将age_net和gender_net作为其参数。
if __name__ == "__main__":
age_net, gender_net = load_caffe_models()
video_detector(age_net, gender_net)
步骤8:读取步骤3中从VideoCapture()创建的cap对象。
cap.read()返回布尔值(True / False)。
如果正确读取框架,则它将为True。
所以你可以通过检查这个返回值来检查视频的结尾。
有时,cap可能尚未初始化捕获。
在这种情况下,此代码显⽰错误。
你可以通过cap.isOpened()⽅法检查它是否已初始化. 如果是真的就继续。
否则,请使⽤cap.open()打开它.
ret, image = cap.read()
步骤9:将图像转换为灰度图像,因为OpenCV⼈脸检测器需要灰度图像。
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
步骤10:加载⽤于⼈脸检测的预构建模型。
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
步骤11:现在,我们如何使⽤级联分类器从图像中检测⼈脸?
OpenCV的CascadedClassifier再次使其变得简单,detectMultiScale()可以准确地检测你需要的内容。
detectMultiScale(image, scaleFactor, minNeighbors)
下⾯是应该传递给detectMultiScale()的参数。
这是⼀个检测对象的通⽤函数,在这种情况下,它将检测⼈脸,因为我们在⼈脸级联中调⽤了此函数。
如果找到⼀个⼈脸,则返回⼀个所述⼈脸的位置列表,格式为“Rect(x,y,w,h)”,如果没有,则返回“None”。
Image:第⼀个输⼊是灰度图像。
scaleFactor:这个函数补偿当⼀张脸看起来⽐另⼀张脸⼤时发⽣的⼤⼩错误感知,因为它更靠近相机。
minNeighbors:⼀种使⽤移动窗⼝检测对象的检测算法,它通过定义在当前窗⼝附近找到多少个对象,然后才能声明找到的⼈脸。
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
第12步:循环浏览⼈脸列表并在视频中的⼈脸上绘制矩形。
在这⾥,我们基本上是寻找⾯孔,分解⾯孔,它们的⼤⼩,并绘制矩形。
for (x, y, w, h )in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (255, 255, 0), 2)
# Get Face
face_img = image[y:y+h, h:h+w].copy()
步骤13:OpenCV提供了⼀个函数,可以帮助对图像进⾏预处理,以便进⾏深度学习分类:blobFromImage()。
它执⾏:
平均减法
缩放⽐例
和可选的通道交换
所以blobFromImage4维的blob是从图像创建的。
可选地调整图像⼤⼩并从中⼼裁剪图像,减去平均值,按⽐例因⼦缩放值,交换蓝⾊和红⾊通道
blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size, mean, swapRB=True)
1. image:这是输⼊图像,我们要先对其进⾏预处理,然后再通过我们的深度神经⽹络进⾏分类。
2. scale factor: 在我们执⾏平均值减法之后,我们可以选择按某个因⼦缩放图像。
这个值默认为1.0(即没有缩放),但我们也可以提供
另⼀个值。
还要注意的是,⽐例因⼦应该是1/σ,因为我们实际上是将输⼊通道(在平均值减去之后)乘以⽐例因⼦。
3. size: 这⾥我们提供卷积神经⽹络所期望的空间⼤⼩。
对于⼤多数⽬前最先进的神经⽹络来说,这可能是224×224、227×227或
299×299。
4. mean:这些是我们的平均减法值。
它们可以是RGB⽅法的3元组,也可以是单个值,在这种情况下,从图像的每个通道中减去提供的
值。
如果要执⾏平均值减法,请确保按(R,G,B)顺序提供3元组,特别是在使⽤swapRB=True的默认⾏为时。
5. swapRB:OpenCV假设图像是BGR通道顺序的;但是,平均值假设我们使⽤的是RGB顺序。
为了解决这个差异,我们可以通过将这个
值设置为True来交换图像中的R和B通道。
默认情况下,OpenCV为我们执⾏此通道交换。
blob = cv2.dnn.blobFromImage(face_img, 1, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
第14步:预测性别。
#Predict Gender
gender_net.setInput(blob)
gender_preds = gender_net.forward()
gender = gender_list[gender_preds[0].argmax()]
第15步:预测年龄。
#Predict Age
age_net.setInput(blob)
age_preds = age_net.forward()
age = age_list[age_preds[0].argmax()]
第16步:现在我们必须使⽤openCV的put text()模块将⽂本放到输出框架上。
putText()的参数如下:
要写⼊的⽂本数据
放置位置坐标(即数据开始的左下⾓)。
字体类型(请检查cv2.putText()⽂档以获取⽀持的字体)
字体⽐例(指定字体⼤⼩)
常规的东西,如颜⾊,厚度,线型等。
为了更好的外观,线型=cv2.LINE_AA是推荐的。
overlay_text = "%s %s" % (gender, age)
cv2.putText(image, overlay_text, (x, y), font, 1, (255, 255, 255), 2, cv2.LINE_AA)
第17步:最后打印你的最终输出。
cv2.imshow('frame', image)
最后我们有:
if cv2.waitKey(1) & 0xFF == ord('q'):
break
我们的程序等待⽤户按下⼀个键最多1毫秒。
然后,它获取读取的键的值,并将其与0xFF进⾏⽐较,0xFF删除底部8位以上的任何内容,并将结果与字母q的ASCII码进⾏⽐较,这意味着⽤户已决定通过按键盘上的q键退出。
很有趣,不是吗?但不太准确。
结论:
正如我们在本⽂中看到的,在短短⼏⾏代码中,我们构建了年龄和性别检测模型,从这⾥开始,你还可以将情感检测和⽬标检测合并到同⼀
个模型中,并创建⼀个功能齐全的应⽤程序。