Przezroczyste PNG psują upscalery AI: błąd ciemnego halo
Podaj PNG z przezroczystością (wycięte zdjęcie, eksport naklejki) niemal dowolnemu upscalerowi AI, a pojawi się konkretna wada: ciemne halo wpełzające kilka pikseli w głąb obiektu od każdej przezroczystej krawędzi, z bladym jasnym pierścieniem przestrzelenia za nim. Kryje się na ciemnych podglądach i razi na białych stronach. Odtworzyliśmy je na własnym potoku, zmierzyliśmy jego dokładny kształt (rów −94 luminancji, szeroki na trzy piksele modelu), wyśledziliśmy je do obiegu przez wstępnie przemnożoną alfę platformy webowej i zmierzyliśmy poprawkę, którą wdrażamy: zalewowe wypełnianie O(n), które usuwa 98% błędu, zanim model w ogóle ruszy.
Każda liczba w tej notatce została zmierzona na kodzie produkcyjnego potoku: te same modele, ta sama matematyka. Surowe rekordy dla każdego obrazu: e3_alpha.json.
1 · Skąd bierze się czerń
Płótno 2D w przeglądarce przechowuje piksele wstępnie przemnożone: nie (r, g, b, α), lecz (rα, gα, bα, α). Kompozycja uwielbia ten format (operatory Portera–Duffa[1] stają się pojedynczymi mnożeniami z dodawaniem), ale jest on stratny w dokładnie jednym miejscu. Odczyt pikseli oznacza podzielenie koloru przez α:
Przy α = 0 to 0/0, a odpowiedź platformy[2] brzmi, że nie ma już czego odzyskać: kolor został pomnożony przez zero w chwili, gdy dotknął płótna. getImageData zwraca RGB (0, 0, 0) pod każdym w pełni przezroczystym pikselem. Przezroczyste pole Twojego wycinka po cichu stało się jeziorem czystej czerni.
Człowiek nigdy nie widzi tego jeziora: alfa je ukrywa. Sieć superrozdzielczości nie jest człowiekiem: pobiera trzy kanały RGB i żadnej alfy, więc widzi fotografię osadzoną w vantablacku, a każdy piksel wyjścia blisko granicy jest liczony z pola recepcyjnego, które zanurza się w jeziorze. Czerń nie zostaje na miejscu; dyfunduje do środka przez stos splotów[3].
2 · Pomiar halo

Jeden naprawdę sprzeczny z intuicją pomiar: spodziewaliśmy się, że model będzie halucynował śmieci wewnątrz przezroczystego obszaru, „ulepszał pustkę”. Nie robi tego. Płaska czerń na wejściu, płaska czerń na wyjściu (energia gradientu 0,1). Szkodą nie jest to, co model wymyśla w pustce; jest nią to, co pustka robi obiektowi przez granicę. To ma znaczenie, bo oznacza, że maskowanie wyjścia Cię nie uratuje: uszkodzone piksele są wewnątrz widocznego obszaru, pod α > 0.
3 · Poprawka: zalej pustkę wiarygodnym kolorem
Jeśli model musi widzieć RGB pod α = 0, niech to będzie RGB, które kontynuuje obiekt. Przed wnioskowaniem uruchamiamy rozlewanie alfa: wieloźródłowe zalewanie wszerz z każdego nieprzezroczystego piksela, w którym każdy przezroczysty piksel przyjmuje średni kolor swoich już pokolorowanych 4-sąsiadów:
Zasianie kolejki pierścieniem brzegowym i przetwarzanie FIFO gwarantuje, że każdy zdejmowany z kolejki piksel ma co najmniej jednego pokolorowanego sąsiada (ten, kto go dodał, skończył pierwszy), więc jeden przebieg O(n) koloruje całą pustkę: bez limitu odległości, z zamkniętymi dziurami włącznie. Bajty alfy nigdy nie są dotykane; półprzezroczyste piksele zachowują własny kolor. Model widzi wtedy gładką kontynuację zamiast urwiska, a alfa (powiększana osobno) jest nakładana ponownie na wyjściu. Zmierzony efekt: błąd w paśmie 0–3 px spada z -62,9 do 1,1 poziomu luminancji, redukcja 63×, bez mierzalnego kosztu czasu działania.

4 · Co to oznacza dla Twoich obrazów
Jeśli używasz tej strony: nic; przezroczyste PNG idą zmierzoną wyżej ścieżką zarówno w potoku chmurowym, jak i w zapasowym silniku przeglądarkowym, bo oba dzielą tę samą czystą bibliotekę. Jeśli budujesz narzędzia do obrazów: traktuj każdy model wyłącznie RGB jako uczulony na wstępnie przemnożone zera: rozlewaj przed wnioskowaniem (powyższe zalewanie to ~30 linii bez zależności) albo nakładaj na jednolity kolor i zaakceptuj jego odchylenie. A jeśli diagnozujesz tajemniczą ciemną krawędź w czyimś wyjściu z ulepszacza, znasz już odcisk palca: rów szeroki na kilka pikseli, pierścień przestrzelenia za nim i idealna korelacja z granicą alfy. Trzy liczby do zapamiętania: −94, 3 px, 63×.
Źródła
- 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