IN3370 h?st 2024 - L?sningshint 3

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.

  1. 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].)
  2. Fra forelesningsnotatet s.21. f_min=50, f_max=150, g_min=0, g_max=255. T[i] = 2.55i - 127.5.
  3. 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).
  4. 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.
  5. 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
Legg merke til at kodesnutten over konverterer ikke til heltallige pikselverdier, ei heller klipper til verdier mellom 0 og 255.

Oppgave 4 - Ikke-line?re, parametriske transformer

  1. ..
  2. Logaritmisk. Fremhever kontrasten i lavintensitets-omr?det.
  3. 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)]

 

Publisert 10. sep. 2024 09:05 - Sist endret 10. sep. 2024 09:05