本文要來介紹的資源是 MediaPipe TouchDesigner Plugin,這個套件核心理念是在 TouchDesigner 中打造一個開箱即用 MediaPipe 功能,整個套件就是一個壓縮檔,解壓縮後直接打開其中隨附的專案,就可以用了!不用花時間配環境! 不用寫程式碼!
下載 MediaPipe Plugin
首先,前往 官方 GitHub 儲存庫 下載套件的壓縮檔。從儲存庫頁面右側欄位中進入 Release 頁面,點擊最新版本的 release.zip 進行下載。
下載完成後,將 release.zip 解壓縮到任意位置,並開啟「MediaPipe TouchDesigner.toe」專案。
開啟專案後,通常需要等待幾秒鐘時間讓系統啟動 MediaPipe,這個套件會使用你的網路攝影機 (Webcam) 來當作影像輸入,啟動完成的畫面如下。
小提示:鍵盤 P 可以開關右側的參數面板。
操作介面說明
MediaPipe 專案之中大致上可以分成兩個區塊,一個是左側紅框的 MediaPipe 核心,另一個是右側白框中的辨識結果輸出:
- MediaPipe 核心:開 / 關各種辨識模型的功能、設定追蹤的選項或各種模型參數
- 辨識結果輸出:包含臉、肢體、手勢、物件追蹤等輸出,可從中取出所需的資訊。
MediaPipe 核心中包含兩個最重要的選項,一是紅框處的攝影機選擇,二是黃框處的辨識功能開關。攝影機需要能正常使用,辨識功能要打開,最後我們才能順利拿到正確的辨識結果。
MediaPipe Plugin 有設定好臉部、臉譜、手與手勢、肢體、物件和影像切割等功能,在本文中我們先來介紹最常使用的五官位置追蹤、手部位置追蹤與手勢狀態辨識,目標是在 TouchDesigner 中用攝影機追蹤到我們的鼻子 (五官之一) 和手的位置,並辨識現在的手勢狀態。
當這些辨識能成功實作,你就已有能力將這個技術應用於互動設計!
五官位置追蹤
MediaPipe 套件有隨附一些 Google 預先訓練好的模型,也包含追蹤五官位置的臉部辨識模型。
首先我們要設定 MediaPipe 核心,請確保網路攝影機能正常運作,並開啟 Detect faces 選項。
打開 Detect faces 後,現在應該能在 MediaPipe 核心上看到辨識的結果,face_detector 上也能單獨看到辨識的五官位置。
我們需要從 face_detector 中取出五官的座標,因此請滑鼠右鍵 Output 0,拉一個 Null 出來,並重新命名為 face_input 以方便辨識。
接下來從 face_input 拉出兩個 Select,由於我預設你最後輸出的畫面解析度為 1280x720,比例是 16:9,而 MediaPipe 輸出的五官座標範圍皆為 0~1,因此我們需要分別對 XY 座標做處理。
在此之前,我們需要先取出指定的五官 (鼻子) 座標,因此分別對兩個 Select 的 Channel Names 做以下設定:
- p*:nose_tip:x
- p*:nose_tip:y
這樣可以讓 Select 能取出所有模型偵測到的鼻子座標 (預設上限 10 人)。
拿到鼻子的座標後,就可以來處理 XY 比例不同的問題。計算 16 / 9 約等於 1.7,預設後續渲染的畫面中心座標為 (0, 0)。
因此分別拉出兩個 Math,並設定 To Range 為:
- X:(-1.7, 1.7)
- Y:(1, -1)
由於 MediaPipe 可以偵測多張臉,且沒偵測到臉的座標會顯示 0,經 Math 計算後會是 (-1.7, 1),因此需要有一個數值來判斷現在有沒有偵測到臉。
請從 Y 的 Select 拉出一個 Logic,並設定 Convert Input 為「Off When Zero Or Less」。
另外,記得把 Time Slice 關掉,我們不需要它。
先前處理的數值都是分成好多個 Channel,現在我們需要將所有 Channel 合併成一個 Channel,讓資料會呈現一個橫軸為 0~10 的折線圖,這個概念有點像將一堆變數存成一個陣列,主要是方便後續應用。
因此,請分別為 XY 和剛才的 Logic 拉出 Shuffle,並設定 Method 為「Sequence All Samples」。
快完成了!現在要考慮未來的維護問題,為了讓我們能輕易辨識哪個是 XY 或臉偵測的狀態,最好要來重新命名一下。
因此,請再分別拉出三個 Rename,並命名為:
- x
- y
- active
最後,我們用一個 Merge 來合併 x、y、active 三個數值成一個 OP,並用一個命名成 face_output 的 Null 做結束。
下一步你可以自由應用 face_output 的資料,以下這支影片是將這筆資料用在 Geometry 的實例 (Instance),詳細操作可參考我們過去發表的 Instance 實例與大量生成物件 教學。
手部位置追蹤
MediaPipe 可以追蹤雙手的關節座標,首先同樣需確認 MediaPipe 核心的網路攝影機和 Detect hands 有沒有開啟與正常運作。
接下來,我們要從 hand_tracking 的 Output 1 拉一個 Null 並命名為 hand_input。
同樣因為輸出畫面的長寬比例不同關係,需分別對 XY 座標的數值做處理。
請再拉出兩個 Select,並分別設定 Channel Names 為:
- h*:index_finger_tip:x
- h*:index_finger_tip:y
這個設定是取出食指尖端的座標,你可以依需求更改成其他關節。
接下來要調整座標範圍,分別拉出兩個 Math,並設定 To Range 為:
- (-1.7, 1.7)
- (-1, 1)
同樣的,我們要從 Y 拉出一個 Logic 來偵測手是否存在,請設定 Convert Input 為「Off When Zero Or Less」。
Time Slice 也要關掉。
用 Shuffle 來合併為一個 Channel,Method 需設定為「Sequence All Samples」。
為方便後續維護,用 Rename 分別重新命名為:
- x
- y
- active
最後,用 Merge 合併 x、y、active 三個數值,並拉出一個 Null 命名為 hand_output。
同樣的,你可以參考我們過去的 Instance 實例與大量生成物件 教學來將座標對應到 Geometry 中的物件。
手勢狀態辨識
MediaPipe 提供的手勢辨識模型可以分辨握拳、布、剪刀、讚與倒讚的手勢。請從 hand_tracking 的 Output 4 拉出 Null 並命名為 gesture_input。
假設我們要偵測握拳的手勢,可拉出一個 Select,並設定 Channel Names 為「h*:Closed_first」。
你可以測試看看,會發現當偵測到握拳手勢時,它輸出的是一個不斷變化的浮點數。然而,我們須要的僅「有」或「沒有」握拳兩種狀態。
因此,請於 Select 後拉出一個 Logic,並設定 Convert Input 為「Off When Zero Or Less」。
記得關掉 Time Slice。
再接一個 Shuffle 來合併數值,設定 Method 為「Sequence All Samples」。
用 Rename 重新命名為 gesture。
最後接一個 Null 並命名為 gesture_output,結束!
同樣可以用 Instance 實例與大量生成物件 的方法,在辨識到指定手勢時更改物件顏色!