Skip to content

Gestenerkennung

Mittels Hand-Tracking lassen sich Gesten erkennen. Wir wollen ein trainiertes Gesten-Modell verwenden und damit über die Webcam mit Hand-Bewegungen ein «Spiel» steuern.

Aufgabe: Auftrag

Arbeit dich in einer Zweier- oder Dreier-Gruppe durch diese Seite durch und versuche den letzten Auftrag als Projekt zu realisieren.

Übersicht

  • Bild von Webcam einlesen
  • Geste im Bild erkennen
  • Turtle steuern

Webcam

Um Bilder über die Webcam einzulesen können wir das Python-Package OpenCV verwenden. Wir können das in Thonny unter «Verwalte Pakete» installieren indem wir nach opencv-contrib-python suchen.

OpenCV bietet auch Möglichkeiten Bilder zu bearbeiten und anzuzeigen. Das untenstehende Programm liest Bilder von der Webcam, spiegelt diese vertikal (wie ein Spiegel) und zeigt sie in einem Fenster solange an, bis der Anwender mit der Taste q das Programm beendet.

py
import cv2

# gewünschte Webcam-Auflösung setzen
width, height = 1280, 720

# erster Video-Capture-Device wählen (ev. mehrere Webcams)
cam = cv2.VideoCapture(0)
cam.set(3, width)  # Höhe setzen
cam.set(4, height)  # Breite setzen

# Kamera-Loop
while cam.isOpened():
    # Einzelbild holen
    success, frame = cam.read()
    if not success:
        print("Webcam-Bild nicht verfügbar!")
        continue
    
    # Bild spiegeln
    frame = cv2.flip(frame, 1)

    # Bild anzeigen
    cv2.imshow("Webcam-Bild", frame)
    
    # Tastendruck «q» beendet Schleife
    if cv2.waitKey(20) == 113:
        break
    
# Webcam freigeben und Fenster schliessen
cam.release()
cv2.destroyAllWindows()

# Nochmals auf Tasteneingabe warten (Fix damit Fenster zugeht)
cv2.waitKey(20)

Aufgabe: Webcam

  • installiere OpenCV
  • kopiere, starte und teste das Beispiel
  • kannst du die Spiegelung deaktivieren?
  • kannst du horizontal statt vertikal spiegeln?

Gestenerkennung

MediaPipe von Google ist ein ML-Framework zur Bilderkennung. Eine Möglichkeit ist Gestenerkennung der Hand.

Mit dem trainierten Standard-Modell gesture_recognizer.task werden die folgenden Gesten erkannt:

👍 👎 ✌️ ☝️ ✊ 🖐️ 🤟

py
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision

# GestureRecognizer-Objekt erstellen basieren auf heruntergeladenem Modell
base_options = python.BaseOptions(model_asset_path='gesture_recognizer.task')
options = vision.GestureRecognizerOptions(base_options=base_options)
recognizer = vision.GestureRecognizer.create_from_options(options)

# Liste von lokalen Bild-Dateien
files = ['thumbs_down.jpg', 'victory.jpg', 'thumbs_up.jpg', 'pointing_up.jpg']

# Schleife über alle Dateien
for file in files:
    # Bild aus Datei lesen
    image = mp.Image.create_from_file(file)

    # Bild durch Recognizer schicken
    recognition_result = recognizer.recognize(image)

    # Top-Geste der Erkennung auslesen
    top_gesture = recognition_result.gestures[0][0]
    
    # Ergebnis ausgeben
    print(file, top_gesture)
thumbs_down.jpg
victory.jpg
thumbs_up.jpg
pointing_up.jpg

Die verlinkte Zip-Datei beinhalten die 4 Beispiel-Bilder und das vortrainierte Model:

Aufgabe: Gesten

  • installiere das Python-Package mediaPipe
  • speichere die 4 Bilder und das Model gesture_recognizer.task (aus Zip-Datei)
  • starte und teste das obenstehende Programm
  • schaffst du es nur den Namen der Geste auszugeben?
  • schaffst du es die Gesten als Emoji auszugeben?

Aufgabe: Gesten mit Webcam

Kombiniere nun die Gestenerkennung mit der Webcam: Statt Bilder aus Dateien, analysierst du nun die «Frames» die du von deiner Webcam erhältst.

Tipp:
Du musst den Frame der Webcam in ein mediaPipe-Bild umwandeln bevor du es dem Recognizer übergeben kannst:

python
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)

Turtle

Um eine Turtle steuerbar zu machen, brauchen wir eine Schleife und müssen auf Veränderungen reagieren. Sind das nun erkannte Handgesten oder – wie im Beispiel – gedrückte Tasten auf der Tastatur. Die Tastatureingaben werden allerdings nicht im Loop abgefragt, sondern als Events registriert. Diese Events bewirken über die Variable koopa.rotation eine Richtungsänderung der Turtle:

py
from turtle import Turtle

# Turtle erzeugen und Screen-Objekt holen
koopa = Turtle()
screen = koopa.getscreen()

# Drehgeschwindigkeit initialisieren
koopa.rotation = 0

# Drehgeschwindigkeit links
def left():
    koopa.rotation = -3

# Drehgeschwindigkeit rechts
def right():    
    koopa.rotation = 3

# Geradeaus
def straight():
    koopa.rotation = 0

# Events registrieren 
screen.onkey(left, "Left")
screen.onkey(right, "Right")
screen.onkey(straight, "Up")

# auf Events reagieren
screen.listen()

# Loop starten
while True:
    koopa.forward(1)     # immer vorwärts
    koopa.right(koopa.rotation)  # je nach Drehgeschwindigkeit drehen
    
koopa.done()

Aufgabe: Turtle

  • test das Turtle-Beispiel
  • kannst du den Kurvenradius variieren?
  • kannst du eine Steuerung der Turtlegeschwindigkeit einbauen?

Auftrag

Aufgabe: Turtle-Gesten-Steuerung

Versuche mit der Hand-Gestenerkennung eine Turtle-Steuerung zu implementieren.

Basis
eine Turtle lässt sich nach links und rechts steuern (2 Gesten)
Erweitert
weitere Gesten für weitere Steuerbefehle
zwei Turtles gesteuert von zwei Spieler (resp. zwei Händen)
daraus ein Spiel mit einem Ziel machen

Zusatzaufgabe

Wende deine Steuerung auf ein anderes Game – etwas was du ev. schon mal programmiert hast – an:

Gymnasium Kirchenfeld, fts & lem