Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
freem
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Openai/692fcfd8-4b44-800f-a184-fa098175a6d5
(section)
Add languages
Page
Discussion
English
Read
Edit
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
Edit source
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Assistant: 好,我直接給你一個 「手勢 1~10」偵測版,用 CVZone + OpenCV。 === 好,我直接給你一個 「手勢 1~10」偵測版,用 CVZone + OpenCV。 邏輯說明: * 用 fingersUp() 拿到 [thumb, index, middle, ring, pinky] * 依照中國數字手勢的常見定義寫規則: - 1:食指 - 2:食指 + 中指 - 3:拇指 + 食指 + 中指 - 4:除拇指出外四指全伸 - 5:五指全伸 - 6:拇指 + 小指(shaka) - 7:拇指 + 食指 + 中指 - 8:拇指 + 食指(手槍狀) - 9:只用食指,額外用手指角度做粗略判斷(和 1 區分可能不完美) - 10:兩隻手都比「1」,視為交叉 10(不強制真的交叉,簡化處理) : ==== <syntaxhighlight lang="python">from cvzone.HandTrackingModule import HandDetector ==== import cv2 import math === 影像來源:0 為內建攝影機 === cap = cv2.VideoCapture(0) === 建立手部偵測器,允許最多 2 隻手(為了手勢10) === detector = HandDetector(detectionCon=0.7, maxHands=2) def classify_single_hand_number(hand, fingers): """ 根據單手的 fingersUp 結果判斷數字 1~9 hand: 單手資訊 (包含 lmList, bbox, type 等) fingers: [thumb, index, middle, ring, pinky] (0/1) 回傳 (number, label) 或 (None, "None") """ pattern = tuple(fingers) # 轉成 tuple 方便比對 # 1~8 直接用固定模式比對 mapping = { (0, 1, 0, 0, 0): (1, "1"), (0, 1, 1, 0, 0): (2, "2"), (1, 1, 1, 0, 0): (3, "3"), (0, 1, 1, 1, 1): (4, "4"), (1, 1, 1, 1, 1): (5, "5"), (1, 0, 0, 0, 1): (6, "6"), (1, 1, 1, 0, 0): (7, "7"), (1, 1, 0, 0, 0): (8, "8"), } if pattern in mapping: return mapping[pattern] # ---- 嘗試把「9」和「1」做粗略區別 ---- # 只伸出食指,有可能是 1 或 9 if pattern == (0, 1, 0, 0, 0): lm_list = hand["lmList"] # 21 個關鍵點 # 食指:MCP = 5, PIP = 6, DIP = 7, TIP = 8 mcp = lm_list[5] # [x, y, z] pip = lm_list[6] dip = lm_list[7] tip = lm_list[8] # 計算 MCP→TIP 的直線長度 dist_mcp_tip = math.dist(mcp[:2], tip[:2]) # 計算 MCP→PIP + PIP→DIP + DIP→TIP 的「折線」長度 dist_mcp_pip = math.dist(mcp[:2], pip[:2]) dist_pip_dip = math.dist(pip[:2], dip[:2]) dist_dip_tip = math.dist(dip[:2], tip[:2]) poly_len = dist_mcp_pip + dist_pip_dip + dist_dip_tip # 如果手指「很彎」,折線長度會明顯大於直線長度 # 這邊用一個很粗略的門檻:poly_len / dist_mcp_tip > 1.25 視為 9 if dist_mcp_tip > 0 and poly_len / dist_mcp_tip > 1.25: return (9, "9 (hook)") else: return (1, "1") # 其餘模式不判斷數字 return (None, "None") def classify_number(hands): """ 根據所有偵測到的手,回傳 (number, label, bbox_for_draw) number: 1~10 或 None label: 顯示在畫面上的文字 bbox_for_draw: 選一個 bbox 用來標文字 (x, y, w, h) """ if not hands: return None, "No Hand", None # 先嘗試判斷「10」:兩手都比 1(只伸食指) if len(hands) >= 2: nums = [] for h in hands[:2]: fingers = detector.fingersUp(h) n, _ = classify_single_hand_number(h, fingers) nums.append(n) if nums[0] == 1 and nums[1] == 1: # 視為手勢 10 # bbox 就抓第一隻手來畫 bbox10 = hands[0]["bbox"] return 10, "10", bbox10 # 若不是 10,就只看第一隻手來判斷 1~9 main_hand = hands[0] bbox = main_hand["bbox"] fingers = detector.fingersUp(main_hand) number, label = classify_single_hand_number(main_hand, fingers) if number is None: return None, "Unknown", bbox else: return number, label, bbox while cap.isOpened(): success, img = cap.read() if not success: break # 找手 hands, img = detector.findHands(img) number, label, bbox = classify_number(hands) # 在畫面上顯示結果 if bbox is not None: x, y, w, h = bbox text = f"Gesture: {label}" cv2.putText(img, text, (x, y - 20), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 2) # 也在終端機印出方便 debug if number is not None: print("Detected number:", number, "|", label) cv2.imshow("Hand Number 1-10", img) if cv2.waitKey(1) & 0xFF == ord("q"): break cap.release() cv2.destroyAllWindows() </syntaxhighlight> ===== 1. 需要先安裝: ``<code>bash pip install opencv-python cvzone mediapipe </code>`` ===== # 執行程式後: - 對著鏡頭比出 1~8,應該會蠻穩定辨識。 - 兩手同時比「1」→ 會顯示為 10。 - 彎曲的「鉤狀食指」有機會被判為 9(但因為角度、距離關係,不一定每次都成功)。 如果你願意,我也可以幫你: * 把每個手勢對應的「圖片 + 數字」做成教學視窗(用 Tkinter 或 Pygame) * 或加上「語音播報」(比出幾,就念出幾,中文或台語都可以 😄) 你想接下來接哪一塊,我就幫你往那邊延伸。
Summary:
Please note that all contributions to freem are considered to be released under the Creative Commons Attribution-ShareAlike 4.0 (see
Freem:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)