Automatisiertes vision-basiertes Objekttracking mit Raspberry Pi und OpenCV
Ein Pan/Tilt-Servosystem, das farbige Objekte mithilfe von Computer Vision automatisch verfolgt.
Hintergrund
Einführung
Im vorherigen Tutorial lernten wir, ein Pan/Tilt-Servo zur Positionierung einer Raspberry Pi Kamera zu steuern. Heute erweitern wir das Setup, sodass die Kamera ein farbiges Objekt autonom verfolgen kann.
Dies ist meine erste praktische Erfahrung mit OpenCV, und ich bin bereits begeistert von dieser Open-Source-Computer-Vision-Bibliothek.
OpenCV ist für akademische und kommerzielle Nutzung kostenlos, bietet C++, C, Python und Java Interfaces und läuft auf Windows, Linux, macOS, iOS und Android. In dieser Serie fokussieren wir uns auf Raspberry Pi (Raspbian) und Python, da OpenCV für Rechenleistung und Echtzeitanwendungen optimiert ist – genau das, was Physical-Computing-Projekte brauchen.
Schritt 1: Stückliste (BOM)
Hauptkomponenten:
- Raspberry Pi V3 – 32,00 $
- 5 MP 1080p OV5647 Mini Kamera Videomodul – 13,00 $
- TowerPro SG90 9G 180-Grad Mikro-Servo (2×) – 4,00 $
- Mini Pan/Tilt Kamera Plattform Anti-Vibrationshalterung m. 2 Servos (*) – 8,00 $
- Rote LED
- Widerstand 220 Ω
- Widerstand 1 kΩ (2×) – Optional
- Verschiedenes: Metallteile, Bänder etc. (falls eigener Pan/Tilt-Mechanismus gebaut wird)
(*) Komplettes Pan/Tilt-Set mit Servos kaufen oder selbst bauen.
Schritt 2: OpenCV 3 installieren
Auf Raspberry Pi V3 mit aktuellem Raspbian Stretch ist der zuverlässigste Weg, Adrian Rosebrocks Tutorial zu folgen (Raspbian Stretch: Install OpenCV 3 + Python on your Raspberry Pi). Es führt durch den Build von OpenCV aus Source und richtet eine dedizierte Python-Virtual-Environment ein.
Nach Abschluss Tutorial Virtual Environment aktivieren und Installation prüfen:
source ~/.profile
workon cv
python
import cv2
print(cv2.__version__)
Sie sollten Version 3.3.0 oder neuer sehen. Die Ausgabe bestätigt, dass OpenCV im cv Virtual Environment bereitsteht.
Schritt 3: Kamera testen
Mit installiertem OpenCV prüfen, ob PiCamera korrekt streamt. Folgendes Skript ausführen (oder simpleCamTest.py herunterladen):
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
frame = cv2.flip(frame, -1) # Vertikal spiegeln falls nötig
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', frame)
cv2.imshow('gray', gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
q oder Strg+C zum Beenden. Erfolgreicher Lauf zeigt Farb- und Graustufen-Feed.
Schritt 4: Farberkennung mit OpenCV in Python
OpenCV arbeitet im HSV-Farbraum (Farbton, Sättigung, Wert), der besser zur menschlichen Farbwahrnehmung passt. Um eine bestimmte Farbe zu detektieren, bestimmen Sie zuerst deren BGR-Werte, konvertieren in HSV und legen untere/obere Schwellwerte fest.
Beispiel: Gelbes Objekt tracken. Per Farbwähler (z. B. PowerPoint) BGR-Werte (71, 234, 213) ermittelt. In HSV konvertieren mit Skript (oder bgr_hsv_converter.py herunterladen):
import sys, numpy as np, cv2
blue, green, red = int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3])
color = np.uint8([[[blue, green, red]]])
hsv = cv2.cvtColor(color, cv2.COLOR_BGR2HSV)
hue = hsv[0][0][0]
print('Lower bound:', [hue-10, 100, 100])
print('Upper bound:', [hue+10, 255, 255])
python bgr_hsv_converter.py 71 234 213 liefert:
Lower bound: [24, 100, 100] Upper bound: [44, 255, 255]
Diese Bounds nutzen, um Farbe in Bild zu maskieren:
import cv2, numpy as np
img = cv2.imread('yellow_object.JPG', 1)
img = cv2.resize(img, (0,0), fx=0.2, fy=0.2)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([24, 100, 100], dtype=np.uint8)
upper = np.array([44, 255, 255], dtype=np.uint8)
mask = cv2.inRange(hsv, lower, upper)
cv2.imshow('mask', mask)
cv2.imshow('image', img)
while True:
k = cv2.waitKey(0)
if k == 27:
break
cv2.destroyAllWindows()
Skript als colorDetection.py speichern und python colorDetection.py ausführen (Bild im selben Verzeichnis).
Schritt 5: Echtzeit-Objekttracking
Aufbauend auf der Maske können wir den Objekt-Schwerpunkt frame-weise tracken. Der Code unten lehnt sich an Adrian Rosebrocks Ball Tracking Tutorial an und nutzt die zuvor definierten HSV-Bounds.
Zuerst imutils Bibliothek installieren:
pip install imutils
Dann ball_tracking.py ausführen:
python ball_tracking.py
Das Skript spiegelt den Frame vertikal (falls nötig) und wendet die Maske an. Bei Erkennung werden Kreis und Schwerpunkt gezeichnet.
Schritt 6: GPIOs testen
Jetzt rote LED am Pi anschließen und GPIO-Steuerung prüfen.
Verdrahtung: LED-Kathode an GPIO 21, Anode über 220 Ω Widerstand an Masse.
Falls RPi.GPIO nicht in cv Environment installiert:
pip install RPi.GPIO
Testskript (LED_simple_test.py):
import sys, time, RPi.GPIO as GPIO
led = int(sys.argv[1])
freq = int(sys.argv[2])
GPIO.setmode(GPIO.BCM)
GPIO.setup(led, GPIO.OUT)
GPIO.setwarnings(False)
print(f'Blinke LED an GPIO {led} alle {freq}s, 5-mal.')
for _ in range(5):
GPIO.output(led, GPIO.LOW)
time.sleep(freq)
GPIO.output(led, GPIO.HIGH)
time.sleep(freq)
GPIO.cleanup()
Mit python LED_simple_test.py 21 1 LED fünfmal pro Sekunde blinken lassen.
Schritt 7: Farberkennung & GPIO-Interaktion
Tracking-Logik mit GPIO-Steuerung kombinieren, sodass LED leuchtet, sobald Ziel-Farbe erkannt wird. Kernezusätze:
import RPi.GPIO as GPIO
led = 21
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(led, GPIO.OUT)
GPIO.output(led, GPIO.LOW)
ledOn = False
In der Erkennungsschleife nach Validierung des Radius hinzufügen:
if not ledOn:
GPIO.output(led, GPIO.HIGH)
ledOn = True
Vollständiges Skript: object_detection_LED.py. Mit python object_detection_LED.py ausführen. LED geht nur an, wenn Objektfarbe innerhalb HSV-Bounds liegt.
Schritt 8: Pan/Tilt-Mechanismus
Mit OpenCV und GPIO funktionsfähig, Servos an externe 5 V Versorgung anschließen. Datenpins wie folgt verdrahten:
- GPIO 17 → Tilt Servo
- GPIO 27 → Pan Servo
Masse zwischen Pi, Servos und Netzteil teilen. Optional 1 kΩ Widerstand in Serie zwischen Pi GPIO und Servo-Datenpin zum Schutz vor Stromspitzen.
Servo-Steuerung testen mit angleServoCtrl.py:
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
def setServoAngle(servo, angle):
pwm = GPIO.PWM(servo, 50)
pwm.start(8)
duty = angle / 18. + 3.
pwm.ChangeDutyCycle(duty)
sleep(0.3)
pwm.stop()
if __name__ == '__main__':
import sys
servo = int(sys.argv[1])
GPIO.setup(servo, GPIO.OUT)
setServoAngle(servo, int(sys.argv[2]))
GPIO.cleanup()
Beispiel: python angleServoCtrl.py 17 45 bewegt Tilt-Servo auf 45°.
Schritt 9: Objekt-Position in Echtzeit bestimmen
Um Kamera auf Ziel zu zentrieren, brauchen wir Objekt-Schwerpunkt-Koordinaten. objectDetect_LED.py modifizieren, um x und y auszugeben:
def mapObjectPosition(x, y):
print(f'[INFO] Objektzentrum bei X={x}, Y={y}')
Koordinaten reichen 0–500 (links-rechts) für x und 0–350 (oben-unten) für y. Objekt bewegen und Live-Output beobachten.
Schritt 10: Objekttracking-System
„Zentrierten“ Bereich definieren (z. B. 220 < x < 280 und 160 < y < 210). Fällt Objekt außerhalb, Pan- und Tilt-Servos entsprechend anpassen:
def mapServoPosition(x, y):
global panAngle, tiltAngle
if x < 220:
panAngle = min(panAngle + 10, 140)
positionServo(panServo, panAngle)
if x > 280:
panAngle = max(panAngle - 10, 40)
positionServo(panServo, panAngle)
if y < 160:
tiltAngle = min(tiltAngle + 10, 140)
positionServo(tiltServo, tiltAngle)
if y > 210:
tiltAngle = max(tiltAngle - 10, 40)
positionServo(tiltServo, tiltAngle)
Helper positionServo(servo, angle) ruft einfach angleServoCtrl.py auf:
import os
def positionServo(servo, angle):
os.system(f'python angleServoCtrl.py {servo} {angle}')
print(f'[INFO] Positioniere Servo GPIO {servo} auf {angle}°')
Alle Skripte im selben Verzeichnis; komplette Implementation von objectDetectTrack.py herunterladen.
Schritt 11: Fazit
Dieses Projekt demonstriert, wie OpenCV, Raspberry Pi GPIO und Pan/Tilt-Servohalterung zu einem autonomen Farb-Objekttracking-System kombiniert werden. Experimentieren Sie frei mit verschiedenen Farben, Formen und Servogeschwindigkeiten.
Vollständiger Code und weitere Ressourcen auf GitHub und dem MJRoBot.org Blog.
Danke fürs Lesen – bis zum nächsten Tutorial!
Herstellungsprozess
- Python Objektorientierte Programmierung meistern: Klassen, Vererbung, Kapselung & Polymorphie
- Fortgeschrittenes Tischtennisball-Tracking mit Raspberry Pi und OpenCV
- Speathe: Atemgesteuerte Kommunikation für gelähmte Nutzer
- Echtzeit-Gesichtserkennung auf Raspberry Pi – Komplette Anleitung
- Python Objektorientierte Programmierung: Umfassender Leitfaden
- Messgenauigkeit dynamischer Objekterfassung in Motion-Capture-Systemen
- Neuer Filter verbessert Roboter-Vision für präzise 6-D-Pose-Estimation
- Automatische Pressen verstehen: Funktion, Vorteile und Anwendungen
- Automatische Exzenterpressen: Eigenschaften, Vorteile und Anwendungen
- Automatische Rohrbiegemaschinen: Funktionen, Vorteile und Anwendungen verstehen