【知識(shí)普及】前端人臉檢測(cè)指南,快來(lái)看看
Shape Detection API 的發(fā)布已經(jīng)有一些時(shí)日,其主要的提供的能力是給予前端直接可用的特征檢測(cè)的接口(包括條形碼、人臉、文本檢測(cè))。本文將簡(jiǎn)單的對(duì)其進(jìn)行介紹,對(duì)前端進(jìn)行人臉檢測(cè)進(jìn)行普適性的講解。(本文不講算法~望輕拍)
1 背景與場(chǎng)景
人臉檢測(cè)(Face Detection)算是老生常談的課題了,在諸多行業(yè)應(yīng)用廣泛,例如金融、安防、電子商務(wù)、智能手機(jī)、娛樂(lè)圖片等行業(yè)。其中涉及的技術(shù)也在不斷的演變,下面簡(jiǎn)要介紹幾種思路:
a. 基于特征的人臉檢測(cè)
例如opencv中內(nèi)置了基于Viola-Jones目標(biāo)檢測(cè)框架的Harr分類(lèi)器(實(shí)際上大多數(shù)分類(lèi)器都是基于學(xué)習(xí)得到的),只需要載入對(duì)應(yīng)的配置文件(haarcascade_frontalface_alt.xml)就能直接調(diào)用detectObject去完成檢測(cè)過(guò)程,同時(shí)也支持其他特征的檢測(cè)(如鼻子、嘴巴等)。
b. 基于學(xué)習(xí)的人臉檢測(cè),其實(shí)也是需要通過(guò)算子提取的圖像中的局部特征,通過(guò)對(duì)其進(jìn)行分類(lèi)、統(tǒng)計(jì)、回歸等方式得到的具備更精確和快響應(yīng)的分類(lèi)器。
2 套路集錦
2.1 后端處理
前端通過(guò)網(wǎng)絡(luò)將資源傳輸?shù)胶蠖?,后端統(tǒng)一處理需要檢測(cè)的圖像或視頻流,對(duì)后端的架構(gòu)有一定的挑戰(zhàn),同時(shí)網(wǎng)絡(luò)的延時(shí)往往不能給用戶(hù)帶來(lái)實(shí)時(shí)的交互效果。
2.2 客戶(hù)端處理
得益于OpenCV在跨語(yǔ)言和跨平臺(tái)的優(yōu)勢(shì),客戶(hù)端也能以較低的開(kāi)發(fā)成本的提供人臉檢測(cè)的能力,并且可以通過(guò)JsBridge等方式向web容器提供服務(wù),然而一旦脫離這個(gè)容器,孤立的頁(yè)面將失去這種能力。直到有一天……
2.3 開(kāi)放服務(wù)
不知道從啥時(shí)候開(kāi)始,云計(jì)算等概念拔地而起,計(jì)算的成本日益降低。各大研發(fā)團(tuán)隊(duì)(如阿里云、Face++)都蠢蠢欲動(dòng)又不緊不慢的上架了人臉檢測(cè)服務(wù),甚至還帶上了各種特!殊!服!務(wù)!,人臉識(shí)別、活體識(shí)別、證件OCR及人臉對(duì)比等等等。
盡管不僅提供了客戶(hù)端的SDK以及前后端的API,但是,怎么說(shuō)也要講講我純前端的方案吧。
3 時(shí)代帶來(lái)了什么
好吧,人臉識(shí)別在前端依然是在刀耕火種的遠(yuǎn)古時(shí)代,然而,我們的基礎(chǔ)建設(shè)已經(jīng)起步,希望后續(xù)的一些相關(guān)介紹能為各位看官帶來(lái)一定的啟發(fā)。
3.1 Shape Detection API
隨著客戶(hù)端硬件的計(jì)算能力逐漸提高,瀏覽器層面得到的權(quán)限也越來(lái)越多,由于圖像處理需要耗費(fèi)大量的計(jì)算資源,實(shí)際上瀏覽器上也能承擔(dān)圖像檢測(cè)的一些工作,因此就搞出了個(gè)Shape Detection API。
以下幾個(gè)簡(jiǎn)單的例子介紹了基本的用法,在嘗試編輯并運(yùn)行這些代碼之前,請(qǐng)確保在你的Chrome版本以及該新特性已經(jīng)被激活,另外該API受同源策略所限制:
chrome://flags/#enable-experimental-web-platform-features
條形碼檢測(cè):Barcode Detection (For Chrome 56+)
- var barcodeDetector = new BarcodeDetector();
- barcodeDetector.detect(image)
- .then(barcodes => {
- barcodes.forEach(barcode => console.log(barcodes.rawValue))
- })
- .catch(err => console.error(err));
人臉檢測(cè):Face Detection (For Chrome 56+)
- var faceDetector = new FaceDetector();
- faceDetector.detect(image)
- .then(faces => faces.forEach(face => console.log(face)))
- .catch(err => console.error(err));
文本檢測(cè):Text Detection (For Chrome 58+)
- 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));
3.2 圖像中的人臉檢測(cè)
圖像的人臉檢測(cè)比較簡(jiǎn)單,只需要傳入一個(gè)圖片的元素,就能直接調(diào)起該API進(jìn)行人臉識(shí)別了。然后接住canvas我們可以將檢測(cè)的結(jié)果展示出來(lái)。
核心代碼:
- 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));
- }
處理效果:
3.3 視頻中的人臉檢測(cè)
視頻中的人臉檢測(cè)跟圖像相差不大,通過(guò) getUserMedia 可以打開(kāi)攝像頭獲取視頻/麥克風(fēng)的信息,通過(guò)將視頻幀進(jìn)行檢測(cè)和展示,即可實(shí)現(xiàn)視頻中的人臉檢測(cè)。
核心代碼如下:
- 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);
處理效果:
3.4 時(shí)光倒流到?jīng)]有API的日子
實(shí)際上,在很久很久以前,也有不少解決方案存在。由于硬件條件以及沒(méi)有硬件加速等限制的情況,一直沒(méi)有被廣泛地投入生產(chǎn)。
a. tracking.js
tracking.js 是一款js封裝的圖像處理的庫(kù),為瀏覽器帶來(lái)豐富的計(jì)算視覺(jué)相關(guān)的算法和技術(shù),通過(guò)它可以實(shí)現(xiàn)顏色追蹤、人臉檢測(cè)等功能,具體特性如下:
b. jquery.facedetection
jquery.facedetection 是一款jquery / zepto 人臉檢測(cè)插件,基于跨終端能力超強(qiáng)的ccv中的圖像分類(lèi)器和檢測(cè)器。
3.5 Node.js & OpenCV
node-opencv 模塊已經(jīng)發(fā)布了有些年頭,盡管目前還不能***兼容v3.x,提供的API也比較有限,但能***兼容opencv v2.4.x。N-API的到來(lái)可能會(huì)帶來(lái)更多的驚喜。
設(shè)想一下在一個(gè)Electron或者Node-Webkit容器中,我們是否可以通過(guò)本地開(kāi)啟websocket服務(wù)來(lái)實(shí)現(xiàn)實(shí)時(shí)的人臉檢測(cè)呢?實(shí)現(xiàn)的思路代碼如下:
后端處理邏輯:
- 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 cameraconst 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);
- };
前端調(diào)用接口:
- 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.1 未來(lái)的發(fā)展
這些前沿的技術(shù)將會(huì)在前端得到更為廣泛的應(yīng)用和支持是毋庸置疑的,未來(lái)的圖像在前端也會(huì)隨著傳統(tǒng)圖像處理->學(xué)習(xí)+圖像處理的方式前進(jìn),這一切的功勞離不開(kāi)基礎(chǔ)設(shè)施(硬件、瀏覽器、工具、庫(kù)等)的逐漸增強(qiáng)和完善,其中包括但不僅限于:
- getUserMedia/Canvas => 圖像 / 視頻的操作
- Shape Detection API => 圖像檢測(cè)
- Web Workers => 并行計(jì)算能力
- ConvNetJS => 深度學(xué)習(xí)框架
- Tensorflow (原 DeeplearnJS) => 正大力支持 JS
4.2 實(shí)際上并沒(méi)有那么樂(lè)觀
4.2.1 準(zhǔn)確率
對(duì)于正臉(多個(gè))的識(shí)別率還是比較高的,但是在側(cè)臉已經(jīng)有障礙物的情況下,檢測(cè)的效果并不理想。
4.2.2 處理速度
對(duì)于圖像中人臉檢測(cè)的例子2.2,耗費(fèi)時(shí)間300ms+(實(shí)際上無(wú)法滿足大分辨率視頻實(shí)時(shí)處理),是調(diào)用Opencv的檢測(cè)速度100ms的三倍之多。
4.2.3 特性
還有很多需要完善的地方:如不支持眼鏡狀態(tài)、性別、年齡估計(jì)、表情識(shí)別、人種、笑容、模糊檢測(cè)等主流服務(wù)提供商提供的服務(wù)。
4.3 想說(shuō)又說(shuō)不完的
a. 本文中所有樣例的源代碼,歡迎 Fork / Star:
https://github.com/x-cold/fac...
https://github.com/x-cold/fac...
b. 關(guān)于人臉檢測(cè)在不同場(chǎng)景的適應(yīng)性,以及檢測(cè)消耗的時(shí)間暫時(shí)沒(méi)有數(shù)據(jù)支撐,后面考慮引入PASCAL VOC、AT&T提供的樣本進(jìn)行小規(guī)模的測(cè)試。
5 參考
- 人臉識(shí)別技術(shù)大總結(jié)(1):Face Detection & Alignment: http://blog.jobbole.com/85783/
- 阿里巴巴直播防控中的實(shí)人認(rèn)證技術(shù): https://xianzhi.aliyun.com/fo...
- 前端在人工智能時(shí)代能做些什么?:https://yq.aliyun.com/article...
- ConvNetJS Deep Learning in your browser:http://cs.stanford.edu/people...
- Face detection using Shape Detection API:https://paul.kinlan.me/face-d...