手把手教你在瀏覽器中使用臉部識別軟件包

雷鋒網按:本文為雷鋒字幕組編譯的技術博客,原標題 face-api.js — JavaScript API for Face Recognition in the Browser with tensorflow.js,作者為 Vincent Mühler 。

翻譯 | 王飛 趙朋飛       整理 |  MY   


我可以很激動地說,我們終於有可能在瀏覽器中運行人臉識別程序了!在這篇文章中,我會給大家介紹一個基於 TensorFlow.js 核心的 JavaScript 模塊,這個模塊叫做 face-api.js。為了實現人臉檢測、人臉識別以及人臉特徵點檢測的目的,該模塊分別實現了三種類型的卷積神經網絡。

和往常一樣,我們先看一個簡單一點的代碼實例,用幾行的代碼以便能夠讓大家可以直接開始使用這個包。我們開始吧!


第一個 face-recognition.js,那麼現在還有其他包嗎?

如果你有閱讀過我的另外一篇關於 nodejs 進行人臉識別方面的文章:Node.js+face-recognition.js: Simple and Robust Face Recognition using Deep Learning , 你可能會意識到,一段時間以前,我構建過一個相似的包。比方說三個 face-recognition.js,將人臉識別功能引入 nodejs 當中。

起初,我沒有想到在 javascript 社區中對臉部識別軟件包的需求如此之高。對於很多人來說,face-recognition.js 似乎是一個很不錯的免費軟件包了,另外也有像微軟和亞馬遜提供的付費軟件包。但是,一直有人問我能否在瀏覽器中完整地運行整個人臉識別的流程

最後的答案是肯定的,多虧了 tensorflow.js,利用好 tfjs-core, 我成功實現了部分相似的工具,這些小工具能夠讓你得到和使用 face-recognition.js 幾乎相似的運行結果,並且是在瀏覽器中。而且最棒的一點是你不需要再安裝任何依賴項,它可以直接運行。額外的好處是它還支持 GPU 加速,在 WebGL 上運行操作。

這足讓我相信 JavaScript 社區需要這樣的瀏覽器軟件包!接下來就是發揮你自己的想象力,你可以用這個來構建各種各樣的應用程序。:)


如何用深度學習來解決人臉識別的問題

如果你是那種想要儘快開始的人(或妹子),你可以跳過這一部分並直接跳到代碼部分。但為了更好地理解 face-api.js 中用於實現人臉識別的方法,我強烈建議你按照步驟來,因為我經常被問到這一部分的問題。

為了簡單起見,我們實際想要實現的是給定一個人的臉部圖像然後對他/她進行識別,給定的圖像即輸入圖像。我們解決這個問題的方法是為每個我們想要識別的人提供一個(或多個)圖像,並用人名稱標記,即參考數據。現在我們將輸入圖像與參考數據進行比較,並找到最相似的參考圖像。如果兩個圖像足夠相似,那我們就輸出人名,否則我們輸出'未知'。

聽起來像是個不錯的計劃!但是這裡仍存在兩個問題。首先,如果我們有一張顯示多個人的圖像,並且我們想要識別所有這些圖像,那該怎麼辦呢?其次,我們還需要能夠獲得度量兩張人臉圖像的相似性的量,以便進行比較。


人臉檢測

第一個問題的答案是人臉檢測。簡單地說,我們首先找到輸入圖像中的所有的人臉。對於人臉檢測,face-api.js 實現了 SSD(Single Shot Multibox Detector),它基本上是一個基於 MobileNetV1 的 CNN,在網絡頂部疊加了一些額外的預測層。

這個網絡返回包圍每張臉的 bounding box,以及其對應的分數,即每個 boundingbox 中包含人臉的概率。這裡的分數用於過濾邊界框,因為圖像中可能根本不包含人臉。另外要注意的是,即使圖像中只有一個人,為了得到 boundingbox,也應該首先進行人臉檢測這一步驟。


人臉特徵點檢測與人臉對齊

第一個問題解決了 但是,我想指出我們接下來要對齊邊界框,在將它們傳遞到面部識別網絡之前,為每個框提取以面部為中心的圖像,因為這樣可以使面部識別更準確!

針對這個目標。face-api.js 已經實現了一個簡單的 CNN,這個網絡能夠返回給定人臉圖片的 68 個臉部特徵點。

根據特徵點的位置,boundingbox 可以被確定在臉部的中心。下面顯示的是人臉檢測的結果(左)以及人臉對齊后的結果(右)。


人臉識別

現在我們可以將提取和對齊的人臉圖像提供給人臉識別網絡,該網絡基於類似 ResNet-34 的體系結構,基本上與 dlib 中實現的體系結構相對應。該網絡已經被訓練,能夠學習將人臉的特徵映射到一個人臉描述器上(具有 128 個值的特徵向量),這一過程通常也被稱為面部嵌入。

現在回到我們最開始比較兩張臉的這個問題上:我們將使用每個提取的面部圖像的面部描述符,並將它們與參考數據的面部描述符進行比較。更確切地說,我們可以計算兩個面部描述符之間的歐氏距離,並基於閾值判斷兩個面是否相似(對於 150×150 大小的面部圖像來說,0.6 是比較好的閾值)。使用歐幾里德距離的效果非常好,但當然你也可以使用你選擇的任何類型的分類器。以下 gif 可視化了兩張圖片通過歐幾里德距離進行比較的過程。

現在,讓我們消化一下人臉識別的理論,接下來用代碼來編寫一個例子吧。


編碼時間!

在這個簡短的例子中,我們將逐步了解如何在以下輸入圖像中識別多個人臉:


包含腳本

首先,從 dist/face-api.js 獲取最新的編譯,或者 從 dist/face-api.min.js 獲取修訂版,並將腳本包含進來:

如果使用 npm:


加載模型數據

根據您的應用程序的需求,您可以專門加載您需要的模型,但是要運行一個完整的端到端示例,我們需要加載人臉檢測、 臉部特徵點和人臉識別模型。模型文件可以在 repo 或點擊這裡獲取。

模型的權重已經被量化,與原始模型相比,將模型文件的大小減少了 75%,以允許您的客戶只加載所需的最少數據。此外,模型權重被分割成最大 4 MB 的塊,允許瀏覽器緩衝這些文件,以便這些文件只被加載一次。

模型文件可以簡單的被當做瀏覽器的靜態資源,或者你可以在其他地方託管它們,並可以通過特定的路由或 URL 加載這些文件。假設你將它們和你的其他資源一起放到模型目錄下(public/models):

或者,如果你僅僅想加載特定的模型: 


從輸入圖像中獲得對所有面孔的完整描述 

神經網絡接受 HTML 圖像、畫布、視頻或者張量等形式的輸入。使用 score > minScore 檢測面部邊界框,我們簡單的說:

完整的面部描述包括檢測結果(邊界框+分值),臉部特徵,以及計算描述符。正如你所看到的,在前面的討論中 faceapi.allFaces 在後台做了所有的工作。然而,你也可以手動獲取臉部位置和特徵點。如果你以此為目標的話,可以在 github repo 找到很多例子。

注意,邊界框和特徵點位置依賴於原始圖像/媒體的大小。如果顯示的圖像大小與原始圖像大小不一致,您可以簡單地調整大小:

我們可以通過將邊界框繪製到畫布上來可視化檢測結果 :

臉部特徵點可以如下方式顯示:

通常,我所做的是將一個絕對定位的畫布疊加在 img 元素的頂部,它們的寬度和高度是相同的(可以查看 github 上的示例了解更多信息)


面部識別

現在我們知道了如何檢索輸入圖像中所有人臉的位置和描述了,我們將從一些圖像中指出每個人臉並計算出人臉的描述符。這些描述符將會是我們的參考數據。

假設我們有一些可用的示例圖像,我們首先從一個 url 獲取圖像,並使用 faceapi.bufferToImage 從數據緩衝區中創建 HTML 圖像元素:

接下來,對於每一個圖像,我們定位主題並計算面部描述符,就像我們之前對輸入圖像所做的操作:

現在,我們要做的所有事情都是循環遍歷我們輸入圖像的面部描述,並找到與參考數據距離最小的描述符:

正如前面提到的,我們使用歐氏距離度量相似度,結果證明它是有效的。我們最終得到了在輸入圖像中檢測到的每個面孔的最佳匹配。

最後,我們可以將邊界框和它們的標籤一起繪製到畫布上,以顯示結果:


好了!到目前為止,我希望您已經了解了如何使用這個 api。另外,我還建議您看一下 repo 的其他例子。現在盡情享受這個軟件包吧!

如果你喜歡這篇文章,歡迎點贊並在 medium 或 twitter 上關注我。也歡迎在 github repository 上評價。請繼續關注更多教程!


原文鏈接:https://itnext.io/face-api-js-javascript-api-for-face-recognition-in-the-browser-with-tensorflow-js-bcc2a6c4cf07

雷鋒網雷鋒網


想在手機閱讀更多Javascript資訊?下載【香港矽谷】Android應用
分享到Facebook
技術平台: Nasthon Systems