GIF / animierte GIFs – Hintergrund transparent freistellen
Erforderliche Eingaben
- Quelldatei: Handelt es sich um eine GIF-, PNG-Sequenz oder ein Video? Bei Videos wird automatisch ffmpeg zur Extraktion der Einzelbilder verwendet (im Skript integriert).
- Betrachtungshintergrund: Auf welchem Hintergrund betrachtet der Benutzer das Bild? Ein dunkler oder weißer Hintergrund zeigt unterschiedliche Artefakte. Falls unbekannt, wird standardmäßig eine vollständige Hintergrundprüfung durchgeführt (im Skript integriert). Nicht überspringen.
- Hat das Motiv helle Teile, die farblich nahe am Hintergrund liegen (z. B. weiße Handschuhe, Stiefel, Kanten)? Dies ist eine Einschränkung des Verfahrens – siehe Abschnitt „Lösbarkeit prüfen“.
Lösbarkeit prüfen (diesen Schritt überspringen führt zu stundenlanger Verschwendung)
Die Hintergrundentfernung ist ein Problem der Informationsrekonstruktion, nicht der Algorithmenoptimierung. Wenn helle Teile des Motivs farblich nahe am Hintergrund liegen, können Nachbearbeitungsschritte sie nicht trennen – alle Verfahren (Chrominanz, Glättung, zeitlicher Median, Hintergrundflächenanpassung) würden das Motiv beschädigen.
Verlassen Sie sich nicht auf das bloße Auge. Führen Sie stattdessen folgenden Befehl aus:
.venv-bg\Scripts\python scripts\cutout.py --input <Quelldatei> --work work --stage solvability
Es extrahiert den Hintergrund und das Motiv unter der Annahme einer statischen Kamera und bewegten Motivs und gibt drei Werte aus:
- Mittlere Farbe des Hintergrunds / hellster Farbton des Motivs / Differenz
- Anteil der Motivpixel, die innerhalb von ±25/255 um die Hintergrundfarbe liegen – dieser Wert ist am aussagekräftigsten.
Beispiel mit einem Robotermaterial: Hintergrund (212,207,210), hellstes Motiv (250,251,250), Differenz 40,7, aber 32,6 % der Motivpixel liegen innerhalb von 25/255 um die Hintergrundfarbe → Ausgabe AMBIGUOUS.
Bei AMBIGUOUS muss der Benutzer informiert werden:
Dieses Material hat helle Teile, die farblich sehr nah am Hintergrund liegen. Eine reine Freistellung kann keine pixelgenaue Sauberkeit erreichen, maximal „sehr feine Artefakte bei Vergrößerung“. Falls eine Quelldatei vorhanden ist, kann die Szene mit einem reinen Grün- oder Magenta-Hintergrund neu gerendert werden, um vollständige Sauberkeit zu erreichen. Mit der endgültigen Ausgabedatei ist nur eine annähernd saubere Lösung möglich.
Fragen Sie den Benutzer, ob er fortfahren möchte, und starten Sie keine 20-minütige Verarbeitung ohne Rückmeldung.
Hinweis: Diese Prüfung ist ein Warnsignal, kein Urteil. Die endgültige Bewertung basiert auf den tatsächlichen Artefakten nach der Verarbeitung – ein „lösbar“-Ergebnis kann dennoch Artefakte durch Modellungenauigkeiten aufweisen, ein „nicht lösbar“-Ergebnis kann dennoch sauber sein.
Ablauf
-
Arbeitsverzeichnis erstellen und Umgebung einrichten
python -m venv .venv-bg && .venv-bg\Scripts\python -m pip install rembg onnxruntime pillow scipy(scipy wird von der rembg-Abhängigkeitskette benötigt, für die Leitfilterung – siehe unten)
-
Pipeline ausführen
.venv-bg\Scripts\python scripts\cutout.py --input <Quelldatei> --outdir out --scale 2--inputakzeptiert Videodateien, GIF/PNG-Dateien oder ein Verzeichnis mit bereits extrahierten PNG-Einzelbildern.--scale 2ist nicht optional: Die Spalten zwischen Gliedmaßen und Körper sind nur 5–15 px breit; bei 720p erkennt das Segmentierungsmodell sie nicht. Bei hartnäckigen Einzelbildern kann--stage mattemit--scale 3separat ausgeführt werden.Auf reiner CPU dauert die Verarbeitung von 70 Frames bei 720p und 2× Skalierung etwa 20 Minuten (ca. 17,6 s/Frame, onnxruntime ohne GPU). Informieren Sie den Benutzer vorab über diesen Zeitrahmen.
-
Verifikation (siehe nächster Abschnitt). Bei Nichtbestehen gezielt die fehlerhafte Stufe wiederholen, nicht die gesamte Pipeline.
-
Auslieferung: Alle drei Formate GIF + WebP + APNG bereitstellen und deren jeweilige Anwendungsfälle erläutern.
Harte Regeln (Verstöße haben zu erheblichen Nacharbeiten geführt)
- Topologische Operationen: Nur Opening, niemals Closing.
binary_closingwürde Lücken ≤2 px zwischen Arm und Körper verschließen, die später nicht mehr zu öffnen sind. Dieser Fehler hat zu mehr Nacharbeiten geführt als alle anderen Probleme zusammen. - Schwellwert für Lochfüllung klein halten (ca. 60 px, nicht Hunderte). Echte Gliedmaßenspalten haben Tausende Pixel, Nadelöcher nur Dutzende.
- Leitfilterradius ≤2, standardmäßig kein Medianfilter. Ein 3×3-Medianfilter und ein Leitfilter mit Radius 4 würden schmale Lücken von wenigen Pixeln auslöschen.
- Keine nichtlineare Kompression des Alphakanals. Eine Abbildung wie
clip((clip((a-0.04)/0.92)-0.06)/0.88)sollte die Kanten straffen, erhöht aber bei α≈0,7 den Alpha-Wert und verstärkt Artefakte. - GIF nicht mit geordnetem Dithering (Bayer) ausgeben. Auf Einzelbildern wirken die Kanten weicher, aber das Raster ist an den Bildschirmkoordinaten fixiert – bei Bewegung entsteht ein flimmernder Effekt. GIF sollte mit harter Schwelle und ohne Dithering ausgegeben werden; weiche Alpha-Kanten bleiben WebP/APNG vorbehalten.
- Modellwahl: BiRefNet. isnet/u2net klassifiziert Spiegelungen auf dem Boden als Teil des Motivs; mit
birefnet-general-litewird der Alpha-Wert an der Stiefelsohle auf Null gesetzt. - Nicht versuchen, den Hintergrund durch Farbabgleich zu „reinigen“. Eine flächige Entfernung von Artefakten durch Hintergrundflächen-/Chrominanzkriterien würde auch helle Teile des Motivs entfernen. Die korrekte Lösung ist eine höhere Matte-Auflösung, nicht eine Änderung der Schwellwerte.
Ausgabeformat
out/<name>.gif– Transparenter Index 255,transparency=255,disposal=2, 1-Bit harte Kanten. Topologische Bereinigung (Punktentfernung) wird nur auf GIF angewendet.out/<name>.webp– Erhält kontinuierliches Alpha, keine topologische Bereinigung, daher bleibt ein weicher, warmer Rand. Bevorzugt für komplexe Hintergründe verwenden – dieser Unterschied ist beabsichtigt, kein Fehler.out/<name>.png– APNG, beste Browser-Kompatibilität.- Behält die ursprüngliche Bildgröße, Bildanzahl, Bilddauer und Wiederholungseinstellungen bei. Die gemessenen Werte werden in der Antwort aufgelistet (animierte WebP-Bilddauer kann von PIL nicht gelesen werden; in diesem Fall ehrlich mit „gemessen anhand GIF“ antworten).
- Dateien mit
<media>-Tag ausliefern und die jeweiligen Anwendungsfälle von GIF und WebP erläutern.
Fehlerbehandlung
- GIF erscheint im Browser mit grauem Hintergrund: Zuerst nicht die Datei ändern. Prüfen Sie das ALPHA-Bit und die ANIM-Hintergrundfarbe in VP8X (
verify.pygibt diese aus). Wenn beides korrekt ist, legt der Viewer einen farbigen Hintergrund unter den transparenten Bereich. Wennverify.pyANMF ... blend=0meldet, liegt ein echtes Problem vor –cutout.pyexportiert standardmäßig mitblend=1. Einblend=0deutet auf eine nicht von diesem Skript erstellte Datei oder eine Bearbeitung mit externen Tools hin. - Motiv wird abgeschnitten: Fast immer ist das Hintergrundkriterium zu breit. Zurück zur Ebene
final/und neu exportieren, nicht in der Entfernungslogik Parameter ändern. - Einige Bildlücken wurden nicht geöffnet: Mit
--stage matte --scale 3nur diese Bilder wiederholen, Kosten pro Bild ca. 20 s. - Langsamer Download des rembg-Modells: rembg 2.x speichert Modelle unter
~/.rembg/models/<model>/<model>.onnx(nicht im alten~/.u2net-Verzeichnis).birefnet-general-liteist ca. 214 MB groß. Beim ersten Start muss der Download abgewartet werden.
Verifikation (dieser Schritt ist nicht optional)
Die Ergebnisse müssen auf dem tatsächlichen Betrachtungshintergrund des Benutzers Frame für Frame geprüft werden, sonst ist die Prüfung wertlos:
.venv-bg\Scripts\python scripts\verify.py out\<name>.gif --backdrop grey --ref work\final
Es gibt aus: Anzahl der Rauschpixel, Deckkraftanteil pro Frame (zur Erkennung von Flimmern), niedrigste undurchsichtige Zeile, Farbquantisierungsfehler von GIF relativ zum Quell-Matte, WebP-Container-Flags, und erzeugt einen Vierfarb-Hintergrundvergleich, einen Kontaktabzug aller Frames und eine vergrößerte Ansicht bestimmter Bereiche.
Bewertungskriterien:
| Kriterium | Bestanden, wenn |
|---|---|
| Rauschpixel | 0 |
| Max. Differenz der Deckkraftanteile über alle Frames | < 0,05 |
| Niedrigste undurchsichtige Zeile | Über alle Frames gleich (Reflexionsartefakte führen zu Schwankungen oder Berühren des Bildrands) |
| Farbquantisierungsfehler (Mittelwert) | < 3/255 (in der Vorschau nicht sichtbar, nur anhand dieses Werts erkennbar) |
| Vierfarb-Hintergrundvergleich | Jeder Hintergrund ist sichtbar, kein einheitliches Hellgrau |
| Kontaktabzug | Keine Geisterbilder, kein Rauschen, Gliedmaßenspalten sind durchgängig |
Eine reine Betrachtung einzelner Frames oder nur auf schwarzem Hintergrund übersieht Probleme – warme Artefakte werden erst auf dunkelgrauem Hintergrund sichtbar.
Hinweise für Windows (win32)
- Der Interpreter wird mit
pyoderpythonaufgerufen,python3existiert unter Windows nicht; verwenden Sie nicht daspythonaus dem PATH (könnte auf eine hermes-Venv ohne pip verweisen), sondern bevorzugt.venv-bg\Scripts\python.exeaus der Venv. - Bei Pfaden mit chinesischen Zeichen verwenden Sie die Tools
Write/Readzum Schreiben von Skriptdateien, nichtSet-Content, um Zeichenkodierungsfehler zu vermeiden. - PILs
ImageFilter.GaussianBlurunterstützt den Modus"F"und float RGB; für Float-Bilder verwenden Siescipy.ndimage.gaussian_filter(scipy ist durch rembg bereits installiert). Image.fromarray(float32_array, "RGB")führt zu einem Fehler; konvertieren Sie zuerst mit.astype(np.float32)und verarbeiten Sie dann kanalweise.- Verwenden Sie nicht
Remove-Itemzur Bereinigung;cutout.py --cleankapselt die Verzeichnisbereinigung.
Beispiele
Eingabe: „Mach den Hintergrund dieses GIFs transparent“
→ cutout.py --input animation.gif --outdir out --scale 2, dann verify.py,
→ Auslieferung von GIF/WebP/APNG, Angabe von 720×720 / 70 Frames / 100 ms pro Frame / gesamt 7000 ms.
Eingabe: „Mach es sauberer, die Kanten haben noch Rauschen, und zwischen Arm und Körper ist noch eine Lücke“
→ Nicht den Schwellwert ändern. Zuerst verify.py --zoom <Koordinaten> ausführen, um die Defektposition zu bestätigen.
→ Bei vielen Rauschpixeln --median 3 hinzufügen, bei unvollständigen Lücken --stage matte --scale 3 für die entsprechenden Frames wiederholen.
→ Erneut verifizieren. In der Antwort klar angeben, um welche Art von Defekt es sich handelt und welche Korrekturmaßnahme ergriffen wurde; nicht einfach „optimiert“ sagen.