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.
2. Funktionsweise
Der Kniebeugen-Zähler wird mit der folgenden Logik implementiert:
MediaPipe Pose wird verwendet, um 33 Körper-Schlüsselpunkte zu erkennen.
Wichtige Gelenke werden ausgewählt (Schulter, Hüfte, Knöchel).
Die normalisierten y-Koordinaten werden verwendet, um die Hüfthöhe abzuschätzen.
Obere und untere Schwellenwerte werden definiert (z. B. 0.55 und 0.45).
Eine einfache Zustandsmaschine erkennt den Übergang: „stehen → Kniebeuge → stehen“.
Der Zähler wird erhöht, wenn ein vollständiger Kniebeugen-Zyklus abgeschlossen ist.
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.
Öffnen Sie das Terminal und geben Sie den folgenden Befehl ein:
sudo python3 ~/ai-lab-kit/mediapipe/mp_pose_squat.py
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 |
Berechnungsformel für den Hip Relative-Wert:
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_relin Echtzeit aus und passen SieDOWN_THundUP_THentsprechend 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_complexityauf 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