En type filter kan være å for hver piksel beregne en ny pikselverdi basert på verdiene rundt. Om en lar den nye verdien være gjennomsnittet av pikslene rundt, blir bildet mer uskarpt.
uskarp = np.array([[1,1,1],
[1,1,1],
[1,1,1]])/9 # Alle verdiene blir 1/9
utsnitt = b[60:63, 110:113] # Utsnittet gir en 3x3-matrise rundt b[61,111],
print(utsnitt) # som kan brukes til å beregne den nye verdien i b[61,111]
filtrert = utsnitt*uskarp # Hvert element blir multiplisert med elementet på samme plass i filteret
print(filtrert)
np.sum(filtrert) # Summen av alle elementene, som blir den nye verdien
[[ 82 133 166]
[ 64 190 176]
[ 35 148 151]]
[[ 9.11111111 14.77777778 18.44444444]
[ 7.11111111 21.11111111 19.55555556]
[ 3.88888889 16.44444444 16.77777778]]
127.22222222222223
For at en skal kunne beregne verdier også for pikslene langs kanten, lager vi en ramme rundt som kopierer kantverdiene ut. Som for utsnittet over.
utsnittRamme = np.pad(utsnitt, 1, mode="edge")
print(utsnittRamme)
[[ 82 82 133 166 166]
[ 82 82 133 166 166]
[ 64 64 190 176 176]
[ 35 35 148 151 151]
[ 35 35 148 151 151]]
Prosessen blir gjentatt for alle pikslene i bildet.
def konvolusjon(bilde, matrise):
x,y = bilde.shape
ut = np.zeros(bilde.shape)
bilde = np.pad(bilde, 1, mode="edge")
for i in range(x):
for j in range(y):
ut[i,j] = np.sum(bilde[i:i+3,j:j+3]*matrise)
return np.abs(ut.astype(int))
print(konvolusjon(øre, uskarp))
visBilde(konvolusjon(øre, uskarp))
[[ 9 9 14 26 36 33 21 11 9 9]
[ 9 16 30 46 50 43 27 16 9 9]
[ 10 33 64 91 80 57 29 17 10 9]
[ 15 54 99 126 96 63 33 25 14 11]
[ 20 66 119 144 112 80 65 59 39 19]
[ 22 66 117 136 111 99 107 109 72 35]
[ 20 61 107 121 95 97 127 142 95 46]
[ 19 56 95 123 95 101 116 137 92 47]
[ 20 45 86 126 116 112 111 121 89 54]
[ 20 35 79 132 144 132 117 115 92 63]]

def visBildeOgKonvolusjon(bilde, matrise):
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)
k = konvolusjon(bilde, matrise)
imgplot = plt.imshow(k, cmap="gray",vmin=0,vmax=255)
plt.axis("off")
visBildeOgKonvolusjon(b, uskarp)

Ulike filter
Ulike matriser kan gi ulike effekter.
# Forsterker kontraster
skarpere = np.array([[ 0,-1, 0],
[-1, 5, -1],
[ 0,-1, 0]])
# Gir inntrykk av lys fra øvre høyre hjørne
emboss = np.array([[-2,-1, 0],
[-1, 1, 1],
[ 0, 1, 2]])
# Kantgjenkjenning
omriss = np.array([[-1,-1,-1],
[-1, 8,-1],
[-1,-1,-1]])
visBildeOgKonvolusjon(b,skarpere)

visBildeOgKonvolusjon(b,emboss)

visBildeOgKonvolusjon(b,omriss)

Oppgaveforslag
- Utvid filterne over til 5×5-matriser, hva blir forskjellen?
- Lag et filter som erstatter pikselverdien med medianen til pikslene rundt. Sammenlign med gjennomsnitt.
- Sett så en del tilfeldige piksler til tilfeldige verdier, eller bruk dette bildet. Sammenlign gjennomsnittfilteret med medianen.