Histogramutjevning i Python

Husk da du så det lavkvalitetsbildet og følte deg litt skuffet? Det var ikke klart nok, og detaljene var litt uklar. Hva om du kunne forbedre bildet til en bedre versjon? Ville det ikke vært bra? Heldigvis er det en måte å gjøre det ved hjelp av Python!

En av metodene du kan bruke til å forbedre et bilde er histogramutjevning, som spesielt forbedrer kontrast av bildet. Nesten alle kamerasystemer bruker faktisk histogramutjevning for å gjøre bildene våre bedre, og på slutten av opplæringen vil du oppdage hvorfor dette er så.

I neste avsnitt vil jeg dype dypere inn i hva som menes med histogramutjevning og hva som skjer med bildet når du bruker metoden, og så ser vi hvordan vi kan implementere metoden i Python. Klar?

Histogramutjevning

La oss si at du har pout.jpg bildet (fortsett og last det ned). Dette er et demobilde som brukes i MATLAB, hvor jeg fikk det fra, men vi vil bruke det i opplæringen vår her. Bildet ser slik ut:

La oss se på hvordan vi kan få tilgang til pixelverdiene til bildet, referert til som intensiteter. Jeg skrev dette lille Python-skriptet som vi kan bruke til å gjøre nettopp det (legg merke til at jeg bruker OpenCV-biblioteket):

importere cv2 img = cv2.imread ('pout.jpg') img_shape = img.shape height = img_shape [0] width = img_shape [1] for rad i rekkevidde (bredde): for kolonne i rekkevidde (høyde): print [kolonne rad])

Det jeg gjør her, er å lese bildet vårt (pout.jpg), og deretter undersøke figurens form (størrelse). img_shape vil returnere: (1031, 850, 3). Dette betyr at bildet vårt er av høyde (antall kolonner) 1031, og med bredde (antall rader) 850, og har 3 kanaler (RGB). Legg merke til at den første parameteren i resultatet er høyden, og den andre parameteren er bredden. Til slutt løper vi gjennom radene og kolonnene og skriver ut de forskjellige pikselverdiene (intensiteter) i hvert rad / kolonnepar.

En prøve av utgangen er: [137 137 137]. Ja, jeg vet at du ventet en verdi som et resultat for pikselintensiteten. Vi har faktisk verdien av pikselintensiteten her, men hva resultatet viser oss er resultatet av den røde, grønne og blåen (RGB) kanaler. Vær imidlertid oppmerksom på at i OpenCV er bestillingen BGR, som dette er hvordan OpenCV laster bildet. Dermed inneholder ovennevnte prøveresultat verdien 137 for hver kanal i rekkefølgen til B, G, og R, henholdsvis.

Grunnen til introduksjonen er at histogramutjevning egentlig handler om modifikasjon av pikselintensiteter for å forbedre bildens kontrast. Dermed vil vårt hovedarbeid her være på pikselintensitetsnivået.

På dette punktet lurer du kanskje på hva en histogram er. Selv om begrepet noen ganger kan være litt forvirrende, er det faktisk et veldig enkelt konsept. Histogrammet er bare et diagram som viser antall piksler i et bilde ved hver intensitetsverdi som er funnet i bildet.

Siden pikslene våre har tre verdier, er en for hver av BGR-kanalene en måte å tegne histogrammet på å ha tre histogrammer, en for hver kanal, hvor x-aksen vil ha de forskjellige pikselverdiene (intensiteter) og y -aks vil vise hvor mange ganger (frekvens) den spesifikke pikselverdien dukket opp blant de forskjellige pikselverdiene.

For eksempel kan det røde kanalhistogrammet ha en pikselverdi på 137 på x-aksen, og y-aksen kan vise hvor mange piksler som har denne verdien for den røde kanalen, for eksempel, 86. Så måten vi leser det er ved å si at pikselverdien for den røde kanalen på 137 dukket opp i 86 piksler, eller har gjentatt 86 ganger i bildet vårt.

Ved å bruke koden fra denne bildehistogramartikkelen for å tegne histogrammet for bildet, får vi følgende:

Histogrammet er faktisk for de røde, grønne og blå kanalene. La oss ta en liten prøve av utdataene du vil få fra den forrige koden, som vist nedenfor. Dette viser at kanalverdiene synes å alltid være de samme, og de tre forskjellige linjene vil således ha de samme verdiene og bli tegnet ovenpå hverandre, som vises som bare en linje.

[101 101 101] [101 101 101] [100 100 100] [98 98 98] [94 94 94] [95 95 95] [97 97 97] [99 99 99] [100 100 100] [95 95 95] [93 93 93]

Hva histogramutjevningsmetoden vil gjøre for histogrammet ovenfor, er at det vil forandre intensitetsverdiene på en måte som vil gjøre histogrammet ser ut smigre i det resulterende bildet. Med andre ord, er histogramutjevning en metode som justerer bildens intensiteter for å forbedre kontrasten i bildet.

Histogrammet ovenfor ser litt konsentrert mot midten av figuren, og hva histogramutjevning vil gjøre, er å distribuere pikselintensitetsverdiene ytterligere for å få et mer flatet histogram.

Jeg tror det er nok om histogramutjevning for å diskutere her, da vi ikke vil bli mer matematiske i denne opplæringen, særlig siden det handler om implementeringen av metoden i Python. Du kan imidlertid sjekke disse notatene som viser de forskjellige formlene som er involvert i metoden: histogramutjevning. Så nå lar vi dykke inn i implementeringen!

Histogramutjevning i Python

I denne delen vil jeg vise deg hvordan du implementerer histogramutjevningsmetoden i Python. Vi vil bruke bildet ovenfor (pout.jpg) i våre eksperimenter. La oss gå gjennom prosessen trinnvis. Det første vi må gjøre er å importere OpenCV- og NumPy-biblioteker, som følger:

importer cv2 import numpy

Etter det trenger vi bare å lese bildet vårt, pout.jpg:

img = cv2.imread ('pout.jpg')

Den gode nyheten er at OpenCV gir oss en funksjon der vi kan bruke histogramutjevning på et bilde, nemlig equalizeHist (). Det er greit å bruke denne funksjonen på et gråtonebilde som metoden faktisk utligner histogrammet til a gråtoner bilde, men i vårt tilfelle har vi tre kanaler (RGB) for hver piksel, og vi kan ikke bruke histogramutjevning på de tre kanalene på egen måte.

En fin løsning jeg kom over i boken Python: Real World Machine Learning er å konvertere bildet vårt til YUV-fargeplassen, utjevne Y kanal, og endelig konvertere resultatet til RGB. Så det første vi gjør er å konvertere vårt bilde til YUV. Dette kan gjøres ved hjelp av metoden cvtColor (), som konverterer bildet fra en plassfarge til en annen, som følger:

img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV)

Legg merke til at vi bruker BGR i stedet for RGB her, siden OpenCV (som nevnt tidligere) laster bildene inn BGR format.

Vi bruker nå histogramutjevningsmetoden på Y kanal ved hjelp av equalizeHist () metoden:

img_to_yuv [:,:, 0] = cv2.equalizeHist (img_to_yuv [:,:, 0])

Endelig konverterer vi Y kanal til RGB (BGR i OpenCV), som følger:

hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR)

Gratulerer! Du har nå brukt histogramutjevning til bildet. I neste avsnitt vil jeg sette all koden sammen og vise deg hvordan bildet vårt vil se ut etter å ha brukt histogramutjevning.

Sette alt sammen

La oss sette alt vi har lært sammen. Python-skriptet for å bruke histogramutjevning på pout.jpg ser slik ut:

import cv2 import numpy img = cv2.imread ('pout.jpg') img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV) img_to_yuv [:,: 0] = cv2.equalizeHist (img_to_yuv [:,: 0]) hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR) cv2.imwrite ('result.jpg', hist_equalization_result)

Utgangen av det ovennevnte skriptet er følgende bilde:

For å merke forskjellen bedre, vil jeg sette de to bildene ved siden av hverandre (venstre: originalbilde; høyre: resultat av histogramutjevning):

Har du merket forskjellen? Det rette bildet ser mye klarere enn det opprinnelige bildet. Ikke rart hvorfor nesten alle bildesystemer utfører histogramutjevning!

Før vi pakker opp, la oss se hva histogrammet til resultatet ser ut som:

Hvis du sammenligner histogrammet til det resulterende bildet med histogrammet til det opprinnelige bildet, vil du legge merke til at histogrammet til det resulterende bildet er flattere enn histogrammet til det opprinnelige bildet, og dette er nøyaktig hva histogramutjevningsmetoden gjør.

Konklusjon

I denne opplæringen så vi hvordan vi kan forbedre kontrasten til et bilde ved hjelp av en metode som kalles histogramutjevning, og hvordan det er enkelt å implementere ved hjelp av Python og OpenCV.

Resultatet var veldig interessant som det var mye klarere enn det opprinnelige bildet, og resultatets histogram var flattere enn histogrammet til det opprinnelige bildet, og viste en bedre fordeling av pikselintensitetsverdier over bildet.

Til slutt, ikke nøl med å se hva vi har tilgjengelig for salg og for studier i Envato Market, og vær så snill å stille spørsmål og gi din verdifulle tilbakemelding ved å bruke feedet under.