Day06 計算食指尖與姆指尖之間的距離
🟡 先看看程式的效果
今天的程式是利用 OpenCV 和 MediaPipe 進行即時手部偵測, 並計算食指指尖和拇指指尖之間的距離。
Today’s program uses OpenCV and MediaPipe for real-time hand detection and calculates the distance between the tip of the index finger and the tip of the thumb.
🟡 學習目標
了解 Mediapipe 手部辨識的節點編寫, 以及如果計算兩點之間的距離。
🟡 程式碼
請先下載 “計算食指尖與姆指尖的距離.py”
請按此下載
'''
Python + AI in 21 days
https://jasonworkshop.com/python
Designed by Jason Workshop
[請勿修改以上內容]
---
預備工作:
首先,請確保已安裝 opencv-python, mediapipe 模組
如不確定可直接在 Windows 的 cmd prompt 執行以下指定
pip install opencv-python mediapipe
'''
import cv2
import mediapipe as mp
import math
# 初始化 MediaPipe Hands 模組
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=2, min_detection_confidence=0.7)
mp_drawing = mp.solutions.drawing_utils # 繪製工具
# 開啟攝影機
cap = cv2.VideoCapture(0)
def calculate_distance(point1, point2):
"""計算兩點之間的歐幾里得距離"""
return math.sqrt((point2.x - point1.x) ** 2 + (point2.y - point1.y) ** 2 + (point2.z - point1.z) ** 2)
while cap.isOpened():
ret, frame = cap.read() # 讀取攝影機畫面
if not ret:
print("無法讀取攝影機畫面")
break
# 轉換 BGR 圖像到 RGB
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 偵測手部
result = hands.process(rgb_frame)
# 繪製手部關鍵點和連線
if result.multi_hand_landmarks:
for hand_landmarks in result.multi_hand_landmarks:
# 繪製手部關鍵點
'''
mp_drawing.draw_landmarks(
frame,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=1, circle_radius=2)
)
'''
# 計算食指指尖和姆指指尖的距離
# 距離的單位是基於 MediaPipe 的歸一化座標系統,這意味著距離是相對於影像尺寸的比例值,而不是以像素或其他實際世界的單位來表示。
index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
thumb_tip = hand_landmarks.landmark[mp_hands.HandLandmark.THUMB_TIP]
distance = calculate_distance(index_finger_tip, thumb_tip)
print(f"食指指尖至姆指指尖的距離: {distance:.2f}")
# 畫線在食指指尖和姆指指尖之間
cv2.line(frame,
(int(index_finger_tip.x * frame.shape[1]), int(index_finger_tip.y * frame.shape[0])),
(int(thumb_tip.x * frame.shape[1]), int(thumb_tip.y * frame.shape[0])),
(255, 255, 255), 2)
# 顯示距離在左上角
cv2.putText(frame, f"Distance: {distance:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
# 只處理第一隻手
break
# 顯示圖像
cv2.imshow('Hand Landmarks Detection', frame)
# 按下 ESC 鍵退出
if cv2.waitKey(1) & 0xFF == 27:
break
# 釋放攝影機並關閉所有視窗
cap.release()
cv2.destroyAllWindows()
🟡 小小挑戰一下
大家可以嘗試進行一些修改或改良喔! 例如:
✌️嘗試計算左右手食指尖之間的距離吧!
😁 明天見!