(图片来源网络,侵删)
目前,随着社交平台以及社交媒体的兴起,年龄与性别自动分类开始与越来越多的应用相关联然而,尤其是与近来在人脸识别任务中取得的快速进展相比,使用现有方法识别真实图像的结果并不尽如人意比如……其实,年龄与性别作为面部的两个关键属性,在社交互动中发挥着根本作用因此,对人脸图像进行年龄性别评估在一些智能应用,如访问权限、人机交互、执法、营销情报和视觉监控等领域具有重要意义实际应用1. 一款名为Quividi的人工智能应用软件,可通过在线面部分析推测用户年龄与性别,并根据分析结果为目标受众自动播放广告2. 安卓应用程序AgeBot,可对用户照片进行面部识别从而推测其年纪该应用不但支持单人年龄和性别推测,同时还能识别多人照片中的不同人脸并推测相应年龄受上述用例启发,本篇文章将详细介绍构建一个简单的年龄性别检测模型的相关步骤那么就从用例开始介绍吧: 用例人脸识别、人脸检测、以及使用CNN(卷积神经网络)对youtube视频里人物进行年龄与性别预测,视频无需下载,仅需保存网址链接(URL)在此,使用CNN来预测视频URLs中的人物年龄性别,这一过程将十分有趣 准备工作Pip install OpenCV-pythonnumpypip install pafypip install youtube_dl(以了解youtube_dl更多相关信息) pafyPafy库用于检索YouTube内容和元数据(包括标题、分级、点击率、持时长、评分、作者、缩略图、关键词等)要了解更多有关pafy的信息,我们来看看一个样本:importpafyurl='https://www.youtube.com/watch?v=c07IsbSNqfI&feature=youtu.be'vPafy= pafy.new(url)printvPafy.titleprintvPafy.ratingprintvPafy.viewcountprintvPafy.authorprintvPafy.lengthprintvPafy.description输出请在Postman上下载测试文件 (multipart/form-data)4.8709678649911478瓦伦汀·德斯帕(Valentin Despa)1688以下是包含本教程所用文件的Git仓库:https://github.com/vdespa/postman-testing-file-uploads演示步骤1. 从YouTube获取视频网址获取Youtube视频网址,并如上所述用pafy获取视频的属性2. 使用Haar cascades检测人脸大多数人至少对这一部分内容有所耳闻OpenCV / JavaCV提供了导入Haar-cascades并将其用来检测面部的直接方法3. 使用CNN识别性别使用OpenCV的fisherfaces来识别性别十分流行,有人可能已经尝试此方法或阅读过相关文章但本文将采取另一种识别性别的方法这一方法最早在2015年由两位以色列研究人员Gil Levi和Tal Hassner首次使用本文所用CNN模型便是由这二人所创建同时,还会用到OpenCV的dnn程序包,dnn代表“深度神经网络”(DeepNatural Networks)在dnn程序包中,OpenCV提供了一个名为Net的类,用于填充神经网络此外,这些软件包支持从众所周知的深度学习框架(如caffe,tensorflow和torch)导入神经网络模型上文提到的研究员已经发布了他们的CNN caffe模型因此,在此可以使用CaffeImporter将该模型导入到应用程序中4. 使用CNN识别年龄与性别识别几乎一致,只是将相应的prototxt文件和caffe模型文件改为“deploy_agenet.prototxt”和“age_net.caffemodel”此外,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 - 包含经过训练的神经网络(训练模型)信息下载.prtotxt和.caffemodel:https://talhassner.github.io/home/publication/2015_CVPR下载用于人脸检测的haar cascade:https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml接下来开始编写模型源代码importcv2importnumpy as npimportpafy#urlof the video to predict Age and genderurl= '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 framecap.set(4,640) #set height of the frameMODEL_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']defload_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)defvideo_detector(age_net, gender_net): font = cv2.FONT_HERSHEY_SIMPLEXwhileTrue: 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)#GetFace face_img = image[y:y+h, h:h+w].copy() blob = cv2.dnn.blobFromImage(face_img, 1,(227, 227), MODEL_MEAN_VALUES, swapRB=False)#PredictGender gender_net.setInput(blob) gender_preds = gender_net.forward() gender =gender_list[gender_preds[0].argmax()] print(\"Gender : \" + gender)#PredictAge 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) #0xFFis a hexadecimal constant which is 11111111 in binary.ifcv2.waitKey(1) & 0xFF == ord('q'): breakif__name__ == \"__main__\":age_net,gender_net = load_caffe_models()video_detector(age_net,gender_net)下面分析一下源代码:第1步: 导入全部所需库importcv2importnumpy as npimportpafy第2步:获取Youtube视频URL,并创建对象‘play’包含webm/mp4格式下视频最佳分辨率url='https://www.youtube.com/watchv=c07IsbSNqfI&feature=youtu.be'vPafy= pafy.new(url)play= vPafy.getbest(preftype=\"mp4\")第3步:通常情况下必须用摄相机捕捉直播OpenCV为此提供了一个非常简单的接口从摄相机捕获到的视频可以转换为灰度视频来显示操作起来也很容易捕获视频需要先创建视频捕获对象参数可以是设备索引或视频文件名称设备索引通过数字指定连接的摄像头通常会连接一台摄像机(如本文所示)因此,只用输入0(或-1)也可以通过输入1来选择第二个摄像机,依此类推如此一来,便可以逐帧捕获cap= cv2.VideoCapture(0) #if you are using webcam但本文所示案例使用的是在线视频网址,因此要在VideoCapture()函数中输入对象'play'cap= cv2.VideoCapture(play.url)第4步:使用set()设置视频的帧高和帧宽cap.set(propId,value),代码中的3代表帧宽,4代表帧高cap.set(3,480) #set width of the framecap.set(4,640) #set height of the frame第5步:创建3个单独列表分别存储Model_Mean_Values,Age和Gender数据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= ['男','女']第6步:定义一个函数来加载年龄和性别检测器的caffe 模型和prototxt文件,它们都是基础的CNN预先训练模型,将进行检测工作defload_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.read()会返回运算(True / False)如果读取到当前帧,则显示True #因此可以通过确认返回值来检查视频结尾#有时,cap函数可能尚未开启捕获,因此代码会显示错误#使用cap.isOpened()来检查是否已开启如果结果为True则已开,否则用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步:接下来,如何使用CascadeClassifier从图像中检测人脸? OpenCV的级联分类器操作十分简单,借助detectMultiScale()函数便可准确检测所需内容detectMultiScale(image,scaleFactor,minNeighbors)以下是detectMultiScale()函数参数 作为一个检测对象的常用函数,在此它能够结合CascadeClassifier中的人脸,如检测到人脸,将以“Rect(x,y,w,h)”的形式返回上述人脸列表,如果没有,则返回“None” · Image:首先输入人脸灰度图 · scaleFactor:缩放图像以减少由于对象与摄像头距离不一而导致人脸尺寸不同带来的检测误差 · minNeighbors:使用移动窗口来检测对象的算法,用来定义当前识别人脸附近还能识别到的人脸个数faces =face_cascade.detectMultiScale(灰色,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(). 运行方式为: · 均值消减· 缩放· 并选择性频道交换 blobFromImage可根据图像创建四维数组可选择从中心调整大小和裁剪图像,减去平均值,通过scalfactor缩放值,交换蓝色和红色通道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×2994. mean:指均值消减既可以减去RGB均值三元组,也可以从图像的各个通道中减去所提供的单个平均值进行均值消减时,要注意确保三元组顺序(依次是R,G,B),尤其是在执行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步:预测性别#PredictGendergender_net.setInput(blob)gender_preds= gender_net.forward()gender= gender_list[gender_preds[0].argmax()]第15步:预测年龄#PredictAgeage_net.setInput(blob)age_preds= age_net.forward()age= age_list[age_preds[0].argmax()]第16步:使用openCV的putText()函数在输出框架上放置文本 cv2.putText()的参数包括: · 要写入的文本数据· 数据放置的位置坐标(即数据开始的左下角)· 字体类型(确认cv2.putText()文件夹所支持字体)· 字体比例(指定字体大小)· 如颜色,粗细,线型等字体常规设置为了美观,推荐使用lineType = cv2.LINE_AAoverlay_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)最后一行:ifcv2.waitKey(1) & 0xFF == ord('q'): break此程序仅需用户等待1毫秒用户按下键盘按键后,程序会结合0xFF进行AND运算,删除底部所有8位以上的内容,并将其结果与ASCII代码进行比较,其中字母q代表用户可按下键盘中的q键(quit)来退出 输出: Video URL-1: https://www.youtube.com/watch?v=iH1ZJVqJO3YVideo URL-2:https://www.youtube.com/watch?v=qLNhVC296YI是不是很有趣呢?尽管结果并不那么精确
0 评论