Blog / Teknik

PNG transparan merusak upscaler AI: bug halo gelap

· studi bug, dengan perbaikan yang diukur · subjek: pipeline ×4 produksi

Masukkan PNG dengan transparansi (foto yang dipotong, ekspor stiker) ke hampir semua upscaler AI dan sebuah cacat khas muncul: halo gelap yang merayap beberapa piksel ke dalam subjek dari setiap tepi transparan, dengan cincin overshoot terang yang samar di belakangnya. Ia bersembunyi pada pratinjau gelap dan mencolok pada halaman putih. Kami mereproduksinya pada pipeline kami sendiri, mengukur bentuk persisnya (parit −94 luma, selebar tiga piksel model), melacaknya ke perjalanan bolak-balik alfa premultiplied pada platform web, dan mengukur perbaikan yang kami rilis: flood fill O(n) yang menghapus 98% galat sebelum model sempat berjalan.

−93,9galat luma, cincin piksel pertamajalur naif vs referensi bersih
≈3 pxlebar parit pada skala modellalu cincin overshoot +17
63×pengurangan galat dari perbaikan−62,9 → 1,1 rata-rata, pita 0–3 px
O(n)biaya perbaikansatu lintasan BFS, tanpa inferensi tambahan

Setiap angka dalam catatan ini diukur pada kode pipeline produksi: model yang sama, matematika yang sama. Rekaman mentah per gambar: e3_alpha.json.

1 · Dari mana hitamnya berasal

Kanvas 2D web menyimpan piksel secara premultiplied: bukan (r, g, b, α) melainkan (rα, gα, bα, α). Pengompositan menyukai format ini (operator Porter–Duff[1] menjadi satu operasi kali-tambah), tetapi ia lossy tepat di satu tempat. Membaca piksel kembali berarti membagi warna dengan α:

r = ⌊ rα / α ⌉, tak terdefinisi pada α = 0(1)

Pada α = 0 itu adalah 0/0, dan jawaban platform[2] adalah tidak ada lagi yang bisa dipulihkan: warnanya sudah dikalikan nol begitu menyentuh kanvas. getImageData mengembalikan RGB (0, 0, 0) di bawah setiap piksel yang sepenuhnya transparan. Bidang transparan pada potonganmu diam-diam telah menjadi danau hitam pekat.

Manusia tidak pernah melihat danau itu: alfa menyembunyikannya. Jaringan super-resolusi bukan manusia: ia mengonsumsi tiga kanal RGB dan tanpa alfa, jadi ia melihat sebuah foto yang tertanam dalam vantablack, dan setiap piksel output di dekat batas dihitung dari receptive field yang mencelup ke danau itu. Hitamnya tidak diam di tempat; ia berdifusi ke dalam melalui tumpukan konvolusi[3].

2 · Mengukur halo

naif (RGB kanvas=0)alpha bleed (milik kami)
-100-75-50-2502513581216jarak L1 ke dalam subjek (px, skala model)Δ luma vs referensisempurna
Gambar 1. Halo, diprofilkan. Jalur naif (ungu): parit −94 luma pada cincin piksel pertama di dalam subjek, −90 pada 2 px, −54 pada 3 px, lalu cincin overshoot +17 pada 5 px yang meluruh ke nol menjelang ~13 px; kontaminasi gelap melalui receptive field yang terbatas, dipertajam oleh GAN menjadi sebuah tepi. Jalur produksi (hijau): tidak pernah lebih buruk dari 1,5 level luma. Jarak pada skala model; ×4 untuk piksel output.
Tiga panel: input potongan ditampilkan di atas papan catur, upscale naif dengan pinggiran gelap di sekeliling oval, dan upscale alpha-bled yang bersih
Gambar 2. Input dengan transparansi (kiri), jalur naif (tengah), jalur produksi (kanan), dikomposit di atas latar terang. Pinggiran panel tengah terbaca sebagai “tepi kotor” yang samar pada ukuran thumbnail, dan itulah persisnya mengapa bug ini begitu sering lolos rilis: ia bersembunyi sampai seorang pengguna meletakkan stikernya di latar terang.

Satu pengukuran yang benar-benar berlawanan dengan intuisi: kami mengira model akan menghalusinasikan sampah di dalam wilayah transparan, “meningkatkan kekosongan”. Ternyata tidak. Hitam datar masuk, hitam datar keluar (energi gradien 0,1). Bahayanya bukan apa yang dikarang model di dalam kekosongan; melainkan apa yang dilakukan kekosongan itu pada subjek melintasi batas. Itu penting karena berarti mem-mask output tidak bisa menyelamatkanmu: piksel yang rusak berada di dalam wilayah yang terlihat, di bawah α > 0.

3 · Perbaikannya: banjiri kekosongan dengan warna yang masuk akal

Jika model harus melihat RGB di bawah α = 0, jadikan itu RGB yang melanjutkan subjek. Sebelum inferensi kami menjalankan alpha bleeding: banjir breadth-first multi-sumber dari setiap piksel non-transparan, di mana setiap piksel transparan mengambil warna rata-rata dari 4 tetangganya yang sudah berwarna:

c(p) = mean{ c(q) : q ∈ N₄(p), q berwarna },  p dalam urutan BFS(2)

Mengisi antrean dengan cincin batas dan memprosesnya secara FIFO menjamin setiap piksel yang dikeluarkan dari antrean punya setidaknya satu tetangga berwarna (siapa pun yang memasukkannya sudah selesai lebih dulu), sehingga satu lintasan O(n) mewarnai seluruh kekosongan: jarak tak terbatas, termasuk lubang yang tertutup. Byte alfa tidak pernah disentuh; piksel semi-transparan mempertahankan warnanya sendiri. Model lalu melihat kelanjutan yang mulus alih-alih tebing, dan alfa (di-upscale secara terpisah) diterapkan kembali saat keluar. Efek terukur: galat pita 0–3 px turun dari -62,9 ke 1,1 level luma, pengurangan 63×, tanpa biaya runtime yang terukur.

Detail tepi rekonstruksi naif dan bled, plus peta panas selisih yang diperkuat yang memperlihatkan halo memeluk batas alfa
Gambar 3. Detail tepi: jalur naif (kiri) di samping jalur bled (tengah), dan di kanan |selisih| antara kedua rekonstruksi, diperkuat ×8. Halo mengikuti batas alfa dan tidak yang lain; jauh dari tepi, outputnya identik, yang berarti perbaikannya berperilaku persis seperti dirancang.

4 · Apa artinya ini bagi gambarmu

Jika kamu memakai situs ini: tidak ada; PNG transparan melewati jalur terukur di atas, baik di pipeline cloud maupun mesin fallback di browser, karena keduanya berbagi pustaka murni yang sama. Jika kamu membangun alat gambar: perlakukan setiap model yang hanya menerima RGB sebagai alergi terhadap nol premultiplied: bleed sebelum inferensi (banjir di atas hanya ~30 baris tanpa dependensi), atau matte ke warna solid dan terima bias matte-nya. Dan jika kamu sedang mendiagnosis tepi gelap misterius pada output enhancer seseorang, kini kamu tahu sidik jarinya: parit selebar beberapa piksel, cincin overshoot di belakangnya, dan korelasi sempurna dengan batas alfa. Tiga angka untuk diingat: −94, 3 px, 63×.

Referensi

  1. Porter, T., & Duff, T. (1984). Compositing Digital Images. SIGGRAPH '84, Computer Graphics 18(3), 253–259. (The premultiplied-alpha compositing algebra.) dl.acm.org
  2. 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
  3. 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
  4. Lange, D. (1936). “Migrant Mother” (Destitute pea pickers in California), Farm Security Administration. Public domain, via Wikimedia Commons. commons.wikimedia.org
  5. ONNX Runtime: the inference engine both our server (CPU) and in-browser (WebGPU/WASM) engines run on. onnxruntime.ai