[TouchDesigner] MediaPipe 臉部、骨架、手勢辨識基礎教學

MediaPipe 是一個由 Google 開發的開源軟體框架,專門用於開發透過影像分析現實物件的電腦視覺技術,辨識範圍包括:人臉表情、肢體骨架、手勢。這個框架同時支援 Windows、macOS、Linux 等多種平台與 Python、C++ 等程式語言,而 TouchDesigner 社群先前已釋出 MediaPipe Plugin,讓創作者不用學程式語言也可以輕易的應用 MediaPipe!

本文要來介紹的資源是 MediaPipe TouchDesigner Plugin,這個套件核心理念是在 TouchDesigner 中打造一個開箱即用 MediaPipe 功能,整個套件就是一個壓縮檔,解壓縮後直接打開其中隨附的專案,就可以用了!不用花時間配環境! 不用寫程式碼!

下載 MediaPipe Plugin

首先,前往 官方 GitHub 儲存庫 下載套件的壓縮檔。從儲存庫頁面右側欄位中進入 Release 頁面,點擊最新版本的 release.zip 進行下載。

image.png

image.png

下載完成後,將 release.zip 解壓縮到任意位置,並開啟「MediaPipe TouchDesigner.toe」專案。

image.png

開啟專案後,通常需要等待幾秒鐘時間讓系統啟動 MediaPipe,這個套件會使用你的網路攝影機 (Webcam) 來當作影像輸入,啟動完成的畫面如下。

小提示:鍵盤 P 可以開關右側的參數面板。

image.png

操作介面說明

MediaPipe 專案之中大致上可以分成兩個區塊,一個是左側紅框的 MediaPipe 核心,另一個是右側白框中的辨識結果輸出:

  • MediaPipe 核心:開 / 關各種辨識模型的功能、設定追蹤的選項或各種模型參數
  • 辨識結果輸出:包含臉、肢體、手勢、物件追蹤等輸出,可從中取出所需的資訊。

image.png

MediaPipe 核心中包含兩個最重要的選項,一是紅框處的攝影機選擇,二是黃框處的辨識功能開關。攝影機需要能正常使用,辨識功能要打開,最後我們才能順利拿到正確的辨識結果。

image.png

MediaPipe Plugin 有設定好臉部、臉譜、手與手勢、肢體、物件和影像切割等功能,在本文中我們先來介紹最常使用的五官位置追蹤、手部位置追蹤與手勢狀態辨識,目標是在 TouchDesigner 中用攝影機追蹤到我們的鼻子 (五官之一) 和手的位置,並辨識現在的手勢狀態。

當這些辨識能成功實作,你就已有能力將這個技術應用於互動設計!

五官位置追蹤

MediaPipe 套件有隨附一些 Google 預先訓練好的模型,也包含追蹤五官位置的臉部辨識模型。

首先我們要設定 MediaPipe 核心,請確保網路攝影機能正常運作,並開啟 Detect faces 選項。

image.png

打開 Detect faces 後,現在應該能在 MediaPipe 核心上看到辨識的結果,face_detector 上也能單獨看到辨識的五官位置。

我們需要從 face_detector 中取出五官的座標,因此請滑鼠右鍵 Output 0,拉一個 Null 出來,並重新命名為 face_input 以方便辨識。

image.png

image.png

接下來從 face_input 拉出兩個 Select,由於我預設你最後輸出的畫面解析度為 1280x720,比例是 16:9,而 MediaPipe 輸出的五官座標範圍皆為 0~1,因此我們需要分別對 XY 座標做處理。

在此之前,我們需要先取出指定的五官 (鼻子) 座標,因此分別對兩個 Select 的 Channel Names 做以下設定:

  • p*:nose_tip:x
  • p*:nose_tip:y

這樣可以讓 Select 能取出所有模型偵測到的鼻子座標 (預設上限 10 人)。

image.png

拿到鼻子的座標後,就可以來處理 XY 比例不同的問題。計算 16 / 9 約等於 1.7,預設後續渲染的畫面中心座標為 (0, 0)。

因此分別拉出兩個 Math,並設定 To Range 為:

  • X:(-1.7, 1.7)
  • Y:(1, -1)

image.png

由於 MediaPipe 可以偵測多張臉,且沒偵測到臉的座標會顯示 0,經 Math 計算後會是 (-1.7, 1),因此需要有一個數值來判斷現在有沒有偵測到臉。

請從 Y 的 Select 拉出一個 Logic,並設定 Convert Input 為「Off When Zero Or Less」。

image.png

另外,記得把 Time Slice 關掉,我們不需要它。

image.png

先前處理的數值都是分成好多個 Channel,現在我們需要將所有 Channel 合併成一個 Channel,讓資料會呈現一個橫軸為 0~10 的折線圖,這個概念有點像將一堆變數存成一個陣列,主要是方便後續應用。

因此,請分別為 XY 和剛才的 Logic 拉出 Shuffle,並設定 Method 為「Sequence All Samples」。

image.png

快完成了!現在要考慮未來的維護問題,為了讓我們能輕易辨識哪個是 XY 或臉偵測的狀態,最好要來重新命名一下。

因此,請再分別拉出三個 Rename,並命名為:

  • x
  • y
  • active

image.png

最後,我們用一個 Merge 來合併 x、y、active 三個數值成一個 OP,並用一個命名成 face_output 的 Null 做結束。

image.png

下一步你可以自由應用 face_output 的資料,以下這支影片是將這筆資料用在 Geometry 的實例 (Instance),詳細操作可參考我們過去發表的 Instance 實例與大量生成物件 教學。

手部位置追蹤

MediaPipe 可以追蹤雙手的關節座標,首先同樣需確認 MediaPipe 核心的網路攝影機和 Detect hands 有沒有開啟與正常運作。

image.png

接下來,我們要從 hand_tracking 的 Output 1 拉一個 Null 並命名為 hand_input。

image.png

image.png

同樣因為輸出畫面的長寬比例不同關係,需分別對 XY 座標的數值做處理。

請再拉出兩個 Select,並分別設定 Channel Names 為:

  • h*:index_finger_tip:x
  • h*:index_finger_tip:y

這個設定是取出食指尖端的座標,你可以依需求更改成其他關節。

image.png

接下來要調整座標範圍,分別拉出兩個 Math,並設定 To Range 為:

  • (-1.7, 1.7)
  • (-1, 1)

image.png

同樣的,我們要從 Y 拉出一個 Logic 來偵測手是否存在,請設定 Convert Input 為「Off When Zero Or Less」。

image.png

Time Slice 也要關掉。

image.png

用 Shuffle 來合併為一個 Channel,Method 需設定為「Sequence All Samples」。

image.png

為方便後續維護,用 Rename 分別重新命名為:

  • x
  • y
  • active

image.png

最後,用 Merge 合併 x、y、active 三個數值,並拉出一個 Null 命名為 hand_output。

image.png

同樣的,你可以參考我們過去的 Instance 實例與大量生成物件 教學來將座標對應到 Geometry 中的物件。

手勢狀態辨識

MediaPipe 提供的手勢辨識模型可以分辨握拳、布、剪刀、讚與倒讚的手勢。請從 hand_tracking 的 Output 4 拉出 Null 並命名為 gesture_input。

image.png

image.png

假設我們要偵測握拳的手勢,可拉出一個 Select,並設定 Channel Names 為「h*:Closed_first」。

image.png

你可以測試看看,會發現當偵測到握拳手勢時,它輸出的是一個不斷變化的浮點數。然而,我們須要的僅「有」或「沒有」握拳兩種狀態。

因此,請於 Select 後拉出一個 Logic,並設定 Convert Input 為「Off When Zero Or Less」。

image.png

記得關掉 Time Slice。

image.png

再接一個 Shuffle 來合併數值,設定 Method 為「Sequence All Samples」。

image.png

用 Rename 重新命名為 gesture。

image.png

最後接一個 Null 並命名為 gesture_output,結束!

image.png

同樣可以用 Instance 實例與大量生成物件 的方法,在辨識到指定手勢時更改物件顏色!

相關文章

Ted Liou

雲科碩士在讀中,專注於 Unity C#、TouchDesigner 技術,常把技術筆記分享到部落格,偶爾還直接挪用文章來當教材的研究生。