hand_landmarks_single_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 eine einzelne Hand.
#
# 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))

# Tracking-Variablen.
n = None

clock = time.clock()
while True:
    clock.tick()
    img = csi0.snapshot()

    if n is None:
        # 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)

    else:
        # 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)])

        # Keine Hände erkannt, den Tracker zurücksetzen.
        if not hands:
            n = None
            continue

        # 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))

                # new_wider_rect zum Tracking auf der Hand zentrieren
                new_wider_rect = (r[0] + (r[2] // 2) - (wider_rect[2] // 2),
                                  r[1] + (r[3] // 2) - (wider_rect[3] // 2),
                                  wider_rect[2],
                                  wider_rect[3])
                # Nur auf der ROI der erkannten Hand arbeiten
                n = Normalization(roi=new_wider_rect)

    print(clock.fps(), "fps")

results matching ""

    No results matching ""