Oppgave 1 - Programmering av histogramfunksjon
import numpy as np import matplotlib.pyplot as plt def my_hist(im, G): N, M = im.shape h = np.zeros([G]) for i in range(N): for j in range(M): v = im[i, j] h[v] += 1 return h # Lag et "dummy-bilde" med tilfeldige tall im = np.floor(np.random.random([128, 128])*256).astype(int) # Beregn histogrammet med v?r splitter nye funksjon h = my_hist(im, 256) # Plot histogrammet som et stolpediagram plt.bar(range(256), h) plt.xlabel('pikselverdi') plt.ylabel('antall') plt.show()
Oppgave 2 - Line?r gr?tonetransform
Anta at et bildet har middelverdi lik 100 og varians lik 400, alts? μ = 100 og σ^2 = 400.
- Middelverdi ikke langt unna midten av 8-bits intervallet, dvs ca. 127, alts? trolig et rimelig balansert bilde mhp lysheten. Varians p? 400 vil si et standardavvik p? sqrt(400)=20, alts? noe lav kontrast i bildet. (Hadde pikselintensitetene v?rt normalfordelt ville ca. 95% av pikselene v?rt innenfor intervallet [100-2*20,100+2*20]=[60,140].)
- Fra forelesningsnotatet s.21. f_min=50, f_max=150, g_min=0, g_max=255. T[i] = 2.55i - 127.5.
- Fra notater s.26. a=2, b=10. My_t = a*μ + b = 210. Varians_t = a^2*σ^2 = 4*400 = 1600. (Firedobler variansen, dobler standardavviket).
- L?s for a og b i ligningene 128 = a*100 + b og 64^2 = a^2*400. Dette skal gi at a = 64/20, b = 128-a*100.
- Se notater s.29. Sigma_t = 2^10 / 4 = 1024/4=256. My_t = 1024/2 = 512. Deretter samme fremgangsm?te som i oppg. d)
Oppgave 3 - Programmering av line?r gr?tonetransform
Legg merke til bevaring av histogrammets "form", samt evt hvor mange av pikslene som man ser blir (eller b?r bli) klippet (til ? forbli innenfor 0-255).
import numpy as np def transform_mean_std(img, m_t, sigma_t): m_img = np.mean(img) sigma_img = np.std(img) a = sigma_t/sigma_img b = m_t - a*m_img return img * a + b
Oppgave 4 - Ikke-line?re, parametriske transformer
- ..
- Logaritmisk. Fremhever kontrasten i lavintensitets-omr?det.
- Ved ? putte inn transformen T[i] = i^(1/5) ser vi at vi ender opp med en (skalert) identitets-avbildning.
Oppgave 6 - Oppgave 3.6 i DIP
Ved histogramutjevning benytter vi en ren, global gr?tonetransform. Alts? har vi en funksjon T, som for alle intensiteter i gir oss en ny intensitet T[i]. Og det er ogs? alt vi har tilgjengelig.
Om vi generelt skal sikre oss et helt flatt histogram, m? vi kunne "brekke" opp noen av v?re histograms?yler. ? "brekke" opp en histograms?yle for intensitet i betyr at noen av pikslene med denne intensiteten m? f? en annen transformert verdi enn de resterende pikslene. Dette bryter med at alt vi har er en funksjon T som transformerer _alle_ piksler likt.
Oppgave 7 - Programmering av histogramutjevning
G = 256 # Antar 8-bit # Finn innbildets histogram h = my_hist(im, G) # Jfr ukeoppgave forrige uke # Finn det normaliserte, kumulative histogrammet: c = np.cumsum(h) / np.sum(h) # Transformen er gitt som en skalert versjon av c T = np.floor(c * (G-1)) # Transformer pikslene med tabelloppslag im_out = T[im.astype(int)]
Husk at man kan ogs? benytte histogramtilpasnings-algoritmen som ettersp?rres i Oppgave 8, og hvor q er en konstant funksjon [q = np.ones(256)/256].
Oppgave 8 - Programmering av histogramtilpasning
def histogramtilpass(img, q, G): # im <- innbilde med G graatoner # q <- oensket normalisert histogram # Finn innbildets normaliserte, kumulative histogram h = my_hist(img, G) # Jfr oppgave uke 2 c = np.cumsum(h) / np.sum(h) # Finn det oenskede kumulative histogrammet cq = np.cumsum(q) # Lag transformen T = np.zeros(G) for i in range(G): T[i] = np.argmin(np.abs(c[i] - cq)) # Anvend T paa hver piksel og returner resultatet return T[img.astype(int)]