Histogram fra bilder

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

Et histogram over pikselverdiene vil vise hvor stor kontrast det er i bildet. Et bilde med mange like gråtoner vil ha topper i histogrammet. Bildet av kameramannen har en veldig mørk frakk og stort sett middels gråtoner over hele. Det er nesten ikke lyse gråtoner i bildet.

def lagHistogram(bilde):
    '''
    Denne funksjonen er en fin oppgave for en elev å lage.
    '''
    x,y = bilde.shape
    h = [0]*256
    for i in range(x):
        for j in range(y):
            h[bilde[i,j]] += 1
    return np.array(h)

def visBildeOgHistogram(bilde):
    h = lagHistogram(bilde)
    fig = plt.figure(figsize=(12,6))
    a = fig.add_subplot(1, 2, 1)
    imgplot = plt.imshow(bilde, cmap="gray",vmin=0,vmax=255)
    plt.axis("off")
    a = fig.add_subplot(1, 2, 2)
    plt.bar(range(256),h,)

visBildeOgHistogram(b)

Histogramutjevning

Om histogrammet er tilnærmet vannrett, er intensitetene jevnt fordelt i bildet. Det kan fremheve detaljer i områder som har lite kontrast.

def kumulativtHistogram(bilde):
    '''
    Også en fin oppgave for elever.
    '''
    h = lagHistogram(bilde)
    x,y = bilde.shape
    ut = np.zeros(255)
    ut[0] = h[0]
    for i in range(1,255):
        ut[i] = ut[i-1] + h[i]
    
    ut = ut/(x*y)*255   # Verdiene gjøres om til 0 - 255. 
    return ut

kh = kumulativtHistogram(b)
plt.plot(kh)
plt.xlabel("Intensitet i det opprinnelige bildet")
plt.ylabel("Intensitet i det utjevnede bildet")
plt.show()

I bildet inn ser vi de mange mørke pikslene i frakken som den bratte stigningen mellom ca 10 og ca 20. Histogrammet viste det som en kraftig topp. Utjevningsalgoritmen gjør om intensiteten inn til verdien av det kumulative histogrammet. Verdiene inn mellom 10 og 20 blir til verdier ut mellom 0 og 50. De lysere pikslene mellom ca 20 og 100 er det færre av, og de blir til verdier mellom ca 50 og 70.

def histogramUtjevn(bilde):
    '''
    En utfordrende oppgave for elever.
    '''
    h = lagHistogram(bilde)
    x,y = bilde.shape
    kh = np.zeros(255)
    kh[0] = h[0]
    for i in range(1,255): 
        kh[i] = kh[i-1]+h[i]
    
    kh = kh/(x*y)*255  
    
    bn = np.zeros(bilde.shape)
    for i in range(x):
        for j in range(y):
            bn[i,j] = kh[int(bilde[i,j])]

    return bn.astype(int)

def visBildeOgUtjevnetHistogram(bilde):
    h = lagHistogram(bilde)
    fig = plt.figure(figsize=(12,12))
    a = fig.add_subplot(2, 2, 1)
    imgplot = plt.imshow(bilde, cmap="gray",vmin=0,vmax=255)
    plt.axis("off")
    a.set_title('Før')
    
    jevnet = histogramUtjevn(bilde)
    a = fig.add_subplot(2, 2, 3)
    plt.bar(range(256),h)
    
    
    hj = lagHistogram(jevnet)
    a = fig.add_subplot(2, 2, 2)
    imgplot = plt.imshow(jevnet, cmap="gray",vmin=0,vmax=255)
    plt.axis("off")
    a.set_title('Etter')
    a = fig.add_subplot(2, 2, 4)
    plt.bar(range(256),hj)

visBildeOgUtjevnetHistogram(b)

Det utjevnede histogrammet har helt jevn fordeling av intensitetene.

plt.plot(kumulativtHistogram(histogramUtjevn(b)))
plt.show()
Serienavigasjon<< matplotlib og numpy i bildebehandlingKantgjenkjenning i bilder med deriverte >>

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