Suodatusoperaatioita käytetään kuvien parantamiseen ja muutteluun, kuten yksityiskohtien voimistamiseen tai hävittämiseen. Suodatuksessa kuvapikseleille lasketaan uusi arvo niiden vanhan arvon, sekä ympäröivien pikseleiden arvojen perusteella. Spatiaalitasossa suodatus tapahtuu matemaattisesti kaksiulotteisen korrelaation tai konvoluution avulla, jossa korreloidaan alkuperäistä kuvamatriisia pienen maskin kanssa. Kun suodatettuja kuvia ja suodattamattomia kuvia yhdistetään aritmeettisten operaatioiden avulla saadaan laaja skaala erilaisia modifioituja kuvia, joista monet voivat olla käyttötarkoitukseen paremmin soveltuvia kuin alkuperäiset.
Maski
Suodatusoperaatioiden keskeinen termi on maski. Maski on kuvan kokoon nähden yleensä pieni (esimerkiksi 3x3), jonka alueella olevista pikselien arvoista tavalla tai toisella lasketaan maskin keskipisteen uusi arvo. Maskeja on eritarkoituksiin hyvin erilaisia.
Lineaarinen suodatus
Matlabissa kuvien suodatus käyttäen konvoluutiota tai korrelaatiota tapahtuu imfilter funktiolla. Funktio saa parametreinaan suodatettavan kuvan ja suodatinmaskin. Näiden lisäksi on mahdollista antaa vielä lisää parametreja, joilla voidaan määritellä mm. suodatuksen käyttäytyminen kuvan reuna-alueilla ja se, käytetäänkö konvoluutiota vai korrelaatiota. Oletusarvoisesti kuvan reunoja jatketaan suodatuksen mahdollistamiseksi nollilla, mikä saattaa aiheuttaa suodatettuun kuvaan kapeat tummat reunat.
Keskiarvosuodatus
Aloitetaan kuvien suodatus yksinkertaisimmasta tapauksesta, eli keskiarvoistavasta alipäästösuotimesta. Keskiarvosuodatuksella pehmennetään kuvaa laskemalla jokaiseen pisteeseen aritmeettinen keskiarvo ympäröivistä pisteistä. Se kuinka suurelta alueelta keskiarvo lasketaan vaikuttaa olennaisesti tulokseen. Mitä suuremman alueen keskiarvoa lasketaan sitä enemmän kuva pehmenee ja yksityiskohdat häviävät.
Käytännössä kuvan päällä kuljetetaan maskia niin, että se käy läpi kaikki kuvan pikselit. Maskin koko määrää keskiarvoistettavien pikselien määrän. Keskiarvo lasketaan summaamalla maskin alle jäävät arvot yhteen ja jakamalla tulos maskin koolla. Tässä suodatuksessa huonona puolena on se, että kuvan yksityiskohdat ja reunat himmenevät.
Esimerkki
Luodaan 3x3 maski, jonka kaikilla alkioilla on sama arvo. Kun halutaan säilyttää kuvan keskimääräinen intensiteetti ennallaan on kertoimien (eli maskin alkioiden) summan oltava yksi. Helpoimmin tällaisen maskin saa aikaan tekemällä ensin ones funktiolla maski, jonka alkioiden arvot ovat ykkösiä ja jakamalla tämä maski alkioiden lukumäärällä. Luodaan maski h1 ja tehdään suodatettu kuva average kohdistamalla suodatusoperaatio alkuperäiseen kuvaan A.
h1 = ones(3,3)/9;average = imfilter(A, h1);
Suodattimien teko
Ensimmäinen keskiarvoistavan suotimen esimerkki oli melko triviaali, mutta jos nyt äkkipäätään pitäisi keksiä, että minkälaista maskia käyttämällä saisi esimerkiksi kuvan vaakasuuntaiset viivat korostumaan, niin voisi jo tulla vaikeuksia. Kuvankäsittelijälle oivallisia erityyppisiä 2-D suodattimia on onneksi kuitenkin paljon jo valmiiksi määriteltyinä korrelaatiomaskien muodossa. Näistä saa tehtyä fspecial funktiolla suoraan kuvaan sovellettavat maskit vaivatta.
Esimerkki
Tähän asti olen käyttänyt esimerkeissä pelkästään harmaasävykuvia, joten otetaan tällä kertaa vaihtelun vuoksi käsittelyyn RGB-värikuva ja katsotaan helpin avulla, mitä suodattimia fspecial meille tarjoaa.
unelma = imread('unelma.jpg');help fspecial;
Sen enempää erilaisten suodattimien käyttökohteita analysoimatta esitän nyt, miten muutamat näistä vaikuttavat unelma kuvaan. Tehdään ensin fspecial komennolla gaussian, ja motion tyyppiset suodatinmaskit ja suodatetaan alkuperäistä kuvaa niiden avulla.
Hgaussian = fspecial('gaussian',10,5) ;Hmotion = fspecial('motion',10,0); gaussianUnelma = imfilter(unelma, Hgaussian); motionUnelma = imfilter(unelma, Hmotion);
Matlabin työtilassa (workspace) yleensä vasemman ylänurkan tienoolla nähdään listattuna kaikki käytetyt matriisit. Sieltä havaitaan, että annetuilla parametreilla fspecial teki 10x10 Hgaussian ja 1x11 Hmotion maskit. Gaussian tyyppinen maski vaikutti kuvaan epätarkentavasti kun taas motion simuloi kameran vaakasuuntaista heilahdusta kuvanottohetkellä.
Reunan etsintä
Reuna on kahden värisävyltään huomattavasti toisistaan poikkeavan alueen raja. Kuvasta voidaan etsiä reunat ns. Sobelin gradientti-operaattoria käyttäen. Kuvan f(x,y) gradientti pisteessä (x,y) on vektori, jonka komponentit ovat osittaisderivaatat x:n ja y:n suhteen. Tämä gradienttivektori osoittaa suurimman muutoksen suuntaan pisteessä (x,y). Sobelin gradienttia laskettaessa käytetään kahta erilaista NxN maskia x:n ja y:n osittaisderivaattojen laskemiseksi. Ensimmäisellä lasketaan funktion osittaisderivaatta x:n suhteen ja jälkimmäisellä y:n suhteen. Käytännössä nämä kaksi matriisia ovat toistensa transpooseja.
Lopullista gradienttia approksimoidaan laskemalla osittaisderivaattojen itseisarvot yhteen. Gradientti lasketaan kuvan jokaiselle pikselille ja näin saadaan aikaiseksi gradienttikuva, joka osoittaa alkuperäisen kuvan eri alueiden reunaviivat. Tasaisen harmaasävyn alueilla gradientti saa arvon nolla, joka vastaa mustaa ja alueilla joissa muutos on voimakasta saadaan muita harmaasävyarvoja, jotka näkyvät gradienttikuvassa reunoina.
Esimerkki
Tehdään fspecial komennolla maski HsobelVertical ja transponoimalla tästä HsobelHorizontal ja katsotaan, miten ne vaikuttavat alkuperäiseen kuvaan unelma.
HsobelVertical = fspecial('sobel');HsobelHorizontal = HsobelVertical';VerticalSobelUnelma = imfilter(unelma, HsobelVertical);HorizontalSobelUnelma = imfilter(unelma, HsobelHorizontal);
Kuten arvata saattoi löysi HsobelHorizontal kuvasta pystysuuntaisia rajoja ja HsobelVertical vaakasuuntaisia. Yhdistelemällä edellä saatuja tuloskuvia voidaan tehdä ääriviivakuva sobelUnelma ja vaikkapa kuva, jossa alkuperäisestä kuvasta on vähennetty ääriviivakuva.
sobelUnelma = imAdd(VerticalSobelUnelma, HorizontalSobelUnelma);luovuutta = imSubtract(unelma, sobelUnelma);
Kuvan terävöittäminen
Terävöittämisen tarkoituksena on korostaa kuvan tarkkoja viivoja tai parantaa sumean kuvan yksityiskohtia. Terävöitys on pehmentämisen käänteisoperaatio, joka yleensä myös valitettavasti voimistaa kohinaa.
Terävöittämisen voi toteuttaa mm. jo analogisen valokuvan käsittelyyn kehitellyllä "unsharp masking" metodilla, jossa alkuperäisestä kuvasta vähennetään sumennettu kuva. Tämä sumennettu kuva voi olla esimerkiksi keskiarvoistusoperaatiolla tehty se. se sisältää matalat taajuudet ja korkeat taajuudet ovat vaimentuneet. Saadussa erotuskuvassa jäljellä ovat vain kohteiden väliset reunat ja muut nopeat harmaasävyjen muutokset. Tämän jälkeen erotuskuva lisätään alkuperäiseen kuvaan jolloin tulokseksi saadaan terävöitetty kuva.
Toinen tapa saada terävöitetty kuva on alipäästösuodatuksen käänteisoperaatio eli ylipäästösuodatus, joka voidaan tehdä vaikkapa Laplace-maskilla. Pelkkä ylipäästösuodatettu kuva ei ole hyvä, mutta kun se lisätään alkuperäiseen kuvaan saadaan lopputuloksena kuva, jonka korkeat taajuudet ovat korostuneet.
Esimerkki
Tehdään ensin fspecial funktiolla laplace maski ja suodatetaan sillä alkuperäinen kuva unelma. Lopuksi vielä lisätään ylipäästösuodatettu kuva alkuperäiseen imadd funktiolla.
Hlaplacian = fspecial('laplacian');laplacianUnelma = imfilter(unelma, Hlaplacian);sharpenedUnelma = imAdd(unelma, laplacianUnelma);
Epälineaarinen suodatus
Epälineaariset suotimet toimivat muuten kuten lineaarisetkin suotimet, mutta maskin keskipisteeseen laskettava uusi harmaasävyarvo ei ole lineaarikombinaatio maskin alla olevista pikseliarvoista. Yleisimpiä epälineaarisia suotimia ovat pikseliarvojen järjestykseen perustuvat maksimi-, minimi- ja yleisistä yleisin mediaanisuodin. Näiden järjestysfunktioon perustuvien epälineaaristen suodattimien yksi ominaisuus on, että ne eivät synnytä uusia pikseliarvoja, vaan maskin keskipisteeseen valitaan aina joku jo alkuperäisessäkin kuvassa oleva arvo.
Mediaanisuodatus
Keskiarvosuodatuksen haittana oleva kuvan reunojen häviäminen voidaan välttää käyttämällä mediaanisuodatusta. Sitä käytetäänkin yleensä kohinansuodatukseen. Tässä suodatuksessa jokaisen alkuperäisen kuvapikselin arvo korvataan pikselin ympäristön harmaasävyarvojen mediaanilla, eli keskimmäiseksi suurimmalla arvolla. Menetelmä toimii erittäin tehokkaasti, jos kuva on melko yhtenäinen harmaasävyarvoiltaan ja siinä esiintyy pikseleitä, joiden harmaasävyarvot poikkeavat ympäristöstään huomattavasti. Esimerkiksi jos 3x3 ympäristössä on seuraavat harmaasävyarvot (10, 20, 20, 20, 15, 20, 20, 25, 100) niin järjestettynä niistä saadaan (10, 15, 20, 20, 20, 20, 20, 25, 100) ja mediaaniarvoksi tulee 20. Mediaanisuodatuksen tarkoituksena on pakottaa huomattavasti poikkeavat harmaasävyarvot ympäristönsä kaltaiseksi. Harmaasävyt tasoittuvat sitä enemmän, mitä isompaa maskia käytetään.
Mediaanisuodin poistaa tehokkaasti kuvasta paikallisia ääriarvoja, kuten ns. suola ja pippurikohinaa kuitenkaan pehmentämättä ääriviivoja. Koska mediaanisuodatus ei ole lineaarinen operaatio, ei sitä myöskään voida toteuttaa minkään maskin painokertoimien avulla. Maskia käytetään toki mediaanisuodatuksessakin poimimaan pikseliä ympäröivien pisteiden arvot, joista mediaaniarvo sitten valitaan maskin keskipisteen uudeksi arvoksi.
Esimerkki
Matlabin IPT:sta löytyy valmiina medfilt2 funktio 2-ulotteiseen mediaanisuodatukseen. Tehdään kuvasta A mediaanisuodatettu versio 3x3 maskilla. Maskin dimensiot annetaan medfilt2 funktiolle kulmasulkeissa toiseksi parametriksi itse suodatettavan kuvan lisäksi.
medfilt = medfilt2(A, [3 3]);
Kaistanestosuodin
function uusi=Kaistanestosuodin(kuva, Alaraja, Ylaraja, taustanArvo) %I=imread('viisiviivaa.gif'); %imshow(I); u8=uint8(kuva); %figure, imshow(u8),title('u8'); u8Ek=Ekvalisaattori(u8); %laajentaa kuvan koko kirkkausalueelle uusi=u8Ek; figure,imshow(u8Ek), title('ekvalisoitu kuva u8-kuva'); [r,s]=size(u8Ek);%Mitataan rivien ja sarakkeiden määrä. for rivi = 1:r for sarake = 1:s if(u8Ek(rivi,sarake)<Ylaraja && u8Ek(rivi,sarake)>Alaraja) uusi(rivi,sarake)=taustanArvo; end end end %figure, imshow(uusi),title('uusi kuva'); end