Bemerkung

Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie mit anderen Enthusiasten tiefer in Raspberry Pi, Arduino und ESP32 ein.

Warum beitreten?

  • Expertenunterstützung: Lösen Sie Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.

  • Lernen & Teilen: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern.

  • Exklusive Vorschauen: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und Sneak Peeks.

  • Sonderrabatte: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.

  • Festliche Aktionen und Gewinnspiele: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.

👉 Bereit, mit uns zu entdecken und zu gestalten? Klicken Sie auf [here] und treten Sie noch heute bei!

8. Kniebeugen-Zähler

1. Überblick

Im vorherigen Kapitel haben wir die grundlegende menschliche Posenschätzung implementiert. Dieses Kapitel baut darauf auf und zeigt die Umsetzung eines einfachen Kniebeugen-Zählers mit MediaPipe Pose.

Dies ist ein praxisnahes Beispiel für die Kombination aus:

  • Pose-Erkennung

  • Bewegungserkennung

  • Echtzeit-Zählung

Es kann in intelligenten Fitnesssystemen, Heimtrainings-Assistenten oder Anwendungen zur Bewegungsanalyse eingesetzt werden.

Squat Count Example

2. Funktionsweise

Der Kniebeugen-Zähler wird mit der folgenden Logik implementiert:

  1. MediaPipe Pose wird verwendet, um 33 Körper-Schlüsselpunkte zu erkennen.

  2. Wichtige Gelenke werden ausgewählt (Schulter, Hüfte, Knöchel).

  3. Die normalisierten y-Koordinaten werden verwendet, um die Hüfthöhe abzuschätzen.

  4. Obere und untere Schwellenwerte werden definiert (z. B. 0.55 und 0.45).

  5. Eine einfache Zustandsmaschine erkennt den Übergang: „stehen → Kniebeuge → stehen“.

  6. Der Zähler wird erhöht, wenn ein vollständiger Kniebeugen-Zyklus abgeschlossen ist.

  7. Die Anzahl der Kniebeugen und der aktuelle Hüftwert werden auf dem Bildschirm angezeigt.

Bemerkung

  • In diesem Beispiel wird keine Gelenkwinkelberechnung verwendet.

  • Es basiert auf normalisierten Koordinaten, um den Rechenaufwand zu verringern.

  • Die Methode ist leichtgewichtig und für den Raspberry Pi geeignet.

3. Code ausführen

Wichtig

Stellen Sie vor dem Start sicher, dass:

  • das Pan-Tilt-Modul montiert ist

  • Sie Zugriff auf den Raspberry Pi Desktop haben

  • das Codepaket installiert ist

  • das Fusion HAT+ installiert und konfiguriert ist

  • OpenCV installiert ist

Detaillierte Anweisungen finden Sie unter 0. OpenCV einrichten.

  1. Öffnen Sie das Terminal und geben Sie den folgenden Befehl ein:

    sudo python3 ~/ai-lab-kit/mediapipe/mp_pose_squat.py
    
  2. Nach dem Start des Programms öffnet sich ein Fenster mit dem Titel „Show Video“ und zeigt den Live-Kamerastream an.

    Wenn eine Person vor der Kamera steht:

    • MediaPipe Pose erkennt in Echtzeit 33 Körper-Landmarks.

    • Ein vollständiges Körperskelett wird auf dem Bildschirm dargestellt.

    • Das System berechnet fortlaufend die relative Hüftposition (HipRel).

    Während Sie Kniebeugen ausführen:

    • Wenn Sie nach unten gehen und Ihre Hüfte den unteren Schwellenwert (DOWN_TH) unterschreitet, markiert das System, dass Sie sich in der „unteren“ Position befinden.

    • Wenn Sie sich wieder aufrichten und die Hüfte den oberen Schwellenwert (UP_TH) überschreitet, erhöht sich der Kniebeugen-Zähler um 1.

    Auf dem Bildschirm werden folgende Informationen angezeigt:

    • Squats: N — die Gesamtzahl der abgeschlossenen Kniebeugen.

    • HipRel: value — die aktuell normalisierte Hüftposition, die für die Erkennung verwendet wird.

    Der Zähler wird nur nach einem vollständigen Bewegungszyklus erhöht (stehen → Kniebeuge → stehen), wodurch doppelte Zählungen verhindert werden.

    Drücken Sie q, um das Programm zu beenden. Die Kamera stoppt und das OpenCV-Fenster wird automatisch geschlossen.

4. Vollständiger Code

Hier ist die vollständige Implementierung des Kniebeugen-Zählers:

from picamera2 import Picamera2, Preview
import cv2
import mediapipe.python.solutions.pose as mp_pose
import mediapipe.python.solutions.drawing_utils as drawing
import mediapipe.python.solutions.drawing_styles as drawing_styles

# Initialize the Pose model
pose = mp_pose.Pose(
   static_image_mode=False,
   model_complexity=1,
   enable_segmentation=True,
)

# ---- Count and threshold ----
squat_count = 0
in_bottom = False
DOWN_TH = 0.55   # Hip relative position > 0.55 is considered "full squat"
UP_TH   = 0.45   # Hip relative position < 0.45 is considered "stand up"

# Open the camera
picam2 = Picamera2()
config = picam2.create_preview_configuration(
   main={"size": (640, 480), "format": "XRGB8888"} ,
)
picam2.configure(config)
picam2.start()

print("Streaming... press 'q' to quit")

while True:
   frame_bgra = picam2.capture_array()               # XRGB8888 to BGRA
   frame_bgr  = cv2.cvtColor(frame_bgra, cv2.COLOR_BGRA2BGR)

   # Convert the frame from BGR to RGB (required by MediaPipe)
   frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)

   # Process the frame for pose detection and tracking
   results = pose.process(frame_rgb)

   # Convert the frame back from RGB to BGR (required by OpenCV)
   frame = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR)

   # If pose is detected, draw landmarks and connections on the frame
   if results.pose_landmarks:
      drawing.draw_landmarks(
            frame,
            results.pose_landmarks,
            mp_pose.POSE_CONNECTIONS,
            landmark_drawing_spec=drawing_styles.get_default_pose_landmarks_style(),
      )

      # Count squat without using hip angle
      lms = results.pose_landmarks.landmark
      # left 11-23-27 (shoulder, hip, ankle)
      # right 12-24-28 (shoulder, hip, ankle)
      idx_sets = [(11,23,27), (12,24,28)]
      hip_rel_list = []

      for sh, hp, an in idx_sets:
            try:
               y_sh, y_hp, y_an = lms[sh].y, lms[hp].y, lms[an].y
               base = abs(y_an - y_sh)  # Distance between shoulder and ankle
               if base > 1e-6:
                  hip_rel = (y_hp - y_sh) / base  # Position of hip relative to shoulder, 0.5 means hip is in the middle, 0 means hip is at the top, 1 means hip is at the bottom
                  hip_rel_list.append(hip_rel)
            except IndexError:
               pass

      if hip_rel_list:
            hip_rel = min(hip_rel_list)  # Choose the smaller one, which is more stable
            # State machine:
            # from low -> mark "in_bottom";
            # from back to high -> count +1
            if not in_bottom and hip_rel >= DOWN_TH:
               in_bottom = True
            elif in_bottom and hip_rel <= UP_TH:
               squat_count += 1
               in_bottom = False

            # Display
            cv2.putText(frame, f"Squats: {squat_count}", (20, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 1.3, (0, 0, 255), 3, cv2.LINE_AA)
            cv2.putText(frame, f"HipRel: {hip_rel:.2f}", (20, 90),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2, cv2.LINE_AA)

   # Display the frame with annotations
   cv2.imshow("Show Video", frame)

   # Exit the loop if 'q' key is pressed
   if cv2.waitKey(1) & 0xff == ord('q'):
      break

# Release the camera
picam2.stop_preview()
picam2.stop()
cv2.destroyAllWindows()

Nach dem Ausführen des Skripts wird das System:

  • das menschliche Skelett erkennen;

  • die relative Hüftposition berechnen;

  • den Zähler um +1 erhöhen, wenn ein vollständiger Zyklus von „in die Hocke gehen“ zu „aufstehen“ abgeschlossen ist;

  • Squats: N sowie den aktuellen HipRel-Wert in Echtzeit auf dem Bildschirm anzeigen.

5. Koordinaten- und Zustandsdesign

Wir verwenden die folgenden 6 Schlüsselpunkte (je 3 auf jeder Seite):

Schlüsselpunkt

Index

Beschreibung

Schulter

11 (Links) / 12 (Rechts)

Oberer Referenzpunkt

Hüfte

23 (Links) / 24 (Rechts)

Kernpunkt zur Berechnung der Kniebeugenposition

Knöchel

27 (Links) / 28 (Rechts)

Unterer Referenzpunkt

MediaPipe Pose Keypoints

Berechnungsformel für den Hip Relative-Wert:

\[hip\_rel = \frac{hip_y - shoulder_y}{ankle_y - shoulder_y}\]
  • Ein größerer hip_rel-Wert bedeutet, dass sich die Hüfte näher am Boden befindet (d. h. in der Hocke).

  • Ein kleinerer hip_rel-Wert bedeutet, dass die Person aufrecht steht.

Wir definieren zwei Schwellenwerte:

  • DOWN_TH = 0.55: Wird als Erreichen der unteren Position der Kniebeuge betrachtet

  • UP_TH = 0.45: Wird als Rückkehr in die aufrechte Position betrachtet

Eine einfache Zustandsmaschine wird für eine zuverlässige Zählung verwendet:

if hip_rel >= DOWN_TH:
    in_bottom = True
if in_bottom and hip_rel <= UP_TH:
    squat_count += 1
    in_bottom = False

6. Parameteranpassung und Optimierung

Parameter

Beschreibung

Anpassungsempfehlung

DOWN_TH

Schwellenwert für die Kniebeugenbewegung

Ein höherer Wert erfordert eine tiefere Kniebeuge, um gezählt zu werden

UP_TH

Schwellenwert für das Aufstehen

Ein niedrigerer Wert erfordert eine aufrechtere Körperhaltung

model_complexity

Komplexität des Pose-Modells

Verwenden Sie 1 für höhere Geschwindigkeit

Resolution

Beeinflusst Bildrate und Genauigkeit

Empfohlen: 640×480

Tipp

Für Personen unterschiedlicher Körpergröße können adaptive Schwellenwerte oder eine persönliche Kalibrierung verwendet werden, um eine genauere Zählung zu erreichen.

5. Fehlerbehebung

  • Ungenaue Zählung

    Wenn die Anzahl der Kniebeugen nicht korrekt ist, passen die Schwellenwerte möglicherweise nicht zu Ihrer Körperhaltung oder zum Kamerawinkel.

    Geben Sie hip_rel in Echtzeit aus und passen Sie DOWN_TH und UP_TH entsprechend an. Achten Sie außerdem darauf, dass Ihre Kniebeugenbewegung klar und konsistent ausgeführt wird.

  • Person wird nicht erkannt

    Wenn der Körper nicht erkannt wird, verbessern Sie die Lichtverhältnisse und vermeiden Sie komplexe Hintergründe.

    Stellen Sie sicher, dass Sie vollständig im Bild stehen und direkt zur Kamera ausgerichtet sind.

  • Hohe Latenz

    Wenn die Videoreaktion langsam ist, reduzieren Sie model_complexity auf 1 und verringern Sie die Kameraauflösung (z. B. 640×480 oder 320×240).

    Schließen Sie unnötige Hintergrundprogramme, um die Leistung zu verbessern.

6. Zusammenfassung

  • In diesem Abschnitt wurde ein Echtzeit-Kniebeugen-Zähler auf Basis von Pose-Schlüsselpunkten und einer Zustandsmaschine implementiert;

  • Es sind keine komplexen Winkelberechnungen erforderlich, wodurch eine hohe Ausführungseffizienz erreicht wird;

  • Geeignet für Anwendungen auf Raspberry Pi oder anderen Edge-Geräten;

  • Mögliche zukünftige Erweiterungen:

    • Liegestütz-/Sit-up-Erkennung

    • Datenerfassung und Visualisierung

    • Automatische Rhythmusführung und Trainingsfeedback