首发于Bug工厂
疫情当前,写一个纯前端实现人脸检测的网页,给你的头像戴上口罩!

疫情当前,写一个纯前端实现人脸检测的网页,给你的头像戴上口罩!

根据春节的起源,如果“年”真的是一个凶猛的怪兽,那么今年一定是2019-nCoV病毒。往年辟邪用的红纸和鞭炮,变成了各色各样的口罩。约好的聚会和自驾游纷纷取消,同学们都成了躲避瘟疫的牛顿,在家里思考科学。甚至在社交网络上也少了很多年味,越来越多的人把口罩都戴到了自己的头像上。


第一次瞥见这种潮流是在除夕前一天,微信群聊里的一个朋友的头像突然刷新,只是多了个口罩,一切都令人猝不及防。我当时的第一反应是又有小机灵鬼出现了,应该已经做出能自动给头像加口罩的应用了吧?但是经过一番短暂的调研,现有的APP和网页版的头像生成器都没有人脸检测的功能,还是靠手动添加贴纸,一点都不智能。理想太丰满,反正也是假期,遂打算自己写一个。于是这一写就写了三天,最后用纯前端实现了一个可以对图像进行人脸关键点检测并自动添加口罩的单页应用。


给你的头像戴上口罩https://www.zhihu.com/video/1205142434168176640


由于这个项目压根不需要后台代码,因此部署很方便(有点边缘计算的意思?)。考虑到GitHub Pages在国内的惨烈加载速度,我同时在码云上部署了一份,应用链接如下,欢迎体验。


至于大体的使用流程,就是用户上传自己的头像后,页面会自动检测图片中的人脸,识别出关键点后匹配最适合的口罩贴纸。然后用户可以在编辑器内改变贴纸的位置、大小、旋转角度和翻转,然后将修改后的头像导出。整个过程都在前端完成,图片无需上传到服务器。最后成品的一个截图如下,界面中间是编辑区,正在编辑用户上传的图片:

偶然发现草间弥生老奶奶和我的UI蜜汁般配



分割线一划,下面介绍一下实现吧。由于开发时间比较紧促(因为眼看着越来越多的人给自己头像P了口罩,潜在用户越来越少),因此在技术上只做到了baseline,后续如果有机会和时间,可能会在模型等各个方面提升一下。目前项目已开源(仓库链接在文末),下文的内容大体上写进了README,也包含对README的一点扩充。


一、人脸检测和人脸关键点检测

面对这两个任务,第一个想法是直接用TensorFlow.js(tfjs)实现。目前tfjs拥有基于WebGL的GPU加速功能并支持任何现代GPU,并不局限于英伟达,如果不考虑它尚不支持的功能的话还是有点香。但是偶然间发现了一个更细化的库,名为face-api.js,它是对tfjs-core的一个封装,包含了一些人脸检测和识别的模型和API。


在本项目中,通过实际效果的比较,人脸检测任务选择了SSD MobileNet V1模型(用WIDERFACE数据集进行训练),人脸关键点检测任务选择了face-api.js作者构建的基于CNN的68点检测模型(在约有35,000张面部图像的数据集上进行训练),模型权重数据来源于face-api.js。

68点检测模型的一个输出


由于本项目的研究对象是用户头像,和单纯的人脸检测任务还是有不小的区别。简单来说就是口罩不光可以加在人脸上,有时还需要加在二次元人像和动物面部之上等等。但是由于时间原因还没有扩充相关数据集进行重新训练或迁移学习,只是用人脸检测模型做出了成品。目前经过实际测试,模型在大部分的清晰人脸照片和小部分的二次元人像上表现良好。

AI给了周杰伦一个口罩


小乌的脸也能够识别,但是二次元效果不如三次元


关于SSD MobileNet V1,结构上是用Google提出的MobileNet V1模型替换了SSD网络中的VGG16部分作为特征提取器,将深度可分离卷积带到了SSD。顺带相关论文链接:

SSD:arxiv.org/pdf/1512.0232

MobileNet V1:arxiv.org/pdf/1704.0486


二、口罩贴纸的自动选择与定位

目前项目中包含了24个口罩贴纸素材和每个口罩的数据。对于每个口罩贴纸,在上面取三个关键点(左上角、右上角和下巴底部)作为特征信息,在检测出用户头像上的68个关键点以后,计算出和口罩同样位置的三个点的坐标,根据这些数据计算出与脸型最匹配的口罩贴纸,并反向计算出相应的几何变换,将贴纸放在头像上的合适位置。


这部分涉及的主要是一些解析几何知识,开发这个模块时费了一些草稿纸(实际上自从上次开发平面几何机器证明算法之后,我已经有些年没接触过这些了,这生疏感令人措手不及)。


目前这个方法在匹配的精度上感觉还可以进一步提高,比如在口罩上多选几个特征点等等。但是目前口罩素材的数量也有限,丰富度不足,算法精度的提升对实际效果影响不会很大。


三、拥有贴纸编辑功能的图像编辑器

本项目的图像编辑器用canvas实现,在开发时主要参考了npm包xl_canvas。但是由于该包不能直接使用,又进行了深度修改,添加了翻转、触摸支持、按原始分辨率导出等一系列功能,集成在项目中。

图像编辑器


这个模块在开发过程中同样用到了不少解析几何和三角函数,在涉及到例如图层管理的时候有一种在开发微型PS的爽快感。canvas确实强大得无与伦比,但是水很深坑也很多。


最后放上本项目在GitHub上的链接,欢迎Star,也欢迎各位大佬提出建议~



今年过了一个难忘的春节。虽然肺炎疫情如同洪水猛兽,但能得此机会静一静做些平常没机会做的小事也不是一件坏事。计算所的老师在学生群里发了一张图片鼓励大家,以此作为结尾,祝大家身体健康!

编辑于 2020-01-27 22:47

文章被以下专栏收录