PawAI
手勢辨識開發歷程總整理
手勢辨識系統 (Gesture Recognition) 驗收與架構報告

1. 底層推論模型解析
- 主要模型: MediaPipe Gesture Recognizer (Task API)
- 模型檔:
gesture_recognizer.task(Float16 精確度版本) - 運作原理: 此模型採用 Pipeline 架構,依序包含三個子網路:
- Palm Detection (手掌偵測):先在大畫面中找出「手在哪裡」。
- Hand Landmarks (手部特徵點):找出手的 21 個 3D 關節點。
- Gesture Classification (手勢分類):根據這些關節點特徵,將手勢分類成預先訓練好的類別。
- 選擇原因: 輕量化、推論速度極快,在 Jetson Nano 這種邊緣運算裝置上,只需依賴 CPU 就能流暢執行,不需佔用寶貴的 GPU 資源(GPU 可留給 LLM 或物件辨識)。
- 模型檔:
- 輔助模型: RTMPose / MediaPipe Pose
- 功能: 全身姿態估計 (Pose Estimation)。
- 用途: 提供全身骨架資訊,除了判斷人的姿勢(站、坐、跌倒)外,未來也可以用來做「手與人體綁定」(確保這隻手是眼前這個人的,而不是背景路人的)。
2. 支援的手勢與對應功能
系統結合了「MediaPipe 內建模型」、「幾何特徵計算」與「時序動態偵測」三種方法,目前共支援 7 種 手勢。
A. 靜態手勢 (由 MediaPipe 內建模型辨識)
透過 gesture_recognizer_backend.py 進行映射:
- 🖐️ 布 (Open_Palm)
palm- 功能: System Pause (系統暫停 / 安全急停)
- 👊 拳頭 (Closed_Fist)
fist- 功能: Enter Mute Mode (進入靜音/休眠模式)
- ☝️ 食指 (Pointing_Up)
index- 功能: Enter Listen Mode (進入聆聽模式)
- 👍 比讚 (Thumb_Up)
thumbs_up- 功能: 提出搖屁股 (Wiggle) 請求。注意:此為高風險動作,系統會要求再比一次「OK 手勢」進行二次確認才會真正執行。
- ✌️ YA (Victory)
peace- 功能: 提出伸懶腰 (Stretch) 請求。同樣需搭配「OK 手勢」進行二次確認。
B. 幾何特徵手勢 (自定義靜態規則)
由於 MediaPipe 原生不支援此手勢,我們透過擷取 21 個手部關節點進行純幾何計算(實作於 gesture_classifier.py):
6. 👌 OK 手勢 ok
- 辨識原理: 計算大拇指尖端 (Thumb tip) 與食指尖端 (Index tip) 的距離,並與手掌寬度做比例運算 (
_OK_TOUCH_RATIO)。同時確保其他三指伸直。 - 功能: 作為最高優先級的手勢,專門用於執行高風險指令前的 二次確認 (Secondary Confirmation)。
C. 動態手勢 (時序軌跡追蹤)
實作於 dynamic_gesture_detector.py:
7. 👋 揮手 (Wave) wave
- 辨識原理: 不依賴單一影格,而是追蹤手腕 (Wrist) 的 X 軸座標。在 1.5 秒的滾動視窗 (Rolling window) 內,偵測手腕 X 軸方向的「速度反轉次數 (Velocity reversals)」與「振幅大小 (Amplitude)」。
- 功能: 觸發打招呼 (Wave Hello) 的社交互動。(註:受限於相機距離與手腕軌跡幅度,目前較不穩定,Demo 時不建議依賴此功能)。
3. 防誤觸與穩定性機制 (Stability Filtering)
為避免把日常動作(如抓癢或聊天揮手)誤判成指令,我們設計了三道防護網:
- 多幀投票 (防雜訊):系統會連續觀察 5 張畫面,只有過半數畫面都辨識出同一個手勢,才會進入下一關。
- 時間鎖定 (防瞬間誤判):手勢必須在畫面上「刻意定住」至少 0.3 秒以上,不能閃爍或改變,系統才會確認觸發。
- 對話防呆 (情境感知):當機器人正在說話,或是剛才有人開口時,系統會自動無視(屏蔽)比讚或 YA 等一般手勢,確保對話不會被意外打斷。
4. 輸出資料規格 (Event Payload)
當手勢滿足所有穩定性條件後,vision_perception_node 會向 /event/gesture_detected (ROS2 Topic) 發布 JSON 格式的事件。大腦模組會解析此 JSON 並觸發動作。
Payload 範例:
{
"stamp": 1716000000.123,
"event_type": "gesture_detected",
"gesture": "thumbs_up",
"confidence": 0.8,
"hand": "right"
}gesture: 辨識出的手勢名稱。confidence: 信賴度。此處非分類器原始機率,而是「投票比例 (Vote Ratio)」(例: 5 幀中有 4 幀是比讚,則為 0.8)。hand:left或right(左右手資訊)。
5. 相關程式檔案清單 (File Structure)
若需追查或修改手勢辨識邏輯,請參考以下核心檔案:
A. 視覺感知端 (vision_perception package)
vision_perception_node.py- 角色: 核心調度節點 (ROS2 Node)。
- 負責: 接收相機影像、呼叫各分類器、執行投票與時間鎖定 (0.3s~0.5s) 防呆機制,並發布
/event/gesture_detected訊號。
gesture_recognizer_backend.py- 角色: MediaPipe 模型串接。
- 負責: 載入
.task模型,進行基礎靜態手勢 (拳頭、比讚、布、食指、YA) 的初步辨識與標籤映射。
gesture_classifier.py- 角色: 幾何特徵分類器。
- 負責: 透過 21 個關節點的空間幾何關係,計算食指與大拇指的距離,實作自定義的 OK 手勢。
dynamic_gesture_detector.py- 角色: 動態時序追蹤器。
- 負責: 利用 Buffer 記錄手腕 X 軸軌跡,算出速度反轉次數與振幅,藉此判斷 揮手 (Wave) 動作。
event_builder.py- 角色: JSON 封裝工具。
- 負責: 將辨識結果打包成符合系統標準的 JSON Payload。
B. 大腦決策端 (interaction_executive package)
brain_node.py- 角色: 動作執行中心。
- 負責: 接收手勢 JSON,對應執行相對應的技能 (如 Wiggle, Stretch)。同時負責對話防呆 (Conversation Gate),決定何時該忽略誤觸的手勢。
6. 系統現狀限制 (Known Constraints)
目前的手勢辨識雖然可以進行展示,但它主要是作為「事件觸發器」,且受限於目前的開發進度,存在以下已知限制:
限制一:高風險手勢容易誤觸
- 現狀描述: 目前系統在使用者聊天、抓癢時,極易誤判出「比讚 (thumbs_up)」或「YA (peace)」。雖然我們有加上「OK 二次確認」來防止狗直接亂動,但仍會跳出確認對話框打斷聊天。
限制二:動態手勢不可行
- 現狀描述: 傳統視覺分類器適合看「單張靜態照片」,這導致它很難理解「揮手 (Wave)」、「畫圈 (Circle)」、「勾手 (ComeHere)」這種具備時間連續性的動作。目前 Wave 雖然有實作但極不穩定,Circle 與 ComeHere 則尚未成熟。
限制三:OK 手勢對角度敏感
- 現狀描述: OK 是用「幾何特徵演算法 (
gesture_classifier.py)」算出來的,它不依賴黑箱神經網路,而是精算食指尖與大拇指尖的距離。這也代表它對「手指遮擋」、「鏡頭角度」比較敏感。
限制四:缺乏持續狀態 (State) 與多人處理
- 現狀描述:
- 手勢目前只是「瞬間事件」,大腦 (Brain) 只會記住最近 5 秒的動作,不具備長期的狀態記憶。
- 目前系統缺乏「多人同框綁定」機制。如果畫面中出現多雙手,系統可能會把手勢判定給錯誤的對象。
7. 未來優化方向 (Future Improvements)
針對上述的系統限制,我們已規劃了下一階段的架構升級方案:
1. 全面升級防呆機制 (Conversation Gate & 嚴格時間鎖)
- 將容易誤觸的
thumbs_up與peace加入對話防呆白名單中,只要系統在講話或正在聆聽,就全面屏蔽這些手勢。 - 針對這類高風險指令,將「時間穩定鎖」從 0.3 秒大幅拉長至 1 秒,強制使用者必須「刻意比好並定住不動」才能觸發。
2. 導入「OK 喚醒」狀態機 (Wake-up State Machine)
- 改變現有「隨時都在看手勢」的邏輯,改為類似語音助理的喚醒機制:系統平時對所有手勢免疫,必須先比出 OK 手勢喚醒系統後,接下來的 30 秒內才會受理比讚、握拳等指令;並可透過比出拳頭來主動進入休眠。
3. 解決多人同框綁定 (Identity Binding)
- 導入座標交集運算 (IoU)。將 MediaPipe 抓到的手部座標,去和 RTMPose 抓出的人體 Bounding Box 做比對,藉此確認「這隻手是屬於哪個人的」,徹底解決多人混雜的問題。
4. 重構動態手勢引擎
- 將動態手勢(如揮手、畫圈、勾手)從靜態分類器中抽離,獨立建立一個基於時間序列 (Temporal sequence) 的狀態機,利用機器學習或更嚴謹的軌跡演算法來取代現有的單純波峰計算,大幅提高辨識穩定度。
https://youtu.be/0P6fmmQO-TA?si=sFhRD51v8j36C4q8
