🧠 RP5 + CVZone + MediaPipe + PiCamera2 雙手偵測與距離計算教學


🧰 一、準備工作

✅ 硬體

  • Raspberry Pi 5

  • Raspberry Pi Camera Module v2/v3

  • microSD(已安裝 Raspberry Pi OS 64-bit)


🛠️ 二、安裝必要套件

1️⃣ 安裝 PiCamera2 與 OpenCV

sudo apt update
sudo apt install -y python3-picamera2 python3-opencv libatlas-base-dev

2️⃣ 安裝 mediapipe(支援 ARM 的最新版)

pip install mediapipe==0.10.9

3️⃣ 安裝 CVZone(需從 GitHub 安裝以支援 ARM)

pip install git+https://github.com/cvzone/cvzone.git

📌 CVZone 是一個基於 OpenCV + MediaPipe 的封裝,內建手勢追蹤、手指辨識等功能。


📸 三、完整程式碼

🔹 檔名:cvzone_handtrack_picamera2.py

import cv2
from picamera2 import Picamera2
import time
from cvzone.HandTrackingModule import HandDetector
import math

# 初始化 PiCamera2
picam2 = Picamera2()
picam2.preview_configuration.main.size = (640, 480)
picam2.preview_configuration.main.format = "RGB888"
picam2.configure("preview")
picam2.start()
time.sleep(2)

# 初始化 HandDetector,支援雙手
detector = HandDetector(detectionCon=0.7, maxHands=2)

while True:
    # 取得相機畫面
    frame = picam2.capture_array()

    # 偵測手部
    hands, img = detector.findHands(frame)

    finger_counts = []
    hand_centers = []

    if hands:
        for hand in hands:
            # 計算手指數
            fingers = detector.fingersUp(hand)
            finger_counts.append(sum(fingers))

            # 取得手掌中心點
            cx, cy = hand["center"]
            hand_centers.append((cx, cy))

            # 顯示數量
            cv2.putText(img, f"Fingers: {sum(fingers)}", (cx - 50, cy - 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    # 計算雙手之間的距離
    if len(hand_centers) == 2:
        x1, y1 = hand_centers[0]
        x2, y2 = hand_centers[1]
        distance = int(math.hypot(x2 - x1, y2 - y1))

        # 顯示距離
        mid_x = (x1 + x2) // 2
        mid_y = (y1 + y2) // 2
        cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 2)
        cv2.putText(img, f"Dist: {distance}px", (mid_x, mid_y - 20),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 255), 2)

    # 顯示畫面
    cv2.imshow("RP5 + CVZone HandDetector", img)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cv2.destroyAllWindows()
picam2.stop()

✅ 成果展示功能

  • 同時追蹤左/右手(最多兩隻手)

  • 每隻手顯示伸出的手指數(例如:5 = ✋,2 = ✌️)

  • 顯示雙手之間的距離(像素計算)


📌 補充說明

模組 功能
cvzone.HandTrackingModule 包含基於 MediaPipe 的封裝,快速取得 fingersUp, handType 等資料
fingersUp() 回傳長度為 5 的陣列([1, 1, 0, 0, 0] 代表伸出大拇指與食指)
math.hypot(dx, dy) 計算兩點之間的直線距離

🧠 延伸應用建議

應用 建議
揮手觸發事件 偵測手指數連續變化進行動作觸發
控制 GPIO 裝置 手勢比 5 控制 LED 開關
體感距離互動 根據雙手距離控制聲音/動畫強度(例如打鼓遊戲)
手勢記錄 將每秒手勢狀態記錄成 CSV 或 JSON 檔供分析

 

文章標籤
全站熱搜
創作者介紹
創作者 liusming 的頭像
liusming

劉老師的跨域創想工坊

liusming 發表在 痞客邦 留言(0) 人氣(6)