Handtrack.js 開源:3行JS程式碼搞定手部動作跟蹤

weixin_33806914發表於2019-03-27

近日,GitHub上開源了一個名為Handtrack.js的專案,有了它,你只需要3行程式碼就能用來檢測圖片中手的動作。

\"\"

演示地址:https://victordibia.github.io/handtrack.js/#/

執行時:22 FPS,Macbook Pro 2018(2.5 Ghz),Chrome瀏覽器。13FPS,Macbook Pro 2014(2.2GHz)。

不久之前,一個使用TensorFlow物件檢測API跟蹤圖片中手部動作的實驗結果把我震驚到了。我把訓練模型和原始碼開放了出來。

從那時起,它就被用來開發一些非常有趣的東西,比如:

一個可以幫助孩子進行拼寫練習的工具

一個可以識別手勢的外掛

一個乒乓球遊戲

有很多人想要嘗試我提供的訓練模型,但無法設定好Tensorflow(安裝問題、TF版本問題、匯出圖表,等等)。幸運的是,Tensorflow.js解決了其中的一些安裝和發行問題,因為它經過優化,可以在瀏覽器的標準化環境中執行。為此,我建立了Handtrack.js庫

它可以讓開發人員使用經過訓練的手部檢測模型快速建立手勢互動原型。

這個庫的目標是隱藏與載入模型檔案相關的步驟,為使用者提供有用的函式,並允許使用者在沒有任何ML經驗的情況下檢測影像中的手,你不需要自己訓練模型。

你也無需匯出任何圖或已儲存的模型。你可以直接在Web應用程式中包含handtrack.js(詳情如下),然後呼叫這個庫提供的方法。

如何在Web應用程式中使用它?

你可以直接在script標籤中包含這個庫的URL地址,或者使用構建工具從npm中匯入它。

使用script標籤

Handtrack.js的最小化js檔案目前託管在jsdelivr上,jsdelivr是一個免費的開源CDN,讓你可以在Web應用程式中包含任何的npm包。

\u0026lt;script src=\u0026quot;https://cdn.jsdelivr.net/npm/handtrackjs/dist/handtrack.min.js\u0026quot;\u0026gt; \u0026lt;/script\u0026gt;

在將上面的script標籤新增到html頁面後,就可以使用handTrack變數引用handtrack.js,如下所示。

const img = document.getElementById('img');  handTrack.load().then(model =\u0026gt; {     model.detect(img).then(predictions =\u0026gt; {      console.log('Predictions: ', predictions) // bbox predictions    });});

上面的程式碼段將列印出通過img標籤傳入的影像的預測邊框,如果換了視訊或通過攝像頭提交影像幀,那麼就可以“跟蹤”在每一幀中出現的手。

\"\"

使用handtrack.js跟蹤影像中的手,你可以呼叫renderPredictions()方法在canvas物件中繪製檢測到的邊框和源影像。

使用NPM

你可以使用以下命令將handtrack.js作為npm包來安裝:

npm install --save handtrackjs

下面給出瞭如何在React應用程式中匯入和使用它的示例。

import * as handTrack from 'handtrackjs';const img = document.getElementById('img');// Load the model.handTrack.load().then(model =\u0026gt; {  // detect objects in the image.  console.log(\u0026quot;model loaded\u0026quot;)  model.detect(img).then(predictions =\u0026gt; {    console.log('Predictions: ', predictions);   });});

\"\"

Handtrack.js的API

Handtrack.js提供了幾種方法。兩個主要的方法是load()和detect(),分別用於載入手部檢測模型和獲取預測結果。

load()方法接受可選的模型引數,允許你控制模型的效能。這個方法以webmodel格式(也託管在jsdelivr上)載入預訓練的手部檢測模型。

detect()方法接受輸入源引數(img、video或canvas物件)並返回影像中手部位置的邊框預測結果。

const modelParams = {  flipHorizontal: true,   // flip e.g for video   imageScaleFactor: 0.7,  // reduce input image size .  maxNumBoxes: 20,        // maximum number of boxes to detect  iouThreshold: 0.5,      // ioU threshold for non-max suppression  scoreThreshold: 0.79,    // confidence threshold for predictions.}const img = document.getElementById('img');handTrack.load(modelParams).then(model =\u0026gt; {    model.detect(img).then(predictions =\u0026gt; {    console.log('Predictions: ', predictions);   });});

預測結果格式如下:

[{  bbox: [x, y, width, height],  class: \u0026quot;hand\u0026quot;,  score: 0.8380282521247864}, {  bbox: [x, y, width, height],  class: \u0026quot;hand\u0026quot;,  score: 0.74644153267145157}]

Handtrack.js還提供了其他輔助方法:

  • model.getFPS():獲取FPS,即每秒檢測次數;

  • model.renderPredictions(predictions, canvas, context, mediasource):在指定的畫布上繪製邊框(和源影像);

  • model.getModelParameters():返回模型引數;

  • model.setModelParameters(modelParams):更新模型引數;

  • dispose():刪除模型例項;

  • startVideo(video):在給定的視訊元素上啟動攝像頭視訊流。返回一個promise,可用於驗證使用者是否提供了視訊許可權;

  • stopVideo(video):停止視訊流。

庫大小和模型大小

庫大小為810 KB,主要是因為它與tensorflow.js庫捆綁在一起(最新版本存在一些未解決的問題)。

模型大小為18.5 MB,在初始載入頁面時需要等待一會兒。TF.js模型通常分為多個檔案(在本例中為四個4.2 MB的檔案和一個1.7 MB的檔案)。

工作原理

Handtrack.js使用了Tensorflow.js庫,一個靈活而直觀的API,用於在瀏覽器中從頭開始構建和訓練模型。它提供了一個低階的JavaScript線性代數庫和一個高階的層API。

建立Handtrack.js庫

\"\"

建立基於Tensorflow.js的JavaScript庫的步驟

資料彙編

這個專案中使用的資料主要來自Egohands資料集。其中包括4800張人手的影像,帶有邊框,使用谷歌眼鏡捕獲。

模型訓練

使用Tensorflow物件檢測API訓練模型。對於這個專案,我們使用了Single Shot MultiBox DetectorMobileNetV2架構。然後將訓練好的模型匯出為savedmodel。

模型轉換

Tensorflow.js提供了一個模型轉換工具,可以用它將savedmodel轉換為可以在瀏覽器中載入的webmodel格式。最後,在轉換過程中刪除了物件檢測模型圖的後處理部分。這個優化可以讓檢測和預測操作的速度加倍。

庫的包裝和託管

這個庫由一個主類組成,這個類提供了一些用於載入模型、檢測影像的方法以及一組其他有用的函式,例如startVideo、stopVideo、getFPS()、renderPredictions()、getModelParameters()、setModelParameters(),等等。方法的完整描述可以在Github上找到.

然後使用rollup.js捆綁原始檔,並在npm上釋出(包括webmodel檔案)。目前Handtrack.js與Tensorflow.js(v0.13.5)捆綁在一起,主要是因為在編寫這個庫的時候,Tensorflow.js(v0.15)在載入影像/視訊標籤為張量時會發生型別錯誤。如果新版本修復了這個問題,我也將更新到最新版本。

什麼時候應該使用Handtrack.js?

如果你對基於手勢的互動式體驗感興趣,Handtrack.js可能會很有用。使用者不需要使用任何額外的感測器或硬體就可以立即獲得基於手勢的互動體驗。

\"\"

下面列出了一些(並非所有)相關的場景:

  • 將滑鼠移動對映到手部移動,達到控制的目的。

  • 當手和其他物體重疊時可以表示某些有意義的互動訊號(例如觸碰物體或選擇物體)。

  • 人手運動可以作為某些動作識別的代理(例如,自動跟蹤視訊或影像中下棋或打高爾夫球的動作),或者知識簡單地計算影像或視訊中出現了多少人。

  • 互動藝術裝置,一組有趣的互動式藝術裝置控制元件。

  • 教授他人ML/AI知識。Handtrack.js庫提供了一個很有意思的介面,用於演示模型引數的變化(置信度閾值、IoU閾值、影像大小等)如何影響檢測結果。

  • 建立演示,任何人都可以輕鬆執行或體驗這些東西。

\"\"

侷限性

瀏覽器是單執行緒的:所以必須確保預測操作不會阻塞UI執行緒。每個預測可能需要50到150毫秒,所以使用者會注意到這個延遲。在將Handtrack.js整合到每秒需要多次渲染整個螢幕的應用程式中時(例如遊戲),我發現有必要減少每秒的預測數量。

逐幀跟蹤手部動作:如果想要跨幀識別手勢,需要編寫額外的程式碼來推斷手在進入、移動和離開連續幀時的ID。

不正確的預測:偶爾會出現不正確的預測(有時候會將臉檢測為手)。我發現,不同的攝像頭和光線條件都需要不同的模型引數設定(尤其是置信度閾值)才能獲得良好的檢測效果。更重要的是,這個可以通過額外的資料進行改進。

下一步

Handtrack.js代表了新形式AI人機互動的早期階段。在瀏覽器方面已經有一些很好的想法,例如用於人體姿勢檢測的posenet

以及用於在瀏覽器中檢測面部表情的handsfree.js

與此同時,我將在以下這些方面花更多的時間:

建立更好的模型:建立一個強大的基準來評估底層的手部模型。收集更多可提高準確性和穩定性的資料。

額外的詞彙表:在構建樣本時,我發現這種互動方法的詞彙表很有限。最起碼還需要支援更多的狀態,比如拳頭和攤開的手掌。這意味著需要重新標記資料集(或使用一些半監督方法)。

額外的模型量化:現在,我們使用的是MobilenetV2。是否還有更快的解決方案?

英文原文:https://hackernoon.com/handtrackjs-677c29c1d585

更多內容,請關注前端之巔。

\"\"

相關文章