咦?瀏覽器都能做人臉檢測了?
Shape Detection API 的發布已經有一些時日,其主要的提供的能力是給予前端直接可用的特征檢測的接口(包括條形碼、人臉、文本檢測)。本文將簡單的對其進行介紹,對前端進行人臉檢測進行普適性的講解。(本文不講算法~望輕拍)
1 背景與場景
人臉檢測(Face Detection)算是老生常談的課題了,在諸多行業應用廣泛,例如金融、安防、電子商務、智能手機、娛樂圖片等行業。其中涉及的技術也在不斷的演變,下麵簡要介紹幾種思路:
a. 基於特征的人臉檢測
例如opencv中內置了基於Viola-Jones目標檢測框架的Harr分類器,隻需要載入一個配置文件(haarcascade_frontalface_alt.xml)就能直接調用detectObject去完成檢測過程,同時也支持其他特征的檢測(如鼻子、嘴巴等)。
b. 基於學習的人臉檢測,其實也是需要通過算子提取的圖像中的局部特征,通過對其進行分類、統計、回歸等方式得到的具備更精確和快響應的分類器。
2 套路集錦
2.1 後端處理
前端通過網絡將資源傳輸到後端,後端統一處理需要檢測的圖像或視頻流,對後端的架構有一定的挑戰,同時網絡的延時往往不能給用戶帶來實時的交互效果。
2.2 客戶端處理
得益於OpenCV在跨語言和跨平台的優勢,客戶端也能以較低的開發成本的提供人臉檢測的能力,並且可以通過JsBridge等方式向web容器提供服務,然而一旦脫離這個容器,孤立的頁麵將失去這種能力。直到有一天……
2.3 開放服務
不知道從啥時候開始,雲計算等概念拔地而起,計算的成本日益降低。各大研發團隊(如阿裏雲、Face++)都蠢蠢欲動又不緊不慢的上架了人臉檢測服務,甚至還帶上了各種特!殊!服!務!,人臉識別、活體識別、證件OCR及人臉對比等等等。
盡管不僅提供了客戶端的SDK以及前後端的API,但是,怎麼說也要講講我純前端的方案吧。
3 時代帶來了什麼
好吧,人臉識別在前端依然是在刀耕火種的遠古時代,然而,我們的基礎建設已經起步,希望後續的一些相關介紹能為各位看官帶來一定的啟發。
3.1 Shape Detection API
隨著客戶端硬件的計算能力逐漸提高,瀏覽器層麵得到的權限也越來越多,由於圖像處理需要耗費大量的計算資源,實際上瀏覽器上也能承擔圖像檢測的一些工作,因此就搞出了個Shape Detection API。
以下幾個簡單的例子介紹了基本的用法,在嚐試編輯並運行這些代碼之前,請確保在你的Chrome版本以及該新特性已經被激活,另外該API受同源策略所限製:
chrome://flags/#enable-experimental-web-platform-features
- 條形碼: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));
- 人臉: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));
- 文本: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 圖像中的人臉檢測
圖像的人臉檢測比較簡單,隻需要傳入一個圖片的元素,就能直接調起該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);
});
}
3.3 視頻中的人臉檢測
視頻中的人臉檢測跟圖像相差不大,通過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);
3.4 時光倒流到沒有API的日子
實際上,在很久很久以前,也有不少解決方案存在。由於硬件條件以及沒有硬件加速等限製的情況,一直沒有被廣泛地投入生產。
a. tracking.js
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 總結
4.1 未來的發展
這些前沿的技術將會在前端得到更為廣泛的應用和支持是毋庸置疑的,未來的圖像在前端也會隨著傳統圖像處理->學習+圖像處理的方式前進,這一切的功勞離不開基礎設施(硬件、瀏覽器、工具、庫等)的逐漸增強和完善,其中包括但不僅限於:
- getUserMedia/Canvas => 圖像 / 視頻的操作
- Shape Detection API => 圖像檢測
- Web Workers => 並行計算能力
- ConvNetJS => 深度學習框架
4.2 實際上並沒有那麼樂觀
4.2.1 準確率
對於正臉(多個)的識別率還是比較高的,但是在側臉已經有障礙物的情況下,檢測的效果並不理想。
4.2.2 處理速度
對於圖像中人臉檢測的例子2.2,耗費時間300ms+(實際上無法滿足大分辨率視頻實時處理),是調用Opencv的檢測速度100ms的三倍之多。
4.2.3 特性
還有很多需要完善的地方:如不支持眼鏡狀態、性別、年齡估計、表情識別、人種、笑容、模煳檢測等主流服務提供商提供的服務。
4.3 想說又說不完的
源代碼暫時沒有整理好,工作飽和中,後麵會分享出來:https://github.com/x-cold
關於人臉檢測在不同場景的適應性,以及檢測消耗的時間暫時沒有數據支撐,後麵考慮引入PASCAL VOC、AT&T提供的樣本進行小規模的測試。
團隊招人中,前端和設計師校招社招都要:ais-ued-jobs@list.alibaba-inc.com
5 參考
- 人臉識別技術大總結(1):Face Detection & Alignment: https://blog.jobbole.com/85783/
- 阿裏巴巴直播防控中的實人認證技術: https://xianzhi.aliyun.com/forum/mobile/read/635.html
- 前端在人工智能時代能做些什麼?:https://yq.aliyun.com/articles/153198
- ConvNetJS Deep Learning in your browser:https://cs.stanford.edu/people/karpathy/convnetjs/
- Face detection using Shape Detection API:https://paul.kinlan.me/face-detection/
最後更新:2017-08-13 22:26:02