原文:https://paul.kinlan.me/face-detection/
在 Google 開發者峰會中,谷歌成員 Miguel Casas-Sanchez 跟我說:“嘿 Paul,我給你看一個 demo”。看完之后我必須對它進行研究。
Shape Detection API(圖形檢測API)目前在 WICG 中尚處於孵化和實驗階段,這對於平台來說是一個很好的漸進過程。
Shape Detection API 有意思的地方在於,它是基於用戶設備的一些基礎硬件功能上創建標准接口的,為 web 平台開啟了一組新功能。
在 web 中使用圖形檢測已有一段很長的時間。有很多的庫能夠實現邊緣檢測,面部檢測,條形碼和二維碼檢測(我甚至編寫過一個具有該功能的 web app)。
Shape Detection API 目前集成在 Chrome Canary(M57)中,能夠檢測面部、條形碼(和二維碼),由於 API 還處於實驗階段,你必須開啟 chrome://flags/#enable-experimental-web-platform-features。
該 API 使用相當簡單,最簡單的面部檢測是使用圖像調用該 API,獲取面部列表。
var faceDetector = new FaceDetector(); faceDetector.detect(image) .then(faces => faces.forEach(face => console.log(face))) .catch(e => { console.error("Boo, Face Detection failed: " + e); });
這里需要一個圖像對象(可以是CanvasImageSource,Blob,ImageData 或者一個 <img> 元素),將它傳遞給系統底層 API,系統將會返回一組 DetectedFace 對象,該對象實際上是包含圖像上每一個面部區域的 DetectedObject。
Miguel 寫了一個完整的 demo(是我偷來放在 JSBin 的),加載一個圖像,傳遞給檢測 API ,然后在圖像上繪制出每一個 DetectedFace 的面部矩形區域。(注意:目前僅適用於 Android 的 Chrome,桌面端的很快就能夠支持該 API)。
var image = document.getElementById('image'); var canvas = document.getElementById('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(); faceDetector.detect(image) .then(faces => { // Draw the faces on the <canvas>. var ctx = canvas.getContext('2d'); ctx.lineWidth = 2; ctx.strokeStyle = 'red'; for(let face of faces) { ctx.rect(Math.floor(face.x * scale), Math.floor(face.y * scale), Math.floor(face.width * scale), Math.floor(face.height * scale)); ctx.stroke(); } }) .catch((e) => { console.error("Boo, Face Detection failed: " + e); }); }
這有什么用呢?
啟用更多的面部檢測 API 有許多不同的使用情況,例如你能夠:
檢測面部時能夠有更好的體驗——我們使用該 API 有很大的靈活性,它允許我們在 Service 或者 Web Worker 中進行處理。
局部圖片剪裁——找到圖片中的臉后能夠自動剪裁圖片。
能夠快速標記——快速的找到場景中所有的人臉,創建一個用戶界面,使您能夠快速標記他們。
優化面部識別——一旦你有了人臉圖像,你就能夠將這些區域傳遞給面部識別工具。
目前這些都能在瀏覽器上實現嗎?是的,但你需要有漸進性的方案。
漸進性方案
很顯然這是一個純 JS API,需要訪問底層硬件的 API,但能夠“輕松的”(呵呵)漸進式的建立應用,確保使用低版本 Chrome 的用戶依然能夠訪問。
我的想法是遵循相關規范達到漸進增強:服務器 -> JS(+ 也許是 Web ASM)-> Web API,但我會更深入的研究,因為我看到了許多的挑戰。
服務器
我們可以創建一個簡單的包含 <input type='file'> 的表單,將圖像上傳到服務器,可以在服務端完成圖像檢測,然后將結果返回給客戶端。
JS
如果我們使用了 JS,我們能夠在瀏覽器上的頁面上下文中使用任意一個客戶端庫完成面部檢測。
Web Assembly:
這種方式進行圖像識別,甚至是以高性能的方式進行目標檢測,是令人難以置信的(至少在我看來)。“原生平台”早已有許多的庫(如 Open CV),主要是用 C 寫的,能夠應用到瀏覽器上,利用豐富的生態系統,也能夠達到相同的性能。
如果有人實現了多邊形檢測 API ,這將是非常有用的功能。
Web API
現在它可以使用底層系統 API 時,我們就能夠在所有的平台上普及。
我覺得這是一個很有趣的 API,它的確為平台開啟了很多的可能性,特別是對我,使用底層系統相對於使用純 javascript ,極大的提高了在 web 上的目標檢測性能,這是我期待條形碼檢測 API 的原因,它將增強二維碼掃描器 Web 應用性能的同事,降低其復雜性。