当前位置:XML > XML介绍

想要训练专属人脸识别模型先掌握构建人脸数

北京中科白瘕风刘云涛 https://mjbk.familydoctor.com.cn/bjbdfyy_ys/

雷锋网AI研习社按,随着深度学习的发展,很多技术已经落地,成为我们每天都能接触到的产品,人脸识别就是其中之一。人脸识别的应用范围很广,涉及上下班打卡、门禁、设备登录、机场、公共区域的监控等多个领域。

我们可以自己训练定制化的人脸识别模型,但在训练模型识别图片或视频中的人脸之前,最重要的一个步骤是收集人脸数据集。如果使用已经设计好的公开数据集,比如LabeledFacesintheWild(LFW),这时候最难的一部分工作已经完成了,大家可以直接使用各种模型创造自己的人脸识别应用。

但是对于大多数人来说,我们想要识别的并不是目前开源的人脸数据集中的人脸,而是我们自己、朋友、家人、同事等等的脸。为了实现这个目标,我们需要收集自己想要识别的人脸,并按照某种方式处理好它们。这个过程通常被称为人脸登记,我们将用户作为一个样本『登记』或者『注册』到我们的数据集中。下面会介绍三种方法进行人脸登记,大家可以根据自己的情况选择最合适的方法。

如何创建定制的人脸识别数据集

首先我将介绍使用OpenCV和一颗摄像头来检测视频流中的人脸,并将带有人脸的图像帧保存到硬盘上。接下来我会列举几种用程序自动从网上下载人脸图片的方法。最后,我们将讨论人工收集图像,以及在什么情况下这种方法是合适的。

现在开始构建一个人脸识别数据集吧!

方法1:通过OpenCV和摄像头登记人脸

该方法适用于:

1.构建一个某区域内的人脸识别系统

2.对于目标人脸,能够找到特定的人并收集他们的人脸图像

这样的系统适用于公司、学校或者其他组织,在这里人们会每天不定时的出现。

为了得到这些人的人脸样本,我们会在一个房间内放置好电脑和摄像机,通过摄像机捕捉目标人脸在摄像画面中的人脸信息,将并包含人脸的图像帧保存到硬盘中。

收集不同条件下的目标人脸样本可能会需要几天或几周的时间,这样能使得人脸数据集足够丰富,很好地表示不同状态下的人脸,保证训练出来模型有足够的鲁棒性,收集的人脸包括:

不同亮度下的人脸每天不同时候,不同光线角度下的人脸不同表情和情绪状态下的人脸

接下来我们更进一步,写一个简单的Python脚本来构建人脸识别数据集,这个脚本会做如下工作:

连接并控制摄像头检测人脸将包含人脸的图像帧写入硬盘

打开一个叫build_face_dataset.py的Python脚本,首先导入一些必要的库,包括OpenCV和imutils

1#importthenecessarypackages2fromimutils.videoimportVideoStream3importargparse4importimutils5importtime6importcv27importos

可以参考这篇文章安装OpenCV:

imutils可以通过pip安装:pipinstall--upgradeimutils

如果使用的是Python虚拟环境,不要忘记使用workon命令

现在环境已经配置好了,接下来讨论两个必要的命令行参数:

9#constructtheargumentparserandparsethearguments10ap=argparse.ArgumentParser()11ap.add_argument(-c,--cascade,required=True,12  help=pathtowherethefacecascaderesides)13ap.add_argument(-o,--output,required=True,14  help=pathtooutputdirectory)15args=vars(ap.parse_args())

命令行参数可以通过argparse库在运行时解析,这个库是包含在Python安装中的。

我们有两个命令行参数:

--cascade:硬盘中的Haarcascade文件路径,用于OpenCV检测人脸--output:输出的文件路径。人脸图像将会被保存到该路径中,因此最好按照人名将人脸分类保存,比如将『JohnSmith』的人脸图像保存到dataset/john_smith的路径下

接下来加载人脸的Haarcascade文件并初始化视频流:

17#loadOpenCVsHaarcascadeforfacedetectionfromdisk18detector=cv2.CascadeClassifier(args[cascade])#initializethevideostream,allowthecamerasensortowarmup,21#andinitializethetotalnumberofexamplefaceswrittentodisk22#thusfar23print([INFO]startingvideostream...)24vs=VideoStream(src=0).start()25#vs=VideoStream(usePiCamera=True).start()26time.sleep(2.0)27total=0

在第18行,我们加载了OpenCV的Haar人脸检测器detector。这个detector将会在接下来每帧的循环中检测人脸;在24行会初始化并开启视频流VideoStreem;如果使用的是树莓派的话,注释掉第24行的代码,使用第25行的代码;第26行让摄像头先热个身,暂停两秒钟;这一段代码也初始化了total计数器来表示保存的人脸图片的数量。

接下来,就开始对视频流的每帧图像进行处理:

29#loopovertheframesfromthevideostream30whileTrue:31  #grabtheframefromthethreadedvideostream,cloneit,(just32  #incasewewanttowriteittodisk),andthenresizetheframe33  #sowecanapplyfacedetectionfaster34  frame=vs.read()35  orig=frame.copy()36  frame=imutils.resize(frame,width=)  #detectfacesinthegrayscaleframe39  rects=detector.detectMultiScale(40    cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY),scaleFactor=1.1,41    minNeighbors=5,minSize=(30,30))  #loopoverthefacedetectionsanddrawthemontheframe44  for(x,y,w,h)inrects:45    cv2.rectangle(frame,(x,y),(x+w,y+h),(0,,0),2)

在第30行,开始循环(循环在『q』键被按下之后结束);34-36行,捕捉一帧画面:frame,创建一个copy,改变大小。

接下来就是人脸检测了!

使用detectMultiScale方法在每帧画面中检测人脸,这个函数需要如下参数:

image:一个灰度图像

scaleFactor:指定在每个维度图像尺寸减少的比例

minNeighbor:该参数指定候选的检测框数量,以保证检测是有效的

minSize:最小的人脸图像尺寸

在某些特殊场景下,可能需要精调这些参数以减少falsepositive的数量或提高人脸的检测率,但是对于一些普通的人脸检测任务来说,这些参数就可以很好的工作了。

其实也还有一些其他更好的方法检测人脸,比如在之前的文章中提到过,可以使用预训练好的深度学习模型来检测人脸。但是本文里提到的使用OpenCV的方法的优点是无需调参,而且速度非常快。

人脸检测的结果被保存在一个rects的列表中(矩形检测框)。为了将这些矩形画在图像上,在44、45行中遍历所有矩形框,并将他们画在图片上。

最后一步就是将检测框显示在屏幕上,以及解决按键退出的问题:

48  #showtheoutputframe49  cv2.imshow(Frame,frame)50  key=cv2.waitKey(1)0xFF  #ifthe`k`keywaspressed,writethe*original*frametodisk53  #sowecanlaterprocessitanduseitforfacerecognition54  ifkey==ord(k):55    p=os.path.sep.join([args[output],{}.png.format(56      str(total).zfill(5))])57    cv2.imwrite(p,orig)58    total+=  #ifthe`q`keywaspressed,breakfromtheloop61  elifkey==ord(q):62    break

第48行执行将该帧图像显示在屏幕上,第49行执行捕捉键盘指令

『k』、『q』键盘指令对应不同的命令:

k:保留该帧图像并保存到硬盘中(53-56行),同时增加total计数器。对每个想要保存的图像帧,都需要按『k』来保存。为了能够更好地训练模型,最好要保存不同角度、人脸在画面不同位置、带/不带眼镜的图像。q:退出循环,退出脚本

最后,将保存的图片数量打印到屏幕上,并清空缓存:

64#printthetotalfacessavedanddoabitofcleanup65print([INFO]{}faceimagesstored.format(total))66print([INFO]cleaningup...)67cv2.destroyAllWindows()68vs.stop()

接下来,只需在终端里运行如下命令就可以了:

$pythonbuild_face_dataset.py--cascadehaarcascade_frontalface_default.xml\--outputdataset/adrian[INFO]startingvideostream...[INFO]6faceimagesstored[INFO]cleaningup...

这里推荐将每个人的人脸数据保存在数据集下的一个子文件夹内,这样能够保证数据集条理清晰,易于管理。

方法2:使用程序自动下载人脸图片

在这种场景下,我们并不需要真的找到那个人拍摄图片,只要他们经常出现在网上,我们能够在网上找到足够多的图片即可,这样就可以写脚本,通过各个平台的API下载这些图片了。

具体使用哪些API主要取决于想要收集的人的人脸信息,比如一个人经常在Twitter或者Instagram上发自拍,那么我们就可以使用这些平台的API来抓取图片。

还可以使用Google和Bing等搜索引擎来抓取:

在这篇博文中,可以找到使用GoogleImages手动或者使用脚本来下载图片的方法。

另一个更好的方法就是使用Bing的图片搜索API,这样能够全自动下载图像,具体方法参见这篇博文。

使用Bing图片搜索API,我们能够从侏罗纪公园和侏罗纪世界这两部电影的海报中下载张AlanGrant的脸部图片。下面展示了通过Bing图片搜索API下载演员OwenGrady的脸部图片的代码:

1$mkdirdataset/owen_grady2$pythonsearch_bing_api.py--queryowengrady--outputdataset/owen_grady使用这种方法下载几个人的人脸图像之后,我们看看整个数据集长什么样1$treejp_dataset--filelimitjp_dataset3├──alan_grant[22entries]4├──claire_dearing[53entries]5├──ellie_sattler[31entries]6├──ian_malcolm[41entries]7├──john_hammond[36entries]8└──owen_grady[35entries]directories,0files

只要20分钟左右(包括手动挑出错误图像的时间),就能够做好一个侏罗纪公园的人脸数据集了。

方法3:手动收集人脸图像

最后一个方法就是全手动收集人脸数据集,这是最不推荐的方法。这种方法显然是最繁琐的,而且需要大量时间。但是在某些特殊情况下,可能不得不使用这些方法。

手动收集的话,通常需要:

使用搜索引擎搜索浏览社交媒体账号(Ins,微博,


转载请注明:http://www.vviuov.com/jbzs/1063019.html

  • 上一篇文章:
  • 下一篇文章: 没有了