Transparente PNGs brechen KI-Upscaler: der Bug mit dem dunklen Halo
Gib ein PNG mit Transparenz (ein freigestelltes Foto, ein Sticker-Export) in fast jeden KI-Upscaler, und ein ganz bestimmter Defekt erscheint: ein dunkler Halo, der von jeder transparenten Kante ein paar Pixel weit ins Motiv kriecht, dahinter ein schwacher heller Überschwinger-Ring. Auf dunklen Vorschauen versteckt er sich, auf weißen Seiten sticht er ins Auge. Wir haben ihn auf unserer eigenen Pipeline reproduziert, seine genaue Form gemessen (ein Graben von −94 Luma, drei Modellpixel breit), ihn auf die Premultiplied-Alpha-Rundreise der Webplattform zurückgeführt und den Fix gemessen, den wir ausliefern: ein O(n)-Flood-Fill, der 98 % des Fehlers entfernt, bevor das Modell überhaupt läuft.
Jede Zahl in dieser Notiz wurde mit dem Code der Produktions-Pipeline gemessen: dieselben Modelle, dieselbe Mathematik. Rohdaten pro Bild: e3_alpha.json.
1 · Woher das Schwarz kommt
Das 2D-Canvas des Webs speichert Pixel vormultipliziert: nicht (r, g, b, α), sondern (rα, gα, bα, α). Das Compositing liebt dieses Format (die Porter-Duff-Operatoren[1] werden zu einzelnen Multiply-Adds), aber es ist an genau einer Stelle verlustbehaftet. Pixel zurückzulesen heißt, die Farbe durch α zu teilen:
Bei α = 0 ist das 0/0, und die Antwort der Plattform[2] lautet, dass es nichts mehr zurückzugewinnen gibt: Die Farbe wurde in dem Moment mit null multipliziert, in dem sie das Canvas berührte. getImageData liefert unter jedem vollständig transparenten Pixel RGB (0, 0, 0). Die transparente Fläche deines Freistellers ist stillschweigend zu einem See aus reinem Schwarz geworden.
Ein Mensch sieht den See nie: Alpha verbirgt ihn. Ein Super-Resolution-Netz ist kein Mensch: Es konsumiert drei RGB-Kanäle und kein Alpha, es sieht also eine Fotografie, eingebettet in Vantablack, und jedes Ausgabepixel nahe der Grenze wird aus einem rezeptiven Feld berechnet, das in den See eintaucht. Das Schwarz bleibt nicht an Ort und Stelle; es diffundiert durch den Faltungsstapel nach innen[3].
2 · Den Halo messen

Eine wirklich kontraintuitive Messung: Wir hatten erwartet, dass das Modell innerhalb des transparenten Bereichs Müll halluziniert, „die Leere verbessert“. Tut es nicht. Flaches Schwarz rein, flaches Schwarz raus (Gradientenenergie 0,1). Der Schaden ist nicht das, was das Modell in der Leere erfindet; es ist das, was die Leere dem Motiv über die Grenze hinweg antut. Das ist wichtig, weil es bedeutet, dass das Maskieren der Ausgabe dich nicht retten kann: Die beschädigten Pixel liegen innerhalb des sichtbaren Bereichs, unter α > 0.
3 · Der Fix: die Leere mit plausibler Farbe fluten
Wenn das Modell RGB unter α = 0 sehen muss, dann soll es RGB sein, das das Motiv fortsetzt. Vor der Inferenz führen wir Alpha-Bleeding aus: eine Breitensuche-Flutung mit mehreren Quellen, ausgehend von jedem nicht-transparenten Pixel, bei der jedes transparente Pixel die mittlere Farbe seiner bereits gefärbten 4-Nachbarn annimmt:
Die Warteschlange mit dem Randring zu seeden und FIFO abzuarbeiten, garantiert, dass jedes entnommene Pixel mindestens einen gefärbten Nachbarn hat (wer es eingereiht hat, war zuerst fertig), sodass ein einziger O(n)-Durchgang die gesamte Leere färbt: unbegrenzte Distanz, eingeschlossene Löcher inklusive. Alpha-Bytes werden nie angefasst; halbtransparente Pixel behalten ihre eigene Farbe. Das Modell sieht dann eine glatte Fortsetzung statt einer Klippe, und Alpha (separat hochskaliert) wird auf dem Weg nach draußen wieder angewendet. Gemessener Effekt: Der Fehler im 0–3-px-Band fällt von -62,9 auf 1,1 Luma-Stufen, eine 63-fache Reduktion, ohne messbare Laufzeitkosten.

4 · Was das für deine Bilder bedeutet
Wenn du diese Seite benutzt: nichts; transparente PNGs nehmen den oben gemessenen Pfad in der Cloud-Pipeline wie in der Browser-Fallback-Engine, denn beide teilen sich dieselbe reine Bibliothek. Wenn du Bild-Tools baust: Behandle jedes reine RGB-Modell als allergisch gegen vormultiplizierte Nullen: Bleeding vor der Inferenz (die Flutung oben sind ~30 Zeilen ohne Abhängigkeiten), oder auf eine Volltonfarbe matten und die Verzerrung der Matte in Kauf nehmen. Und wenn du eine mysteriöse dunkle Kante in der Ausgabe von jemandes Enhancer diagnostizierst, kennst du jetzt den Fingerabdruck: ein Graben, ein paar Pixel breit, ein Überschwinger-Ring dahinter und eine perfekte Korrelation mit der Alpha-Grenze. Die drei Zahlen zum Merken: −94, 3 px, 63×.
Quellen
- Porter, T., & Duff, T. (1984). Compositing Digital Images. SIGGRAPH '84, Computer Graphics 18(3), 253–259. (The premultiplied-alpha compositing algebra.) dl.acm.org
- WHATWG HTML Living Standard, the 2D canvas element: premultiplied backing stores and the lossy getImageData round-trip for non-opaque pixels. html.spec.whatwg.org
- Wang, X., Xie, L., Dong, C., & Shan, Y. (2021). Real-ESRGAN: Training Real-World Blind Super-Resolution with Pure Synthetic Data. ICCV Workshops. arXiv:2107.10833. arxiv.org
- Lange, D. (1936). “Migrant Mother” (Destitute pea pickers in California), Farm Security Administration. Public domain, via Wikimedia Commons. commons.wikimedia.org
- ONNX Runtime: the inference engine both our server (CPU) and in-browser (WebGPU/WASM) engines run on. onnxruntime.ai