5.19. Koreksi tonal

Koreksi tonal mengubah cara kecerahan dan warna didistribusikan dalam citra yang diambil -- perbaikan yang diterapkan aplikasi ketika sebuah bingkai terlalu gelap, terlalu terang, terlalu datar, atau condong ke arah warna yang salah.

Koreksi-koreksi ini terbagi dalam dua kelompok: penyesuaian kecerahan-dan-kontras yang mendistribusikan ulang kecerahan, dan penyesuaian warna yang mengubah warna yang dibaca oleh setiap piksel. Keduanya memiliki padanannya dalam ISP sensor, yang mengoreksi setiap bingkai saat masuk; metode-metode di sini diterapkan pada Image yang sudah diambil, setelah fakta, untuk kasus-kasus di mana bingkai membutuhkan koreksi lebih dari yang diberikan ISP.

5.19.1. Ekualisasi histogram

Operasi peregangan kontras yang paling sederhana adalah ekualisasi histogram. Idenya adalah memetakan ulang nilai-nilai piksel sehingga histogram keluaran serata mungkin -- setiap nilai muncul kira-kira sama sering. Efek visualnya adalah bahwa citra berkontras rendah (yang histogramnya terkonsentrasi dalam rentang sempit) menjadi citra berkontras tinggi yang piksel-pikselnya mencakup rentang penuh 0 -- 255.

histeq() menjalankan ekualisasi:

img.histeq()

Mekanismenya langsung. Fungsi distribusi kumulatif (CDF) dari histogram sumber dihitung; setiap nilai piksel masukan dipetakan ke posisinya dalam CDF, diskalakan ke rentang keluaran. Di mana piksel-piksel sudah tersebar merata, pemetaan mendekati identitas; di mana piksel-piksel menumpuk pada satu kecerahan, pemetaan menyebarkannya dengan meregangkan kecerahan tersebut ke rentang nilai keluaran yang lebih luas.

Hasilnya dramatis pada adegan berkontras rendah -- perbedaan antara foto indoor yang redup dan foto yang sama setelah histeq sering kali merupakan perbedaan antara "tidak terbaca" dan "terbaca dengan sempurna." Pertimbangannya adalah bahwa operasi ini memperkuat segalanya, termasuk noise sensor. Pada adegan dengan detail berkontras rendah yang nyata untuk dipulihkan, histeq adalah jawaban yang tepat; pada adegan yang bersih dan tereksposur dengan baik yang memang tidak memerlukannya, histeq menghasilkan noise yang terlihat.

5.19.2. CLAHE: ekualisasi adaptif

Ekualisasi histogram bersifat global: ia menggunakan satu CDF yang dihitung dari seluruh citra dan menerapkannya di mana saja. Itu berhasil pada citra yang rentang kecerahannya kira-kira seragam, tetapi gagal pada adegan dengan wilayah gelap dan terang yang terlokalisasi -- CDF tertarik ke sisi yang memiliki lebih banyak piksel, dan sisi yang berlawanan menjadi terkorekksi secara berlebihan.

Varian adaptifnya adalah Contrast Limited Adaptive Histogram Equalisation, yang biasa disebut CLAHE. Alih-alih satu CDF global, CLAHE menghitung CDF terpisah untuk setiap ubin kecil citra, menyamakan setiap ubin terhadap CDF-nya sendiri, dan memadukan batas-batas ubin bersama. Hasilnya adalah penyesuaian kecerahan terjadi secara lokal -- sudut yang redup mendapatkan ekualisasinya sendiri tanpa sudut yang terang menariknya ke arah yang salah.

Bendera adaptive=True mengalihkan histeq() ke mode CLAHE:

img.histeq(adaptive=True, clip_limit=10)

Parameter clip_limit adalah bagian dari CLAHE yang dirujuk oleh kata "contrast limited" dalam namanya. Ekualisasi lokal dapat terlalu memperkuat noise di wilayah datar di mana CDF memiliki sedikit nilai yang berbeda; batas klip membatasi seberapa agresif setiap bin tunggal dapat didistribusikan ulang, yang mencegah amplifikasi noise sekaligus tetap memungkinkan peregangan kontras di tempat yang penting. Nilai sekitar 10 adalah titik awal yang masuk akal; nilai yang lebih besar membiarkan CLAHE bekerja lebih keras dengan biaya noise yang lebih terlihat, nilai yang lebih kecil membuatnya lebih lembut.

CLAHE lebih mahal daripada histeq global, tetapi menghasilkan hasil yang lebih bersih pada adegan di mana kecerahan didistribusikan secara tidak merata -- yang merupakan sebagian besar adegan dunia nyata.

5.19.3. Gamma, kontras, dan kecerahan

Ekualisasi histogram adalah cara berbasis data untuk memetakan ulang kecerahan. Cara yang tidak bergantung pada data adalah dengan menerapkan kurva yang dipilih, diparameterisasi oleh beberapa tombol yang mudah disetel. gamma() menyediakan tiga:

img.gamma(gamma=1.0, contrast=1.0, brightness=0.0)

Setiap parameter menerapkan satu transformasi spesifik pada setiap piksel:

gamma menjalankan setiap nilai piksel melalui fungsi pangkat output = input ** (1 / gamma). Arti standar: nilai lebih besar dari 1.0 mencerahkan citra dan mengangkat midtone (koreksi "monitor gamma" klasik); nilai lebih kecil dari 1.0 menggelapkannya. Parameter ini tidak linier -- ia mempertahankan titik hitam dan putih dan hanya membentuk ulang distribusi di antara keduanya, yang merupakan perilaku yang tepat ketika tujuannya adalah memulihkan detail di wilayah bayangan atau highlight tanpa menghancurkan ekstrem yang ada.

contrast menjalankan setiap piksel melalui perkalian lurus di sekitar titik abu-abu tengah. Nilai lebih besar dari 1.0 meningkatkan kontras (gelap menjadi lebih gelap, terang menjadi lebih terang, abu-abu tengah tetap sama); nilai lebih kecil dari 1.0 mengurangi kontras.

brightness menambahkan konstanta ke setiap nilai piksel. Nilai positif mencerahkan, nilai negatif menggelapkan. Pergeserannya seragam -- tidak ada yang dipertahankan -- yang jarang menjadi yang diinginkan aplikasi dengan sendirinya, tetapi berpasangan dengan baik dengan tahap kontras untuk memusatkan kembali hasilnya.

Ketiga parameter saling menyusun: satu panggilan gamma() dapat menerapkan kurva gamma, lalu perkalian kontras, lalu pergeseran kecerahan, semuanya dalam satu kali jalan. Urutannya adalah gamma dulu, kemudian kontras, kemudian kecerahan, yang sesuai dengan urutan yang memberikan hasil paling intuitif ketika ketiganya bukan nilai default.

5.19.4. Auto white balance

Keluarga warna dari koreksi tonal dimulai dengan auto white balance. Mekanisme yang sama yang dijalankan ISP sensor sebagai bagian dari pipeline pencitraan -- menyesuaikan gain relatif pada saluran merah, hijau, dan biru sehingga tambalan abu-abu rata-rata terbaca sebagai abu-abu yang sebenarnya -- juga tersedia sebagai operasi pasca-pengambilan pada Image yang sudah selesai:

img.awb()

Default menggunakan algoritma gray-world: warna rata-rata seluruh citra diasumsikan abu-abu netral, dan gain per-saluran disesuaikan untuk membuatnya demikian. Bentuk alternatif max=True menggunakan algoritma white-patch: piksel paling terang diasumsikan putih netral, dan gain disesuaikan untuk membuatnya demikian. Keduanya bekerja pada RGB565 dan pada Bayer mentah; keduanya tidak bekerja pada skala abu-abu (di mana tidak ada warna untuk diseimbangkan) atau YUV (di mana representasi warnanya bukan yang dioperasikan algoritma ini).

Kapan menggunakan bentuk pasca-pengambilan daripada auto white balance ISP: ketika pilihan ISP kurang cocok untuk adegan tertentu, ketika aplikasi memuat bingkai referensi dari disk yang diambil dalam kondisi berbeda, atau ketika penilaian warna cukup penting sehingga aplikasi ingin menjalankannya kembali dengan pilihan algoritmanya sendiri.

5.19.5. Matriks koreksi warna

Ketika koreksi warna yang dibutuhkan citra bukan penskalaan per-saluran yang diberikan white balance, melainkan pencampuran saluran yang lebih umum, operasi yang perlu digunakan adalah matriks koreksi warna. Metode ccm() menerapkan matriks 3-kali-3 (atau 3-kali-4 dengan offset) yang mengalikan vektor (r, g, b) setiap piksel untuk menghasilkan vektor (r, g, b) baru:

img.ccm([[1.1, -0.05, -0.05],
        [-0.05, 1.1, -0.05],
        [-0.05, -0.05, 1.1]])

Matriks memungkinkan aplikasi mengoreksi crosstalk antara saluran warna -- di mana respons sensor merah mencakup beberapa cahaya hijau, misalnya, matriks dapat mengurangkan sebagian kecil saluran hijau dari keluaran merah untuk mengkompensasi. Dikombinasikan dengan offset per-saluran, bentuk 3-kali-4 juga memungkinkan aplikasi me-re-zero setiap saluran.

Materi ISP pipeline mencakup mengapa dari matriks koreksi warna. Bentuk pasca-pengambilan pada Image hanyalah operasi yang sama, diterapkan setelah fakta.