做者|Nagesh Singh Chauhan
编译|Flin
来源|towardsdatasciencepython
愈来愈多的应用程序与年龄和性别的自动分类相关,特别是自从社交平台和社交媒体兴起以来。尽管如此,现有的方法在真实图像上的性能仍然明显不足,特别是与最近报道的与人脸识别相关的任务在性能上的巨大飞跃相比。——使用卷积神经网络进行年龄和性别分类(https://talhassner.github.io/home/publication/2015_CVPR)git
年龄和性别是人脸的两个重要属性,在社会交往中起着很是基础的做用,使得从单我的脸图像中估计年龄和性别成为智能应用中的一项重要任务,如访问控制、人机交互、执法、营销智能以及视觉监控等。github
真实世界用例:web
最近我遇到了Quividi,它是一我的工智能软件应用程序,用于根据在线人脸分析检测通过的用户的年龄和性别,并根据目标受众自动开始播放广告。算法
另外一个例子多是AgeBot,它是一个Android应用程序,经过人脸识别从照片中肯定你的年龄。它能够猜想你的年龄和性别,同时也能够在一张照片中找到多张脸,并估计每张脸的年龄。网络
受上述用例的启发,咱们将在本文中构建一个简单的年龄和性别检测模型。因此让咱们从咱们的用例开始:框架
用例——咱们将作一些人脸识别,人脸检测的工做,并且,咱们将使用CNN(卷积神经网络)从youtube视频中预测年龄和性别,只要视频URL是能够用的,你就不须要下载视频。有趣的部分是CNN在视频网址上用于年龄和性别预测。机器学习
要求:
pip install OpenCV-python
numpy
pip install pafy
pip install youtube_dl(了解更多关于youtube-dl的信息:https://rg3.github.io/youtube-dl/)ide
pafy:pafy库用于检索YouTube内容和元数据(如标题、分级、观看次数、持续时间、分级、做者、缩略图、关键字等)。更多有关pafy,点击网址:https://pypi.org/project/pafy/函数
让咱们检查一个样本:
import pafy url = 'https://www.youtube.com/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://www.udemy.com/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://github.com/vdespa/postman-testing-file-uploads
要遵循的步骤:
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: 包含训练神经网络(训练模型)的信息。
从这里(https://talhassner.github.io/home/publication/2015_CVPR) 下载.prtoxt和.caffemodel。
从这里(https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml) 下载用于人脸检测的haar级联。
让咱们开始编码咱们的模型吧。
源代码:
import cv2 import numpy as np import pafy #url of the video to predict Age and gender url = 'https://www.youtube.com/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://www.youtube.com/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”。
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)
image:这是输入图像,咱们要先对其进行预处理,而后再经过咱们的深度神经网络进行分类。
scale factor: 在咱们执行平均值减法以后,咱们能够选择按某个因子缩放图像。这个值默认为1.0(即没有缩放),但咱们也能够提供另外一个值。还要注意的是,比例因子应该是1/σ,由于咱们其实是将输入通道(在平均值减去以后)乘以比例因子。
size: 这里咱们提供卷积神经网络所指望的空间大小。对于大多数目前最早进的神经网络来讲,这多是224×22四、227×227或299×299。
mean:这些是咱们的平均减法值。它们能够是RGB方法的3元组,也能够是单个值,在这种状况下,从图像的每一个通道中减去提供的值。若是要执行平均值减法,请确保按(R,G,B)顺序提供3元组,特别是在使用swapRB=True的默认行为时。
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()的参数以下:
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键退出。
输出:视频URL-1:https://www.youtube.com/watch?v=iH1ZJVqJO3Y
视频URL-2:https://www.youtube.com/watch?v=qLNhVC296YI
颇有趣,不是吗?但不太准确。
正如咱们在本文中看到的,在短短几行代码中,咱们构建了年龄和性别检测模型,从这里开始,你还能够将情感检测和目标检测合并到同一个模型中,并建立一个功能齐全的应用程序。
欢迎关注磐创AI博客站:
http://panchuang.net/
sklearn机器学习中文官方文档:
http://sklearn123.com/
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/