摘要:身为一名前业务程序员和现前端程序员,这样的功能还是陌生的领域。需求使用加摄像头,通过人脸检测,完成自动拍照功能。在的屏幕上,显示摄像头的实时画面,要是画面中检测出人脸,则触发拍照。这样做的效果能够获得更高的,同时还能完成更远距离脸部的捕获。
需求因为项目原因,需要使用人脸检测(face detection)功能。身为一名前JAVA业务程序员和现前端程序员,这样的功能还是陌生的领域。那能不能通过搜索和学习能力,加上已有的编程思想,快速实现功能呢?这就是这篇文章的重点,凭借自己的技术与积累,走向自己不熟悉的领域。
使用PC加摄像头,通过人脸检测,完成自动拍照功能。在PC的屏幕上,显示摄像头的实时画面,要是画面中检测出人脸,则触发拍照。
抽其关键点:摄像头,实时画面,人脸检测,和拍照
自己拥有的技能项目并没有要求开发应用的类型,那么我肯定是先从自身拥有的技能出发,看是否能寻求解决方案。身为前端,深知前端技术潜力无限,肯定有自己还不知道的技术。果不其然,找到了Tracking.js
Tracking.js是一个很有意思的库,体积小巧,在浏览器上,直接通过JS提供一些基本的Computer Vison相关的功能,如人脸检测(face detection),颜色识别(color detection),特征识别(feature detection)。关键是,出了对静态图片能够进行识别和处理之外,还能够直接对视频(video)和摄像头(webcam)视屏流进行处理,这就基本给出了人脸识别的方案。
那如何拍照呢?我找到了WebcamJS。能够在浏览器上读取摄像头视频流,调用函数截取某个时刻视频流帧为图片,即视为拍照。
解决方案一两个库一结合,就有了初步的解决方案,实现了功能,简单快速。
人脸检测能力不足在Tracking.js的官网上可以看到,demo的视频尺寸都是很小的,320 * 240,才能有30FPS的处理速度。尺寸如果大了,则识别速度慢,卡顿明显。项目中视频显示大小基本为1080P分辨率屏幕的三分之一,直接处理这个大小的视频,速度肯定不够。就算我不直接对大尺寸视频流进行处理,转而对一个隐藏的小尺寸视频流处理,将人脸位置映射到大视频流中,速度上没问题,但是可检测的人脸大小就有限了,即人必须离摄像头比较近才能被检测到。
视频流的清晰度不够使用的是罗技的1080P的网络摄像头,但是在浏览器上能够看到的,好像并没有以1080P的分辨率进行展示。尝试了一些参数的修改,但是结果都不尽人意。
人脸识别造成性能问题实时的视频流人脸识别,是很耗CPU的,下图中右边那个蓝色的陡坡就是在我关闭了Tracking.js的demo页面后CPU下降的曲线。
这种情况下,想添加一些传统的网页动效,简直卡出翔来。(关于这点,使用web worker进行人脸检测的工作,应该能有所帮助,但是自己并没有往这方面走)
继续寻找方案为了寻找上面的问题的解决办法,我了解到了Tracking.js和WebcamJS的运行原理。比如在浏览器上获取摄像头视频流,是通过getUserMedia,是基于WebRTC的支持。
WebcamJS就是通过getuserMedia()方法,获得摄像头的视频流信息,作为标签的src属性,从来能够在网页上进行显示实时画面。通过Canvas的drawImage()方法,将video标签传入,即可绘制那个时刻视频帧的图像。(也是通过这次机会我才了解到drawImage()原来还可以接受HTMLVideoElement作为参数的)
之前就知道,一般做计算机视觉的,都会用opencv库,这是个C++的库。同时又查到了,有人在node上做了opencv的扩展,并且看到了这个Github项目。于是为了检测效果,自己做了尝试。
解决方案二通过上面的学习,我已经能够在浏览器段获取摄像头的帧图像,并且知道opencv能做人脸检测。那么这次的方案思路就是:将视频流的帧图像,通过websocket发到后台服务器上,在服务器里使用opencv进行人脸分析,将人脸的坐标发送到前端。
这里后台我并没有使用node-opencv,而是使用QT直接做websocket服务器和调用opencv库(仗着自己曾也学过C++,就大胆的直接奔着C++去了)。
但是结果也不理想,原因如下。
发送图像给后台耗时大将图片发送给后台,首先想到的是使用Canvas的toDataURL()方法,将图片转成base64字符串,发给后台。但实测该方法很慢!640 * 480大小的图片,通过toDataURL(),大致需要50ms时间。
然后考虑使用getImageData(0, 0, 640, 480)方法,获取图片像素信息,然后转成字符串发到后台。经测,该方法比toDataURL()确实快不少,大致在5ms左右。但是将它转成JSON字符串,则很慢很慢。
最后查到,toDataURL("image/jpeg")会加快速度,因为这里不需要计算Alpha通道。实测,小于10ms。
之前有担心的网络传输耗时问题,倒是得到了证实,这个担心是没有必要的。因为是本地传输,通过websocket传输一张图片(小尺寸或者大尺寸)base64字符串大小的内容,耗时都很小,算下来FPS能够上50。
CPU消耗大Approach | CPU % |
---|---|
QT Opencv Face Detection | 30% |
Tracking.js Face Detection | 50% |
Websocket + Opencv | 90% |
不确定自己在实现上是否哪里出了问题,导致这么高的CPU使用率。但不管怎么,还是放弃了这个方案。
解决方案三竟然都使用上了QT,就大步向前走好了,毕竟这样的图像处理程序,还是做桌面应用是做合适的。况且QT体系中的QML语言,能够使用JS,学起来有点像在学一个新的前端MVVM框架,好感度和信心瞬间提升不少。
使用QML做界面,使用Camera和VideoOutput组件进行摄像头视频的实时显示,这里能指定显示分辨率和FPS,很方便;配合使用QVideoFilterRunnable和QAbstractVideoFilter类对帧进行处理,异步返回给主界面人脸检测的结果;opencv和另外一个能做人脸识别的C++库Dlib结合使用,能够完成640 * 480尺寸的30FPS处理。
再优化!给每一帧图片进行人脸识别,速度和识别能力都可以提高,就是通过Dlib中提供的Video Object Tracking来完成。一旦对某一帧能够检测到人脸之后,对之后的帧执行该人脸区域图像的tracking。这样做的效果能够获得更高的FPS,同时tracking还能完成更远距离脸部的捕获。
到这里,方案才觉得差不多了。
总结面对项目中自己的未知领域,如果不缺钱,那么直接买商业解决方案。Visage Tech提供的HTML5的人脸识别解决方案(好像用了WebAssembly),简直{{BANNED}}:快速!准确!稳定!核心科技就是和我们这些小打小闹的不一样。
如果不购买商用解决方案,那么应该尽量找到能够帮助自己的朋友,指条正确的方向能够节省很多调查摸索的时间。比如,如果需求要求程序在拍照时还能控制外接的灯泡,完成闪光灯的效果。那么如何使用软件完成对外部硬件的控制呢?这样的功能对于我这个非计算机专业的而言,真是蒙圈了。最后还是经历的大半天的摸索,才找到GPIO的解决办法。
提高编程的素养,扩大自己的兴趣面,热爱技术,善于google,逻辑思路清晰,那么在面对不熟悉的领域,新的技术,也能够找到解决方案。并且这个过程能让自己获得不少知识,face detection, object tracking, tracking.js, webcamJS, getUserMedia(), toDataURL()的性能,opencv,dlib,QML,GPIO,树莓派,我还差点去现学了Python。这些东西没有必要都是深究,但是知道他们的存在,会给扩展自己的思路。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/81739.html
摘要:的发布已经有一些时日,其主要的提供的能力是给予前端直接可用的特征检测的接口包括条形码人脸文本检测。本文将简单的对其进行介绍,对前端进行人脸检测进行普适性的讲解。 Shape Detection API 的发布已经有一些时日,其主要的提供的能力是给予前端直接可用的特征检测的接口(包括条形码、人脸、文本检测)。本文将简单的对其进行介绍,对前端进行人脸检测进行普适性的讲解。(本文不讲算法~望...
摘要:的发布已经有一些时日,其主要的提供的能力是给予前端直接可用的特征检测的接口包括条形码人脸文本检测。本文将简单的对其进行介绍,对前端进行人脸检测进行普适性的讲解。 Shape Detection API 的发布已经有一些时日,其主要的提供的能力是给予前端直接可用的特征检测的接口(包括条形码、人脸、文本检测)。本文将简单的对其进行介绍,对前端进行人脸检测进行普适性的讲解。(本文不讲算法~望...
阅读 2594·2021-11-11 16:55
阅读 1258·2021-09-22 15:25
阅读 1766·2019-08-29 16:26
阅读 864·2019-08-29 13:21
阅读 2284·2019-08-23 16:19
阅读 2780·2019-08-23 15:10
阅读 740·2019-08-23 14:24
阅读 1828·2019-08-23 13:48