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!
4. Objekte mit Schwenk-Neige-Einheit verfolgen
In den vorherigen Tutorials haben wir gelernt, wie man YOLO für die Objekterkennung auf dem Raspberry Pi verwendet. Die Erkennung ist jedoch nur der erste Schritt – wenn die Kamera einem Ziel wirklich „folgen“ soll, müssen Sie die Erkennung mit mechanischer Steuerung kombinieren.
Dieses Tutorial führt Sie durch die Entwicklung eines YOLO-Objekterkennungs- und Verfolgungssystems, das Folgendes erreicht:
Echtzeiterkennung spezifischer Objekte mit YOLO
Automatische Berechnung der Positionsabweichung des Ziels im Bild
Servogesteuerte Schwenk-Neige-Einheit, um das Ziel in der Bildmitte zu halten
Unterstützung zum Speichern aktueller Bilder mit der LEERTASTE für die Datensatzerstellung
Hier verfolgen wir das Ziel aus unserem benutzerdefinierten Modell, das wir im vorherigen Tutorial trainiert haben – bei mir ist es ein Schneemann. Sie können auch andere Modelle (wie yolov8n) wählen, um andere Ziele (wie Personen, Autos usw.) zu verfolgen.
Abbildung: YOLO-Objekterkennungssystem in Aktion. Wenn sich das Ziel bewegt, folgt die Kamera-Schwenk-Neige-Einheit automatisch und hält das Ziel nahe dem gelben Fadenkreuz in der Bildmitte. Der grüne Begrenzungsrahmen markiert das erkannte Ziel.
Anwendungsszenarien:
Intelligente Überwachung: Automatische Verfolgung verdächtiger Ziele
Haustierbegleiter: Die Kamera folgt den Bewegungen Ihres Haustiers
Videokonferenzen: Automatische Zentrierung sprechender Personen
Datenerfassung: Automatische Aufnahme von Mehrwinkelbildern eines Ziels
Hardware-Aufbau
Für dieses Projekt müssen Sie die Schwenk-Neige-Einheit gemäß der Anleitung in Pan-Tilt montieren (für die Kamera) zusammenbauen.
Ausführen des Codes
Konfigurationsparameter anpassen
cd ~/ai-lab-kit/yolo nano yolo_tracking.py
Ändern Sie die Variable
TARGETam Anfang des Codes auf das Objekt, das Sie verfolgen möchten:TARGET = "person" # Eine Person verfolgen # oder TARGET = "snowman" # Einen Schneemann verfolgen
Die Modelldatei vorbereiten
Verwenden Sie ein vortrainiertes Modell:
model = YOLO("yolov8n.pt")Verwenden Sie ein benutzerdefiniertes Modell:
model = YOLO("snowman.pt")
Speichern und Ausführen des Codes
python3 yolo_tracking.pyBedienungsanleitung
Nach dem Start arbeitet die Kamera automatisch
Wenn ein Ziel erkannt wird, drehen sich die Servos automatisch, um das Ziel in der Bildmitte zu halten
Drücken Sie die
LEERTASTE, um das aktuelle Bild zu speichern (zum Sammeln von Trainingsdaten)Drücken Sie
ESC, um das Programm zu beenden
Code
#!/usr/bin/env python3
"""
YOLO-basierte Objektverfolgung für Raspberry Pi
Verfolgt ein bestimmtes Objekt (z.B. Person) mit YOLO und steuert Servos
Drücken Sie LEERTASTE, um Bilder für den Datensatz aufzunehmen, ESC zum Beenden
"""
from picamera2 import Picamera2
from ultralytics import YOLO
from fusion_hat.servo import Servo
import cv2
import time
import os
# -------------------- Konfiguration --------------------
TARGET = "your_object" # Zu verfolgendes Objekt (Klassenname)
W, H = 640, 480 # Kamerauflösung
CX, CY = W // 2, H // 2 # Bildmittelpunkt
CONFIDENCE = 0.3 # Konfidenzschwelle für Erkennung
DEADZONE = 50 # Pixel um die Mitte, bevor Bewegung erfolgt
SAVE_DIR = "captured_images" # Verzeichnis zum Speichern von Datensätzen
# Erstelle das Speicherverzeichnis
os.makedirs(SAVE_DIR, exist_ok=True)
print(f"=== YOLO-Verfolgungssystem ===")
print(f"Ziel: {TARGET}")
print(f"Konfidenzschwelle: {CONFIDENCE}")
print(f"Totzone: {DEADZONE} Pixel")
# -------------------- Servo-Initialisierung --------------------
print("Initialisiere Servos...")
pan = Servo(2) # Kanal 2 für Schwenken (horizontal)
tilt = Servo(3) # Kanal 3 für Neigen (vertikal)
pan.angle(0) # Mittelposition
tilt.angle(0) # Mittelposition
time.sleep(1)
# -------------------- Laden des YOLO-Modells --------------------
print("Lade YOLO-Modell...")
# Verwenden Sie YOLOv8n für beste Leistung auf dem Raspberry Pi
model = YOLO("your_model.pt")
print("Modell erfolgreich geladen")
# -------------------- Kamera-Initialisierung --------------------
print("Initialisiere Kamera...")
picam2 = Picamera2()
picam2.preview_configuration.main.size = (W, H)
picam2.preview_configuration.main.format = "RGB888"
picam2.configure("preview")
picam2.start()
time.sleep(2)
print("\n=== System bereit ===")
print("Bedienung:")
print(" LEERTASTE - Bild aufnehmen (für Datensatz)")
print(" ESC - Beenden")
print(" (Automatische Verfolgung bei Zielerkennung)")
print("==========================\n")
# -------------------- Verfolgungsvariablen --------------------
pan_pos = 0 # Aktueller Schwenkwinkel (-90 bis 90)
tilt_pos = 0 # Aktueller Neigungswinkel (-45 bis 45)
capture_count = 0
def simple_track(x, y):
"""
Einfache 4-Richtungs-Verfolgung mit Totzone
Gibt zurück: (pan_move, tilt_move) wobei:
pan_move: -1 (links), 0 (stopp), 1 (rechts)
tilt_move: -1 (runter), 0 (stopp), 1 (hoch)
"""
if x is None or y is None:
return 0, 0
pan_move = 0
tilt_move = 0
# Horizontale Bewegung (Schwenken)
if x < CX - DEADZONE:
pan_move = 1 # Nach rechts bewegen
elif x > CX + DEADZONE:
pan_move = -1 # Nach links bewegen
# Vertikale Bewegung (Neigen)
if y < CY - DEADZONE:
tilt_move = -1 # Nach unten bewegen
elif y > CY + DEADZONE:
tilt_move = 1 # Nach oben bewegen
return pan_move, tilt_move
def find_target_detection(results, target_name):
"""
Durchsucht die YOLO-Erkennungsergebnisse nach dem Zielobjekt
Gibt zurück: (x_center, y_center, confidence) oder (None, None, None)
"""
if len(results[0].boxes) == 0:
return None, None, None
for box in results[0].boxes:
class_id = int(box.cls[0])
class_name = model.names[class_id]
confidence = float(box.conf[0])
# Groß-/Kleinschreibung-unabhängige Teilübereinstimmung
if target_name.lower() in class_name.lower():
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
x_center = int((x1 + x2) / 2)
y_center = int((y1 + y2) / 2)
return x_center, y_center, confidence
return None, None, None
# -------------------- Hauptverfolgungsschleife --------------------
try:
while True:
# Einzelbild erfassen
frame = picam2.capture_array()
# YOLO-Erkennung ausführen
results = model.predict(frame, imgsz=320, conf=CONFIDENCE, verbose=False)
# Zielobjekt finden
obj_x, obj_y, obj_conf = find_target_detection(results, TARGET)
# Verfolgung verarbeiten, wenn Objekt gefunden
if obj_x is not None:
pan_move, tilt_move = simple_track(obj_x, obj_y)
pan_pos += pan_move
tilt_pos += tilt_move
# Servowinkel auf sichere Bereiche begrenzen
pan_pos = max(-90, min(90, pan_pos))
tilt_pos = max(-45, min(45, tilt_pos))
# Befehle an die Servos senden
pan.angle(pan_pos)
tilt.angle(tilt_pos)
# Erkennungsrahmen zeichnen
cv2.rectangle(frame, (obj_x - 30, obj_y - 30),
(obj_x + 30, obj_y + 30), (0, 255, 0), 2)
cv2.circle(frame, (obj_x, obj_y), 5, (0, 255, 0), -1)
status = f"{TARGET} erkannt: {obj_conf:.2f}"
color = (0, 255, 0)
else:
status = f"Kein {TARGET} erkannt"
color = (0, 0, 255)
# Fadenkreuz in der Mitte zeichnen
cv2.line(frame, (CX - 20, CY), (CX + 20, CY), (0, 255, 255), 2)
cv2.line(frame, (CX, CY - 20), (CX, CY + 20), (0, 255, 255), 2)
# Totzone-Rechteck zeichnen (visuelle Referenz)
cv2.rectangle(frame, (CX - DEADZONE, CY - DEADZONE),
(CX + DEADZONE, CY + DEADZONE), (255, 255, 0), 1)
# Statusinformationen anzeigen
cv2.putText(frame, status, (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
cv2.putText(frame, f"Schwenk: {pan_pos:.0f} Neigung: {tilt_pos:.0f}",
(10, 55), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1)
cv2.putText(frame, f"Aufgenommene Bilder: {capture_count}", (10, 80),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
cv2.putText(frame, "LEERTASTE=aufnehmen ESC=beenden", (10, 105),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
# Videofenster anzeigen
cv2.imshow(f"YOLO-Verfolgung - {TARGET}", frame)
# Tastendrücke verarbeiten
key = cv2.waitKey(1) & 0xFF
if key == 32: # LEERTASTE - Bild aufnehmen
filename = f"{SAVE_DIR}/img_{capture_count:04d}.jpg"
cv2.imwrite(filename, frame)
print(f"Aufgenommen: {filename}")
capture_count += 1
# Blitzeffekt
flash = frame.copy()
flash[:] = (255, 255, 255)
cv2.imshow(f"YOLO-Verfolgung - {TARGET}", flash)
cv2.waitKey(50)
elif key == 27: # ESC-Taste - Beenden
print(f"\nBeende. Insgesamt aufgenommen: {capture_count} Bilder")
break
finally:
# -------------------- Aufräumen --------------------
print("Räume auf...")
pan.angle(0) # Zurück zur Mitte
tilt.angle(0) # Zurück zur Mitte
time.sleep(0.5)
cv2.destroyAllWindows()
picam2.stop()
print("Verfolgung gestoppt. Servos zentriert.")
Code-Erklärung
Hier ist der vollständige YOLO-Objekterkennungscode. Wir analysieren seine Funktionsweise Abschnitt für Abschnitt.
1. Bibliotheken importieren und Konfigurationsparameter
#!/usr/bin/env python3
"""
YOLO-basierte Objektverfolgung für Raspberry Pi
Verfolgt ein bestimmtes Objekt (z.B. Person) mit YOLO und steuert Servos
Drücken Sie LEERTASTE, um Bilder für den Datensatz aufzunehmen, ESC zum Beenden
"""
from picamera2 import Picamera2
from ultralytics import YOLO
from fusion_hat.servo import Servo
import cv2
import time
import os
# -------------------- Konfiguration --------------------
TARGET = "your_object" # Zu verfolgendes Objekt (Klassenname)
W, H = 640, 480 # Kamerauflösung
CX, CY = W // 2, H // 2 # Bildmittelpunkt
CONFIDENCE = 0.3 # Konfidenzschwelle für Erkennung
DEADZONE = 50 # Pixel um die Mitte, bevor Bewegung erfolgt
SAVE_DIR = "captured_images" # Verzeichnis zum Speichern von Datensätzen
# Erstelle das Speicherverzeichnis
os.makedirs(SAVE_DIR, exist_ok=True)
Konfigurationsparameter:
Parameter |
Beschreibung |
Empfohlener Wert |
|---|---|---|
|
Name des zu verfolgenden Objekts |
„person“, „snowman“, „cup“ |
|
Kamerauflösung |
640x480 (ausgewogene Leistung) |
|
Totzonenbereich (Pixel) |
50-100, verhindert häufiges Zittern |
|
Konfidenzschwelle für Erkennung |
0.3-0.5 |
|
Bildspeicherverzeichnis |
captured_images |
2. Servos initialisieren
# -------------------- Servo-Initialisierung --------------------
print("Initialisiere Servos...")
pan = Servo(2) # Kanal 2 für Schwenken (horizontal)
tilt = Servo(3) # Kanal 3 für Neigen (vertikal)
pan.angle(0) # Mittelposition
tilt.angle(0) # Mittelposition
time.sleep(1)
Servo-Winkelbereiche:
Schwenkservo (horizontal): -90° bis 90°, 0° ist die Mitte
Neigungsservo (vertikal): -45° bis 45°, 0° ist die Mitte
3. YOLO-Modell laden
# -------------------- Laden des YOLO-Modells --------------------
print("Lade YOLO-Modell...")
# Verwenden Sie YOLOv8n für beste Leistung auf dem Raspberry Pi
model = YOLO("your_model.pt")
print("Modell erfolgreich geladen")
Modellauswahl-Empfehlungen:
Verwenden Sie Ihr eigenes trainiertes Modell:
"snowman.pt","my_pet.pt"Verwenden Sie ein vortrainiertes Modell:
"yolov8n.pt"(erkennt 80 gängige Objekte)
4. Objekterkennungs- und Verfolgungslogik
def simple_track(x, y):
"""
Einfache 4-Richtungs-Verfolgung mit Totzone
Gibt zurück: (pan_move, tilt_move) wobei:
pan_move: -1 (links), 0 (stopp), 1 (rechts)
tilt_move: -1 (runter), 0 (stopp), 1 (hoch)
"""
if x is None or y is None:
return 0, 0
pan_move = 0
tilt_move = 0
# Horizontale Bewegung (Schwenken)
if x < CX - DEADZONE:
pan_move = 1 # Nach rechts bewegen
elif x > CX + DEADZONE:
pan_move = -1 # Nach links bewegen
# Vertikale Bewegung (Neigen)
if y < CY - DEADZONE:
tilt_move = -1 # Nach unten bewegen
elif y > CY + DEADZONE:
tilt_move = 1 # Nach oben bewegen
return pan_move, tilt_move
def find_target_detection(results, target_name):
"""
Durchsucht die YOLO-Erkennungsergebnisse nach dem Zielobjekt
Gibt zurück: (x_center, y_center, confidence) oder (None, None, None)
"""
if len(results[0].boxes) == 0:
return None, None, None
for box in results[0].boxes:
class_id = int(box.cls[0])
class_name = model.names[class_id]
confidence = float(box.conf[0])
# Groß-/Kleinschreibung-unabhängige Teilübereinstimmung
if target_name.lower() in class_name.lower():
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
x_center = int((x1 + x2) / 2)
y_center = int((y1 + y2) / 2)
return x_center, y_center, confidence
return None, None, None
Erklärung der Verfolgungslogik:
Totzonen-Mechanismus: Wenn sich das Ziel innerhalb der Totzone nahe der Bildmitte befindet, bewegen sich die Servos nicht, um häufiges Zittern zu verhindern
Richtungsbestimmung: Wenn das Ziel links von der Mitte ist, nach rechts drehen; wenn rechts von der Mitte, nach links drehen
Zielidentifikation: Finden des zu verfolgenden Objekts durch Abgleich der Klassennamen
5. Hauptschleife
# -------------------- Hauptverfolgungsschleife --------------------
try:
while True:
# Einzelbild erfassen
frame = picam2.capture_array()
# YOLO-Erkennung ausführen
results = model.predict(frame, imgsz=320, conf=CONFIDENCE, verbose=False)
# Zielobjekt finden
obj_x, obj_y, obj_conf = find_target_detection(results, TARGET)
# Verfolgung verarbeiten, wenn Objekt gefunden
if obj_x is not None:
pan_move, tilt_move = simple_track(obj_x, obj_y)
pan_pos += pan_move
tilt_pos += tilt_move
# Servowinkel auf sichere Bereiche begrenzen
pan_pos = max(-90, min(90, pan_pos))
tilt_pos = max(-45, min(45, tilt_pos))
# Befehle an die Servos senden
pan.angle(pan_pos)
tilt.angle(tilt_pos)
# Erkennungsrahmen zeichnen
cv2.rectangle(frame, (obj_x - 30, obj_y - 30),
(obj_x + 30, obj_y + 30), (0, 255, 0), 2)
cv2.circle(frame, (obj_x, obj_y), 5, (0, 255, 0), -1)
status = f"{TARGET} erkannt: {obj_conf:.2f}"
color = (0, 255, 0)
else:
status = f"Kein {TARGET} erkannt"
color = (0, 0, 255)
# Fadenkreuz in der Mitte zeichnen
cv2.line(frame, (CX - 20, CY), (CX + 20, CY), (0, 255, 255), 2)
cv2.line(frame, (CX, CY - 20), (CX, CY + 20), (0, 255, 255), 2)
# Totzone-Rechteck zeichnen (visuelle Referenz)
cv2.rectangle(frame, (CX - DEADZONE, CY - DEADZONE),
(CX + DEADZONE, CY + DEADZONE), (255, 255, 0), 1)
# Statusinformationen anzeigen
cv2.putText(frame, status, (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
cv2.putText(frame, f"Schwenk: {pan_pos:.0f} Neigung: {tilt_pos:.0f}",
(10, 55), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1)
cv2.putText(frame, f"Aufgenommene Bilder: {capture_count}", (10, 80),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
cv2.putText(frame, "LEERTASTE=aufnehmen ESC=beenden", (10, 105),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
# Videofenster anzeigen
cv2.imshow(f"YOLO-Verfolgung - {TARGET}", frame)
# Tastendrücke verarbeiten
key = cv2.waitKey(1) & 0xFF
if key == 32: # LEERTASTE - Bild aufnehmen
filename = f"{SAVE_DIR}/img_{capture_count:04d}.jpg"
cv2.imwrite(filename, frame)
print(f"Aufgenommen: {filename}")
capture_count += 1
# Blitzeffekt
flash = frame.copy()
flash[:] = (255, 255, 255)
cv2.imshow(f"YOLO-Verfolgung - {TARGET}", flash)
cv2.waitKey(50)
elif key == 27: # ESC-Taste - Beenden
print(f"\nBeende. Insgesamt aufgenommen: {capture_count} Bilder")
break
finally:
# -------------------- Aufräumen --------------------
print("Räume auf...")
pan.angle(0) # Zurück zur Mitte
tilt.angle(0) # Zurück zur Mitte
time.sleep(0.5)
cv2.destroyAllWindows()
picam2.stop()
print("Verfolgung gestoppt. Servos zentriert.")
Leistungsoptimierung
Beim Ausführen des Verfolgungssystems auf dem Raspberry Pi können folgende Optimierungen helfen:
Erkennungshäufigkeit reduzieren: Alle 2-3 Bilder erkennen, Erkennungsergebnisse für die anderen Bilder wiederverwenden
frame_count = 0
while True:
frame = picam2.capture_array()
if frame_count % 3 == 0:
results = model.predict(frame, imgsz=320)
frame_count += 1
Erkennungsbereich eingrenzen: Nur in Bereichen erkennen, in denen das Ziel wahrscheinlich erscheint
Kleinere Modelle verwenden:
yolov8n.ptist die beste WahlTotzonenbereich anpassen: Eine Vergrößerung von
DEADZONEreduziert häufige Servobewegungen
Häufige Fragen
F: Was tun, wenn sich die Servos nicht bewegen?
Überprüfen Sie, ob die Servos richtig angeschlossen sind
Stellen Sie sicher, dass die fusion_hat-Bibliothek korrekt installiert ist
F: Was tun, wenn die Verfolgungsreaktion zu langsam ist?
Kamerauflösung verringern (z. B. 320x240)
Erkennungsauflösung
imgszreduzierenTotzonenbereich vergrößern, um Servobewegungen zu reduzieren
F: Was tun, wenn die Zielerkennung instabil ist?
Passen Sie die
CONFIDENCE-Schwelle an (niedrigere Werte erkennen mehr, erhöhen aber falsch-positive Ergebnisse)Sorgen Sie für ausreichende Beleuchtung
Verwenden Sie ein benutzerdefiniertes Modell für bessere Spezifität
F: Wie kann die Servoempfindlichkeit angepasst werden?
Ändern Sie den Schrittweitenwert in der simple_track-Funktion:
# Schrittweite für schnellere Servobewegung erhöhen
pan_move = 2 # Ursprünglich 1
tilt_move = 2
F: Kann ich mehrere Ziele verfolgen?
Ändern Sie die find_target_detection-Funktion so, dass sie das nächste oder das Ziel mit der höchsten Konfidenz zurückgibt, oder implementieren Sie eine Umschaltfunktionalität für mehrere Ziele.
Erweiterte Funktionen
1. PID-Regelung hinzufügen (weichere Verfolgung)
# Vereinfachtes PID-Reglerbeispiel
pan_error = CX - obj_x
pan_output = pan_error * 0.05 # Proportionalregelung
pan_pos += int(pan_output)
2. Automatische Aufzeichnung der Verfolgungsbahn
# Zielpositionsverlauf aufzeichnen
trajectory = []
trajectory.append((obj_x, obj_y))
3. Benachrichtigung bei Zielerkennung senden
if obj_x is not None:
# E-Mail oder Push-Benachrichtigung senden
pass
4. Gesichtserkennung integrieren
Kombinieren Sie mit Gesichtserkennungsbibliotheken, um nur bestimmte Personen zu verfolgen.
Zusammenfassung
Durch dieses Tutorial haben Sie gelernt:
Wie Sie YOLO-Objekterkennung mit Servosteuerung kombinieren
Wie Sie ein visionäres automatisches Verfolgungssystem implementieren
Wie Sie Totzonenmechanismen zur Vermeidung von Zittern einsetzen
Wie Sie während der Verfolgung Trainingsdaten sammeln
Dieses System kann in Szenarien wie intelligenter Überwachung, automatisierter Fotografie und robotischer Vision weit verbreitet eingesetzt werden. Da sich YOLO-Modelle weiterentwickeln, können Sie noch intelligentere Verfolgungssysteme aufbauen – wie z. B. automatische Zoomanpassung basierend auf der Zielgröße oder Vorhersage von Zielbewegungen basierend auf Bewegungstrajektorien.