5.19. Corecții tonale

Corecțiile tonale modifică modul în care luminozitatea și culoarea sunt distribuite într-o imagine capturată – corecturile pe care le aplică o aplicație atunci când un cadru este prea întunecat, prea luminos, prea șters sau înclinat spre o culoare greșită.

Corecțiile aparțin a două familii: ajustările de luminozitate și contrast, care redistribuie luminozitatea, și ajustările de culoare, care schimbă culoarea cu care este interpretat fiecare pixel. Ambele au corespondente în ISP al senzorului, care corectează fiecare cadru pe măsură ce intră; metodele de aici se aplică unei Image deja capturate, după fapt, pentru cazurile în care cadrul are nevoie de o corecție mai mare decât a oferit ISP-ul.

5.19.1. Egalizarea histogramei

Cea mai simplă operație de întindere a contrastului este egalizarea histogramei. Ideea este de a remapa valorile pixelilor astfel încât histograma rezultatului să fie cât mai plată posibil – fiecare valoare să apară aproximativ la fel de des. Efectul vizual este că o imagine cu contrast scăzut (a cărei histogramă este concentrată într-o bandă îngustă) devine una cu contrast ridicat, ai cărei pixeli acoperă întreaga gamă 0255.

histeq() execută egalizarea:

img.histeq()

Mecanismul este direct. Se calculează funcția de distribuție cumulativă (CDF) a histogramei sursei; fiecare valoare de pixel de intrare este mapată la poziția sa în CDF, scalată la gama de ieșire. Acolo unde pixelii erau deja distribuiți uniform, maparea este aproape de identitate; acolo unde pixelii erau aglomerați la o anumită luminozitate, maparea îi distribuie întinzând acea luminozitate pe o gamă mai largă de valori de ieșire.

Rezultatul este spectaculos pe scenele cu contrast scăzut – diferența dintre o fotografie de interior slab iluminată și aceeași fotografie după histeq este adesea diferența dintre „ilizibil” și „perfect lizibil”. Compromisul este că operația amplifică totul, inclusiv zgomotul senzorului. Pe o scenă cu detalii reale de contrast scăzut de recuperat, histeq este răspunsul potrivit; pe o scenă curată, bine expusă, care pur și simplu nu are nevoie de el, histeq introduce zgomot vizibil.

5.19.2. CLAHE: egalizare adaptivă

Egalizarea histogramei este globală: folosește o singură CDF calculată din întreaga imagine și o aplică peste tot. Aceasta funcționează pe imagini a căror gamă de luminozitate este aproximativ uniformă, dar eșuează pe scene cu regiuni întunecate și luminoase localizate – CDF-ul este tras spre partea care are mai mulți pixeli, iar partea opusă este supracorectată.

Varianta adaptivă este Egalizarea Adaptivă a Histogramei cu Limitarea Contrastului, denumită în mod obișnuit CLAHE. În loc de o singură CDF globală, CLAHE calculează o CDF separată pentru fiecare dală mică a imaginii, egalizează fiecare dală în raport cu propria CDF și combină limitele dintre dale. Rezultatul este că ajustările de luminozitate au loc local – colțul aflat în umbră primește propria egalizare, fără ca colțul luminos să-l tragă în direcția greșită.

Indicatorul adaptive=True comută histeq() în modul CLAHE:

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

Parametrul clip_limit este partea din CLAHE la care se referă „limitarea contrastului” din denumire. Egalizarea locală poate supra-amplifica zgomotul în regiunile uniforme unde CDF-ul are foarte puține valori distincte; limita de plafonare limitează cât de agresiv poate fi redistribuit un singur compartiment, ceea ce previne amplificarea zgomotului permițând totodată întinderea contrastului acolo unde contează. O valoare în jur de 10 este un punct de plecare rezonabil; valorile mai mari permit CLAHE să lucreze mai intens cu prețul unui zgomot mai vizibil, valorile mai mici îl fac mai blând.

CLAHE este mai costisitor decât histeq global, dar produce rezultate mai curate pe scenele unde luminozitatea este distribuită neuniform – adică majoritatea scenelor din lumea reală.

5.19.3. Gamma, contrast și luminozitate

Egalizarea histogramei este metoda bazată pe date de a remapa luminozitatea. Metoda independentă de date este aplicarea unei curbe alese, parametrizată prin câteva butoane ușor de reglat. gamma() oferă trei:

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

Fiecare parametru aplică o transformare specifică fiecărui pixel:

gamma trece valoarea fiecărui pixel prin funcția de putere output = input ** (1 / gamma). Semnificația standard: valorile mai mari de 1.0 luminează imaginea și ridică tonurile medii (corecția clasică „gamma de monitor”); valorile mai mici de 1.0 o întunecă. Parametrul este neliniar – păstrează punctele de negru și de alb și remodelează doar distribuția dintre ele, ceea ce este comportamentul corect atunci când scopul este de a recupera detalii în regiunile de umbră sau de evidențiere fără a strivi extremele existente.

contrast trece fiecare pixel printr-o înmulțire directă în jurul punctului de gri mediu. Valorile mai mari de 1.0 cresc contrastul (întunericul devine mai întunecat, luminosul mai luminos, grisul mediu rămâne neschimbat); valorile mai mici de 1.0 reduc contrastul.

brightness adaugă o constantă la valoarea fiecărui pixel. Valorile pozitive luminează, valorile negative întunecă. Deplasarea este uniformă – nimic nu este păstrat – ceea ce rareori își dorește o aplicație de una singură, dar se combină bine cu o trecere de contrast pentru a recentra rezultatul.

Cei trei parametri se compun: un singur apel gamma() poate aplica o curbă gamma, apoi o înmulțire de contrast, apoi o deplasare de luminozitate, toate într-o singură trecere. Ordinea este mai întâi gamma, apoi contrast, apoi luminozitate, ceea ce corespunde ordinii care oferă cele mai intuitive rezultate atunci când toate trei sunt diferite de valorile implicite.

5.19.4. Echilibrarea automată a albului

Familia de corecții tonale de culoare începe cu echilibrarea automată a albului. Același mecanism pe care ISP-ul senzorului îl rulează ca parte a fluxului de procesare a imaginii – ajustarea amplificărilor relative pe canalele de roșu, verde și albastru astfel încât un petic de culoare gri medie să fie interpretat ca gri real – este disponibil și ca operație post-captură pe o Image finalizată:

img.awb()

Valoarea implicită folosește algoritmul gray-world: se presupune că culoarea medie a întregii imagini este gri neutru, iar amplificările per canal sunt ajustate pentru a face asta. Forma alternativă max=True folosește algoritmul white-patch: se presupune că pixelii cei mai luminoși sunt alb neutru, iar amplificările sunt ajustate pentru a face asta. Ambele funcționează pe RGB565 și pe Bayer brut; niciuna nu funcționează pe tonuri de gri (unde nu există culoare de echilibrat) sau YUV (unde reprezentarea culorii nu este cea pe care operează acești algoritmi).

Când să recurgi la forma post-captură în loc de echilibrarea automată a albului a ISP-ului: când alegerea ISP-ului a fost o potrivire slabă pentru scena particulară, când aplicația încarcă de pe disc cadre de referință care au fost capturate în condiții diferite sau când judecata de culoare contează suficient de mult încât aplicația dorește să o reia cu propria alegere de algoritm.

5.19.5. Matricea de corecție a culorii

Atunci când corecția de culoare de care are nevoie imaginea nu este scalarea per canal pe care o oferă echilibrarea albului, ci o amestecare de canale mai generală, operația la care trebuie să recurgi este matricea de corecție a culorii. Metoda ccm() aplică o matrice de 3 pe 3 (sau 3 pe 4 cu decalaj) care înmulțește vectorul (r, g, b) al fiecărui pixel pentru a produce un nou vector (r, g, b):

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

Matricea permite aplicației să corecteze interferența dintre canalele de culoare – acolo unde, de exemplu, răspunsul senzorului de roșu include puțină lumină verde, matricea poate scădea o fracțiune din canalul verde din ieșirea roșie pentru a compensa. Combinată cu un decalaj per canal, forma de 3 pe 4 permite aplicației să readucă la zero și fiecare canal.

Materialul fluxul de procesare ISP acoperă de ce-ul matricelor de corecție a culorii. Forma post-captură de pe Image este pur și simplu aceeași operație, aplicată după fapt.