hand_landmarks_multi_hand.py
# Dieses Werk ist unter der MIT-Lizenz lizenziert.
# Copyright (c) 2013-2025 OpenMV LLC. Alle Rechte vorbehalten.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Dieses Beispiel demonstriert Googles MediaPipe-Handlandmarken-Erkennungsmodell für mehrere Hände.
#
# HINWEIS: Für dieses Beispiel wird eine OpenMV Cam mit NPU wie die AE3 oder N6 benötigt, um in Echtzeit zu laufen.
import csi
import time
import ml
from ml.preprocessing import Normalization
from ml.postprocessing.mediapipe import BlazePalm
from ml.postprocessing.mediapipe import HandLandmarks
# Sensor initialisieren.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
# BlazePalm benötigt für die besten Ergebnisse ein quadratisches Bild.
# HandLandmarks funktioniert mit nicht-quadratischen Bildern aus BlazePalm-Zuschnitten.
csi0.window((400, 400))
# Eingebautes Handflächenerkennungsmodell laden
palm_detection = ml.Model("/rom/palm_detection_full_192.tflite", postprocess=BlazePalm(threshold=0.4))
print(palm_detection)
# Eingebautes Handlandmarken-Modell laden
hand_landmarks = ml.Model("/rom/hand_landmarks_full_224.tflite", postprocess=HandLandmarks(threshold=0.4))
print(hand_landmarks)
# Linienverbindungen zwischen Handgelenken zum Zeichnen des Handskeletts.
hand_lines = ((0, 1), (1, 2), (2, 3), (3, 4), (0, 5), (5, 6), (6, 7), (7, 8),
(5, 9), (9, 10), (10, 11), (11, 12), (9, 13), (13, 14), (14, 15), (15, 16),
(13, 17), (17, 18), (18, 19), (19, 20), (0, 17))
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# palms ist eine Liste von ((x, y, w, h), score, keypoints)-Tupeln
for r, score, keypoints in palm_detection.predict([img]):
# rect ist (x, y, w, h) - für das Handlandmarken-Modell um das 3-Fache vergrößern
wider_rect = (r[0] - r[2], r[1] - r[3], r[2] * 3, r[3] * 3)
# Nur auf der ROI der erkannten Handfläche arbeiten
n = Normalization(roi=wider_rect)
# hands ist eine Liste von ((x, y, w, h), score, keypoints)-Tupeln
# Index 0 (falls vorhanden) ist die linke Hand
# Index 1 (falls vorhanden) ist die rechte Hand
hands = hand_landmarks.predict([n(img)])
# Begrenzungsrahmen um die erkannten Hände und Keypoints zeichnen.
for i, detections in enumerate(hands):
for r, score, keypoints in detections:
ml.utils.draw_predictions(img, [r], ("right",) if i else ("left",), ((0, 0, 255),), format=None)
# keypoints: ndarray (21, 3) der Handgelenke (x, y, z)
# Die Indizes folgen der MediaPipe-Konvention:
# 0: Handgelenk
# Daumen: 1 CMC, 2 MCP, 3 IP, 4 Spitze
# Zeigefinger: 5 MCP, 6 PIP, 7 DIP, 8 Spitze
# Mittelfinger: 9 MCP, 10 PIP, 11 DIP, 12 Spitze
# Ringfinger: 13 MCP, 14 PIP, 15 DIP, 16 Spitze
# Kleiner Finger: 17 MCP, 18 PIP, 19 DIP, 20 Spitze
# (cmc=Basis, mcp=Knöchel, pip=Mitte, dip=distal, ip=Daumengelenk, tip=Fingerspitze)
ml.utils.draw_skeleton(img, keypoints, hand_lines, kp_color=(255, 0, 0), line_color=(0, 255, 0))
print(clock.fps(), "fps")