5.19. Tonální korekce

Tonální korekce mění, jak jsou jas a barva rozloženy ve zachyceném obrazu – jde o opravy, které aplikace použije, když je snímek příliš tmavý, příliš světlý, příliš plochý nebo posunutý směrem k nesprávné barvě.

Korekce patří do dvou skupin: úpravy jasu a kontrastu, které přerozdělují jas, a barevné úpravy, které mění, jako kterou barvu je každý pixel čten. Obě mají obdoby v ISP senzoru, který opravuje každý snímek při jeho příchodu; zde uvedené metody se aplikují na již zachycený Image dodatečně, pro případy, kdy snímek potřebuje více korekcí, než poskytl ISP.

5.19.1. Ekvalizace histogramu

Nejjednodušší operací pro roztažení kontrastu je ekvalizace histogramu. Myšlenka spočívá v přemapování hodnot pixelů tak, aby byl histogram výstupu co nejplošší – každá hodnota se vyskytuje zhruba stejně často. Vizuálním efektem je, že obraz s nízkým kontrastem (jehož histogram je soustředěn v úzkém pásmu) se stane obrazem s vysokým kontrastem, jehož pixely pokrývají celý rozsah 0255.

histeq() provádí ekvalizaci:

img.histeq()

Mechanika je přímočará. Vypočítá se kumulativní distribuční funkce (CDF) histogramu zdroje; každá vstupní hodnota pixelu je namapována na svou pozici v CDF, škálovanou na výstupní rozsah. Tam, kde byly pixely již rovnoměrně rozloženy, se mapování blíží identitě; tam, kde se pixely nahromadily na jednom jasu, je mapování rozprostře tím, že daný jas roztáhne přes širší rozsah výstupních hodnot.

Výsledek je dramatický u scén s nízkým kontrastem – rozdíl mezi tmavou fotografií v interiéru a toutéž fotografií po histeq je často rozdílem mezi „nečitelným“ a „perfektně čitelným“. Cenou za to je, že operace zesiluje vše, včetně šumu senzoru. U scény se skutečným detailem s nízkým kontrastem, který je třeba obnovit, je histeq správnou odpovědí; u čisté, dobře exponované scény, která jej jednoduše nepotřebuje, histeq zavádí viditelný šum.

5.19.2. CLAHE: adaptivní ekvalizace

Ekvalizace histogramu je globální: používá jednu CDF vypočítanou z celého obrazu a aplikuje ji všude. To funguje na obrazech, jejichž rozsah jasu je zhruba rovnoměrný, ale selhává u scén s lokalizovanými tmavými a světlými oblastmi – CDF je stažena směrem ke straně, která má více pixelů, a opačná strana je překorigována.

Adaptivní variantou je Contrast Limited Adaptive Histogram Equalisation, běžně označovaná jako CLAHE. Místo jedné globální CDF vypočítá CLAHE samostatnou CDF pro každou malou dlaždici obrazu, ekvalizuje každou dlaždici vůči její vlastní CDF a sloučí hranice dlaždic dohromady. Výsledkem je, že úpravy jasu probíhají lokálně – zastíněný roh dostane svou vlastní ekvalizaci, aniž by jej světlý roh táhl nesprávným směrem.

Příznak adaptive=True přepíná histeq() do režimu CLAHE:

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

Parametr clip_limit je tou částí CLAHE, na kterou odkazuje „contrast limited“ v jeho názvu. Lokální ekvalizace může nadměrně zesilovat šum v plochých oblastech, kde má CDF velmi málo odlišných hodnot; clip limit omezuje, jak agresivně může být kterýkoli jednotlivý koš přerozdělen, což zabraňuje zesílení šumu a přitom stále umožňuje roztažení kontrastu tam, kde na něm záleží. Hodnota kolem 10 je rozumným výchozím bodem; větší hodnoty nechávají CLAHE pracovat tvrději za cenu více viditelného šumu, menší hodnoty jej činí jemnějším.

CLAHE je náročnější než globální histeq, ale produkuje čistší výsledky u scén, kde je jas nerovnoměrně rozložen – což je většina reálných scén.

5.19.3. Gama, kontrast a jas

Ekvalizace histogramu je datově řízený způsob přemapování jasu. Datově nezávislým způsobem je aplikovat zvolenou křivku, parametrizovanou několika snadno laditelnými ovladači. gamma() poskytuje tři:

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

Každý parametr aplikuje jednu konkrétní transformaci na každý pixel:

gamma prožene hodnotu každého pixelu mocninnou funkcí output = input ** (1 / gamma). Standardní význam: hodnoty větší než 1.0 obraz zesvětlují a zvedají střední tóny (klasická korekce „monitor gamma“); hodnoty menší než 1.0 jej ztmavují. Parametr je nelineární – zachovává černý a bílý bod a přetváří pouze rozložení mezi nimi, což je správné chování, když je cílem obnovit detail ve stínech nebo světlech bez potlačení stávajících extrémů.

contrast prožene každý pixel přímým násobením kolem bodu střední šedi. Hodnoty větší než 1.0 zvyšují kontrast (tmavé se ztmaví, světlé se zesvětlí, střední šedá zůstane stejná); hodnoty menší než 1.0 kontrast snižují.

brightness přičítá konstantu ke každé hodnotě pixelu. Kladné hodnoty zesvětlují, záporné hodnoty ztmavují. Posun je rovnoměrný – nic se nezachovává – což je zřídka to, co aplikace sama o sobě chce, ale dobře se kombinuje s průchodem kontrastu pro vystředění výsledku.

Tyto tři parametry se skládají: jediné volání gamma() může aplikovat gama křivku, poté násobení kontrastem a poté posun jasu, vše v jednom průchodu. Pořadí je nejprve gama, poté kontrast a poté jas, což odpovídá pořadí, které dává nejintuitivnější výsledky, když jsou všechny tři nevýchozí.

5.19.4. Automatické vyvážení bílé

Barevná skupina tonálních korekcí začíná automatickým vyvážením bílé. Tentýž mechanismus, který ISP senzoru spouští jako součást zobrazovacího řetězce – úpravu relativních zisků na červeném, zeleném a modrém kanálu tak, aby se průměrná šedě zbarvená plocha četla jako skutečně šedá – je k dispozici také jako operace po zachycení na hotovém Image:

img.awb()

Výchozí nastavení používá algoritmus gray-world: předpokládá se, že průměrná barva celého obrazu je neutrálně šedá, a zisky jednotlivých kanálů jsou upraveny tak, aby tomu tak bylo. Alternativní forma max=True používá algoritmus white-patch: předpokládá se, že nejsvětlejší pixely jsou neutrálně bílé, a zisky jsou upraveny tak, aby tomu tak bylo. Oba fungují na RGB565 a na surovém Bayer; ani jeden nefunguje na stupních šedi (kde není žádná barva k vyvážení) ani na YUV (kde reprezentace barvy není tím, s čím tyto algoritmy pracují).

Kdy sáhnout po formě po zachycení namísto automatického vyvážení bílé od ISP: když volba ISP špatně odpovídala konkrétní scéně, když aplikace načítá referenční snímky z disku, které byly zachyceny za odlišných podmínek, nebo když na barevném posouzení záleží natolik, že aplikace jej chce znovu spustit s vlastní volbou algoritmu.

5.19.5. Matice korekce barev

Když barevná korekce, kterou obraz potřebuje, není škálováním jednotlivých kanálů, jaké poskytuje vyvážení bílé, ale obecnějším mícháním kanálů, operací, po které je třeba sáhnout, je matice korekce barev. Metoda ccm() aplikuje matici 3 krát 3 (nebo 3 krát 4 s offsetem), která násobí vektor (r, g, b) každého pixelu, aby vytvořila nový vektor (r, g, b):

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

Matice umožňuje aplikaci korigovat přeslechy mezi barevnými kanály – například tam, kde odezva červeného senzoru zahrnuje část zeleného světla, může matice odečíst zlomek zeleného kanálu z červeného výstupu jako kompenzaci. V kombinaci s offsetem jednotlivých kanálů umožňuje forma 3 krát 4 aplikaci také vynulovat každý kanál.

Materiál o ISP řetězci se zabývá tím, proč matice korekce barev. Forma po zachycení na Image je jen tatáž operace, aplikovaná dodatečně.