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!
9. Green-Screen
1. Überblick
In diesem Kapitel wird die Personensegmentierung von MediaPipe Pose verwendet, um einen einfachen Green-Screen-Effekt zu realisieren.
Durch die Trennung der Person vom Hintergrund kann der ursprüngliche Hintergrund durch eine einfarbig grüne Fläche ersetzt werden. Dadurch lassen sich folgende Anwendungen umsetzen:
Virtuelle Hintergründe
Chroma-Key-Komposition (OBS / NLE)
Effekte für Live-Streaming
AR-ähnlicher Szenenersatz
2. Funktionsweise
Der Green-Screen-Effekt wird mit den folgenden Schritten umgesetzt:
Initialisieren des Pose-Modells mit
enable_segmentation=True.Für jedes Frame wird
results.segmentation_maskabgerufen.Die Maske ist eine einkanalige Wahrscheinlichkeitskarte (Bereich 0–1).
Ein Schwellenwert (z. B. 0.5) trennt Vordergrund und Hintergrund.
Hintergrundpixel werden durch eine einfarbig grüne Fläche ersetzt.
Optional können Weichzeichnen oder morphologische Filter angewendet werden, um die Kanten zu glätten.
Diese Methode ist leichtgewichtig und läuft in Echtzeit auf dem Raspberry Pi und dient gleichzeitig als praktisches Beispiel für Personensegmentierung.
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_segmentation.py
Wenn Sie MediaPipe Pose mit einem aufgezeichneten Video verwenden möchten, können Sie folgenden Befehl ausführen:
sudo python3 ~/ai-lab-kit/mediapipe/mp_pose_segmentation_video.py
Nach dem Start des Programms öffnet sich ein Fenster mit dem Titel „Show Video“ und zeigt den Live-Kamerastream an.
Im selben Fenster erscheint ein Trackbar-Regler mit dem Namen
Mask. Er steuert den Segmentierungsschwellenwert (0–100), der Standardwert ist 50 (0.5).Wenn eine Person vor der Kamera erscheint:
MediaPipe Pose erzeugt für jedes Frame eine
segmentation_mask.Pixel mit Maskenwerten über dem Schwellenwert werden als Vordergrund (Person) behandelt.
Alle anderen Pixel werden durch einen einfarbig grünen Hintergrund ersetzt (Green-Screen-Effekt).
Wenn Sie den
Mask-Regler bewegen:Ein höherer Schwellenwert behält nur den sichersten Vordergrundbereich (weniger Hintergrunddurchsickern, aber eventuell abgeschnittene Körperteile).
Ein niedrigerer Schwellenwert nimmt mehr Pixel als Vordergrund auf (vollständigere Silhouette, aber möglicherweise mehr Hintergrundrauschen).
Wenn keine Segmentierungsmaske verfügbar ist, zeigt das Programm lediglich den normalen Kamerastream ohne Hintergrundersatz an.
Drücken Sie
q, um das Programm zu beenden. Die Kamera stoppt und das OpenCV-Fenster wird automatisch geschlossen.
4. Vollständiger Code
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
import numpy as np
GREEN = (0, 255, 0) # Green color (BGR)
# Initialize the Pose model
pose = mp_pose.Pose(
static_image_mode=False, # Set to False for processing video frames
model_complexity=1,
enable_segmentation=True,
)
# Open the camera
picam2 = Picamera2()
config = picam2.create_preview_configuration(
main={"size": (640, 480), "format": "XRGB8888"} ,
)
picam2.configure(config)
#picam2.start_preview(Preview.QTGL)
picam2.start()
print("Streaming... press 'q' to quit")
# --- Utility: empty callback for trackbars ---
def _noop(x):
pass
# Create Window
cv2.namedWindow('Show Video')
# Create a trackbar for threshold, default value is 50
cv2.createTrackbar('Mask', 'Show Video', 50, 100, _noop)
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 = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
# Process the frame for pose detection and tracking
results = pose.process(frame)
# Convert the frame back from RGB to BGR (required by OpenCV)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
# Read the trackbar value
threshold = cv2.getTrackbarPos('Mask', 'Show Video')
# Cutout the green background
if results.segmentation_mask is not None:
# segmentation_mask is a single-channel [H, W] probability map.
mask = results.segmentation_mask
# Use 0.5 as the hard threshold; you can adjust it to 0.3-0.7 based on the effect.
condition = (mask > threshold/100.0)[..., None] # [H, W, 1]
# Create a green background
bg = np.full_like(frame, GREEN, dtype=np.uint8)
# Use mask to keep the character and replace the background with green
frame = np.where(condition, frame, bg)
# 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 bleibt die Person (Vordergrund) erhalten, während der Hintergrund durch eine einfarbig grüne Fläche ersetzt wird. Dies kann direkt für nachfolgendes Keying mit Chroma Key in OBS, Premiere, DaVinci Resolve usw. verwendet werden.
5. Erklärung der wichtigsten Punkte
segmentation_mask ist ein einkanaliges Float-Bild (Bereich 0~1) mit derselben Größe wie das Eingabebild:
Wert nahe 1: Hohe Wahrscheinlichkeit für Vordergrund (Person);
Wert nahe 0: Hohe Wahrscheinlichkeit für Hintergrund.
Üblicherweise wird ein Schwellenwert T (z. B. 0.5) festgelegt und eine Bedingungsmaske erstellt:
condition = (mask > T)[..., None]
Hier richten wir einen Trackbar-Regler ein, um den Schwellenwert in Echtzeit anzupassen:
# Create a trackbar for threshold, default value is 50
cv2.createTrackbar('Mask', 'Show Video', 50, 100, _noop)
while True:
...
# Read the trackbar value
threshold = cv2.getTrackbarPos('Mask', 'Show Video')
# Create a condition mask
condition = (mask > threshold/100.0)[..., None] # [H, W, 1]
Anschließend können wir np.where(condition, frame, background) verwenden, um den Hintergrund zu ersetzen; hier ersetzen wir ihn durch Grün:
# Create a green background
bg = np.full_like(frame, GREEN, dtype=np.uint8)
# Use mask to keep the character and replace the background with green
frame = np.where(condition, frame, bg)
6. Effekt und Kantenoptimierung
Eine direkte Binärschwellwertbildung kann gezackte Kanten oder kleine Löcher an Haar- und Kleidungskanten verursachen. Leichte Nachbearbeitung kann die Kanten verbessern:
# Slight blur (soften edges)
mask_blur = cv2.GaussianBlur(mask, (5, 5), 0)
# Re-threshold (smoother foreground boundary)
condition = (mask_blur > 0.5)[..., None]
# Or perform morphological closing to fill small holes
bin_mask = (mask > 0.5).astype(np.uint8) * 255
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
bin_mask = cv2.morphologyEx(bin_mask, cv2.MORPH_CLOSE, kernel, iterations=1)
condition = (bin_mask > 127)[..., None]
Tipp
Empfohlener T-Wertbereich 0.3~0.7: In dunklen Umgebungen oder bei konservativen Modellen kann der Wert etwas gesenkt werden; bei stärkerem Rauschen kann er erhöht werden.
Der Unschärfekernel sollte nicht zu groß sein, da sonst die Personenkontur „grün auslaufen“ kann.
7. Verwendung eines benutzerdefinierten Hintergrunds (Bild/Video)
Ersetzen Sie das einfarbige Grün durch ein eigenes Hintergrundbild:
bg_img = cv2.imread("background.jpg")
bg_img = cv2.resize(bg_img, (frame.shape[1], frame.shape[0]))
frame = np.where(condition, frame, bg_img)
Oder verwenden Sie ein anderes Video als Hintergrund (lesen Sie das nächste Frame bg_frame, passen Sie die Größe an und ersetzen Sie es entsprechend).
8. Balance zwischen Leistung und Qualität
Element |
Auswirkung |
Empfehlung |
|---|---|---|
Auflösung |
Höhere Auflösung liefert feinere Kanten, aber geringere Geschwindigkeit |
Beginnen Sie mit 640×480; erhöhen Sie bei Bedarf für klarere Bilder |
model_complexity |
Höher bedeutet präzisere Erkennung, aber geringere Geschwindigkeit |
Für Raspberry Pi wird 1~2 empfohlen |
Stärke der Nachbearbeitung |
Zu viel Blur/Morphologie kann Kanten „verschlucken“ oder Grün durchscheinen lassen |
Kleiner Kernel + wenige Iterationen, Kantenwirkung beobachten |
9. Fehlerbehebung
Gezackte Kanten oder sichtbare Übergänge um die Person
Dies passiert meist, wenn die Maske mit einem harten Schwellenwert angewendet wird, wodurch scharfe Kanten entstehen.
Passen Sie den Schwellenwert mit dem
Mask-Regler an. Für weichere Kanten können Sie die Segmentierungsmaske leicht weichzeichnen oder eine einfache morphologische Closing-Operation vor der Komposition anwenden.Fehlende Teile der Person
Wenn Teile des Körpers fehlen, kann die Beleuchtung zu schwach sein oder die Kleidung farblich mit dem Hintergrund verschmelzen.
Verbessern Sie die Beleuchtung, passen Sie den Schwellenwert an und verwenden Sie möglichst einen einfachen Hintergrund mit starkem Kontrast zur Person.
Niedrige Bildrate
Wenn das Video langsam wirkt, ist möglicherweise die Auflösung zu hoch oder das Modell zu komplex.
Reduzieren Sie die Kameraauflösung (z. B. 640×480 oder 320×240) und setzen Sie
model_complexityauf 1 für bessere Leistung.Grüner Hintergrund überlappt mit der Person
Wenn der grüne Hintergrund auf die Person übergreift, kann die Segmentierungsgrenze ungenau sein oder die Farbe der Person zu Verwechslungen führen.
Versuchen Sie eine andere Ersatzfarbe (z. B. Blau oder Grau) oder ersetzen Sie den Hintergrund durch ein Bild statt durch eine einfarbige Fläche, um ein natürlicheres Ergebnis zu erzielen.
10. Zusammenfassung
Mit
segmentation_masklässt sich schnell ein „Personenfreistellen + Hintergrundersatz“ realisieren;Natürlichere Kanten können durch geeignete Schwellenwerte und leichte Nachbearbeitung erreicht werden;
Geeignet für virtuelle Hintergründe, Live-Streaming-Keying, Fernunterricht usw.;
Als nächster Schritt können Pose-Skelett und Segmentierung kombiniert werden, um interaktivere Effekte zu erzeugen (z. B. Hintergrund ersetzen, aber das Skelett weiterhin im Vordergrund anzeigen).