Shape Detection API 的发布已经有一些时日,其主要的提供的能力是给予前端直接可用的特征检测的接口(包括条形码、人脸、文本检测)。本文将简单的对其进行介绍,对前端进行人脸检测进行普适性的讲解。(本文不讲算法~望轻拍)html
人脸检测(Face Detection)算是老生常谈的课题了,在诸多行业应用普遍,例如金融、安防、电子商务、智能手机、娱乐图片等行业。其中涉及的技术也在不断的演变,下面简要介绍几种思路:前端
例如opencv中内置了基于Viola-Jones目标检测框架的Harr分类器,只须要载入一个配置文件(haarcascade_frontalface_alt.xml)就能直接调用detectObject去完成检测过程,同时也支持其余特征的检测(如鼻子、嘴巴等)。node
前端经过网络将资源传输到后端,后端统一处理须要检测的图像或视频流,对后端的架构有必定的挑战,同时网络的延时每每不能给用户带来实时的交互效果。jquery
得益于OpenCV在跨语言和跨平台的优点,客户端也能以较低的开发成本的提供人脸检测的能力,而且能够经过JsBridge等方式向web容器提供服务,然而一旦脱离这个容器,孤立的页面将失去这种能力。直到有一天……git
不知道从啥时候开始,云计算等概念拔地而起,计算的成本日益下降。各大研发团队(如阿里云、Face++)都蠢蠢欲动又不紧不慢的上架了人脸检测服务,甚至还带上了各类特!殊!服!务!,人脸识别、活体识别、证件OCR及人脸对比等等等。github
尽管不只提供了客户端的SDK以及先后端的API,可是,怎么说也要讲讲我纯前端的方案吧。web
好吧,人脸识别在前端依然是在刀耕火种的远古时代,然而,咱们的基础建设已经起步,但愿后续的一些相关介绍能为各位看官带来必定的启发。算法
随着客户端硬件的计算能力逐渐提升,浏览器层面获得的权限也愈来愈多,因为图像处理须要耗费大量的计算资源,实际上浏览器上也能承担图像检测的一些工做,所以就搞出了个Shape Detection API。chrome
如下几个简单的例子介绍了基本的用法,在尝试编辑并运行这些代码以前,请确保在你的Chrome版本以及该新特性已经被激活,另外该API受同源策略所限制:canvas
chrome://flags/#enable-experimental-web-platform-features
var barcodeDetector = new BarcodeDetector(); barcodeDetector.detect(image) .then(barcodes => { barcodes.forEach(barcode => console.log(barcodes.rawValue)) }) .catch(err => console.error(err));
var faceDetector = new FaceDetector(); faceDetector.detect(image) .then(faces => faces.forEach(face => console.log(face))) .catch(err => console.error(err));
var textDetector = new TextDetector(); textDetector.detect(image) .then(boundingBoxes => { for(let box of boundingBoxes) { speechSynthesis.speak(new SpeechSynthesisUtterance(box.rawValue)); } }) .catch(err => console.error(err));
图像的人脸检测比较简单,只须要传入一个图片的元素,就能直接调起该API进行人脸识别了。而后接住canvas咱们能够将检测的结果展现出来。
核心代码以下:
var image = document.querySelector('#image'); var canvas = document.querySelector('#canvas'); var ctx = canvas.getContext("2d"); var scale = 1; image.onload = function () { ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height); scale = canvas.width / image.width; }; function detect() { if (window.FaceDetector == undefined) { console.error('Face Detection not supported'); return; } var faceDetector = new FaceDetector(); console.time('detect'); return faceDetector.detect(image) .then(faces => { console.log(faces) // Draw the faces on the <canvas>. var ctx = canvas.getContext("2d"); ctx.lineWidth = 2; ctx.strokeStyle = "red"; for (var i = 0; i < faces.length; i++) { var item = faces[i].boundingBox; ctx.rect(Math.floor(item.x * scale), Math.floor(item.y * scale), Math.floor(item.width * scale), Math.floor(item.height * scale)); ctx.stroke(); } console.timeEnd('detect'); }) .catch((e) => { console.error("Boo, Face Detection failed: " + e); }); }
视频中的人脸检测跟图像相差不大,经过getUserMedia
能够打开摄像头获取视频/麦克风的信息,经过将视频帧进行检测和展现,便可实现视频中的人脸检测。
核心代码以下:
navigator.mediaDevices.getUserMedia({ video: true, // audio: true }) .then(function (mediaStream) { video.src = window.URL.createObjectURL(mediaStream); video.onloadedmetadata = function (e) { // Do something with the video here. }; }) .catch(function (error) { console.log(error.name); }); setInterval(function () { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(video, 0, 0); image.src = canvas.toDataURL('image/png'); image.onload = function() { detect(); } }, 60);
实际上,在好久好久之前,也有很多解决方案存在。因为硬件条件以及没有硬件加速等限制的状况,一直没有被普遍地投入生产。
tracking.js 是一款js封装的图像处理的库,为浏览器带来丰富的计算视觉相关的算法和技术,经过它能够实现颜色追踪、人脸检测等功能,具体特性以下:
jquery.facedetection 是一款jquery / zepto 人脸检测插件,基于跨终端能力超强的ccv中的图像分类器和检测器。
2.5 Node.js & OpenCv
node-opencv 模块已经发布了有些年头,尽管目前还不能完美兼容v3.x,提供的API也比较有限,但能完美兼容opencv v2.4.x。N-API的到来可能会带来更多的惊喜。
设想一下在一个Electron或者Node-Webkit容器中,咱们是否能够经过本地开启websocket服务来实现实时的人脸检测呢?实现的思路代码以下:
import cv from 'opencv'; const detectConfigFile = './node_modules/opencv/data/haarcascade_frontalface_alt2.xml'; // camera properties const camWidth = 320; const camHeight = 240; const camFps = 10; const camInterval = 1000 / camFps; // face detection properties const rectColor = [0, 255, 0]; const rectThickness = 2; // initialize camera const camera = new cv.VideoCapture(0); camera.setWidth(camWidth); camera.setHeight(camHeight); const frameHandler = (err, im) => { return new Promise((resolve, reject) => { if (err) { return reject(err); } im.detectObject(detectConfigFile, {}, (error, faces) => { if (error) { return reject(error); } let face; for (let i = 0; i < faces.length; i++) { face = faces[i]; im.rectangle([face.x, face.y], [face.width, face.height], rectColor, rectThickness); } return resolve(im); }); }); }; module.exports = function (socket) { const frameSocketHanlder = (err, im) => { return frameHandler(err, im) .then((img) => { socket.emit('frame', { buffer: img.toBuffer(), }); }); }; const handler = () => { camera.read(frameSocketHanlder); }; setInterval(handler, camInterval); };
socket.on('frame', function (data) { var unit8Arr = new Uint8Array(data.buffer); var str = String.fromCharCode.apply(null, unit8Arr); var base64String = btoa(str); img.onload = function () { ctx.drawImage(this, 0, 0, canvas.width, canvas.height); } img.src = 'data:image/png;base64,' + base64String; });
这些前沿的技术将会在前端获得更为普遍的应用和支持是毋庸置疑的,将来的图像在前端也会随着传统图像处理->学习+图像处理的方式前进,这一切的功劳离不开基础设施(硬件、浏览器、工具、库等)的逐渐加强和完善,其中包括但不只限于:
4.2.1 准确率
对于正脸(多个)的识别率仍是比较高的,可是在侧脸已经有障碍物的状况下,检测的效果并不理想。
4.2.2 处理速度
对于图像中人脸检测的例子2.2,耗费时间300ms+(实际上没法知足大分辨率视频实时处理),是调用Opencv的检测速度100ms的三倍之多。
4.2.3 特性
还有不少须要完善的地方:如不支持眼镜状态、性别、年龄估计、表情识别、人种、笑容、模糊检测等主流服务提供商提供的服务。