Å variere lysstyrken til bilder med numpy

Denne posten er del 6 av 7 i serien Bildebehandling med python i vgs

En vanlig måte å redigere bilder på er å gjøre de lysere eller mørkere. Det vil bety å flytte verdier sideveis i histogrammet. En naiv strategi vil være å legge en fast verdi til hver piksel.

b = lesBilde("cameraman.png")
c = b+50
visBildeOgHistogram(c)
Alle pikselverdiene er økt med 50, bildet blir lysere, men de lyseste verdiene «brettes rundt» og blir mørke.

I lesBilde-funksjonen blir matrisens type satt til uint8 (unsigned integer 8 bit), som er hele tall mellom 0 og 255. Når en verdi over 205 får lagt til 50, blir verdien tatt modulo 255. For eksempel blir 230 + 50 = 280 ≡ 25 mod 255. De aller lyseste verdiene blir svarte.

Gammakorreksjon

En bedre løsning vil være å gjøre som for histogramutjevningen, lage en funksjon som tilordner hver piksel en ny verdi. Den funksjonen vil ligne på et kumulativt histogram. For å gjøre bildet lysere, må de mørkeste pikslene strekkes opp og de lyseste komprimeres.

En slik mulig funksjon som holder verdiene mellom 0 og 255, er \(I’ = \left(\frac{I}{255}\right)^\gamma \cdot 255\). For hver piksel blir intensiteten delt på maks, som gir et desimaltall mellom 0 og 1. Dette desimaltallet opphøyes i en verdi \(\gamma\). Dersom \(\gamma\) er større enn 1, blir de mørke verdiene enda mørkere, og dersom \(\gamma\) er mindre enn 1, blir de lyse verdiene enda lysere. Men alle verdiene holder seg fremdeles mellom 0 og 1.

Denne typen justering blir gjort i opptak av video og bilder, siden øyets følsomhet varierer tilnærmet logaritmisk. Det trengs mer informasjon blant et lite område høye lysstyrker.

Flere gammakurver,
def gammaKorriger(bilde, gamma):
    ut = (bilde/255)**(1/gamma) * 255
    return ut.astype("uint8")

Å gjøre bildet lysere kan en for eksempel gjøre som under, hvor \(\gamma\) er lik 2,5.

Pikslene er stort sett lysere, og ingen har verdi over 255.

Om en mot formodning ville gjøre dette bildet mørkere, kan en sette \(\gamma\) til f.eks. 0,4.

Mange piksler er i utgangspunktet mørke, og blir etter korrigeringen satt til 0.

Tilsvarende justeringer kan en gjøre med ulike funksjoner som har definisjonsmengde [0, 255] og verdimengde [0, 255]. For å bevare egenskapene til bildet best mulig, bør funksjonen være voksende. I mange billedbehandlingsprogram kan en justere kurven til funksjonen på frihånd.

Eksempel fra Gimp, med manuelt justert kurve.

Eksempler

Tre ulike kurver, som gir ulike effekter.
Den blå S-formede kurven fremhever detaljer i de mellomgrå tonene som i gresset, og slår sammen de lyseste og mørkeste tonene.
Den oransje kurven med et tydelig «platå» i midten, verdiene i et stort intervall blir satt til den verdien. Om bildet stort sett bare hadde mørke og lyse piksler ville det ha fremhevet detaljer i de.
Den grønne kurven snur bildet, som et gammeldags negativ.

Oppgaveforslag

  • Lag en funksjon som øker verdien med en lineær funksjon, \(a \cdot x + b\). Om verdiene går over 255 eller under 0, sett de til 255 eller 0. Hvilken effekt har \(a\) og \(b\)?

Serienavigasjon<< Matrisefiltre i bildebehandlingSteganografi, skjult informasjon i et bilde >>

Underviser i matematikk, fysikk og naturfag på Tryggheim vgs.