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)]