Julia - Obrada slike - Izoštravanje slike

In [2]:
# U okviru ove lekcije obradićemo algoritme za pojačavanje ivica kod objekata i videćemo šta se dešava 
#ukoliko na tako obrađenu sliku primenimo neki od filtara za uklanjanje šuma, kao i kakav
#će biti efekat ako na već filtriranu
#sliku budemo primenili nekakav algoritam za izoštravanje ivica
In [3]:
#Prirodno, ivica predstavlja nekakvu naglu promenu na slici, pa bi intuitivno sa time bilo logično da se ona
#možda može detektovati korišćenjem prvog izvoda signala, budući da je on 
#matematički operator koji ima za cilj procenu
#promene trenda neke matematičke funkcije

#Sada, izvod će na "uniformnim regionima" zaista imati vrednost 0, a prilikom promene 
#regiona će imati neke velike vrednosti
#pa bi ovakvo rešenje delovalo da može da daje dobre rezultate. 

#Međutim, jedan od potencijalnih problema predstavljaju velike amplitude šuma na našim slikama, koje mogu poremetiti rad
#ovakvog algoritma - detekcija nečega što nije ni ivica, ili propuštena detekcija

#Umesto toga, bolju ocenu o tome gde je ivica može nam dati drugi izvod funkcije, kao pratilac promene trenda prvog 
#izvoda - a nama je takva problematika da moramo istovremeno
#vršiti i diferenciranja po jednoj i po drugoj promenljivoj

#Ovde ćemo dati postupak izoštravanja slike korišćenjem Laplasijana:. Laplasijan će nam dati dobru ocenu o tome
#gde se nalaze prelazi između objekata i on će izvršiti dodatno pojačanje 
#tih prelaza (ekv. izvršiće pojačanje visokih
#učestanosti) kako bi se što bolje izvršile ivice

#najčešće korišćene maske za Laplasijan su:
lap2 = [1 1 1; 1 -8 1; 1 1 1];
lap1 = [0 1 0; 1 -4 1; 0 1 0];
#ove aproksimacije su dobijene iz formula za aproksimaciju Laplasijana, 
#pa se iz jednačina dobija da zbir ovih faktora
#koji čine maske mora biti jednak 0
In [4]:
using Images, TestImages,ImageFiltering
In [5]:
img = load("slikaizo2.jpg")
Out[5]:
In [9]:
#Algoritam se sastoji u sledećem:

#1. Računamo Laplasijan naše matrice - dobijamo inf. o tome gde treba vršiti pojačanje
#2. Vršimo množenje Laplasijana nekom konstantom c - konstanta 
#c treba da bude suprotnog znaka od znaka centralnog elementa
#3. Oduzimanje dobijenog proizvoda od originalne slike

c = 0.2;  #menjanjem parametra c dobijaće se različiti rezultati - voditi računa o njegovom znaku i vrednosti
sl1_lap = imfilter(img, lap1, "symmetric");
sl1_rez = img  - c * sl1_lap;

mosaicview(img, sl1_rez; nrow = 1)
┌ Warning: `mosaicview(A1::AbstractArray, A2::AbstractArray; kwargs...)` is deprecated, use `mosaic(A1, A2; kwargs...)` instead.
│   caller = ip:0x0
└ @ Core :-1
Out[9]:
In [61]:
#Druga aproksimacija Laplasijana, data sa lap2, daće još izaženije rezultate nego lap1
sl1_lap2 = imfilter(img, lap2, "symmetric");
sl1_rez2 = img  - c * sl1_lap2;
mosaicview(img, sl1_rez2; nrow = 1)
Out[61]:
In [62]:
#Kao jedna od alternativa ovom postupku - postoji i algoritam za isticanje 
#visokih učestanosti (ivica predstavlja naglu
#promenu na našoj slici pa ona ima prirodu visokih učestanosti)

#1. Vršimo usrednjavanje slike - na taj način eliminišemo visoke komponente, pa samim time ivice
#2. Vršimo oduzimanje rezultata usrednjavanja od naše slike od originalne slike i na taj način dobijamo ivice
#3. Vršimo dodavanje ovih ivica na našu originalnu sliku - na taj način smo izvršili pojačavanje ivica

filt_usr = [1 1 1; 1 4 1; 1 1 1 ];
filt_usr = filt_usr / sum(filt_usr)
Out[62]:
3×3 Array{Float64,2}:
 0.0833333  0.0833333  0.0833333
 0.0833333  0.333333   0.0833333
 0.0833333  0.0833333  0.0833333
In [65]:
bez_ivica = imfilter(img, filt_usr, "symmetric");
samo_ivice = img - bez_ivica;
k = 2;  #u zavisnosti od k biramo koliko će biti pojačane naše ivice
sl_rez = img + k * samo_ivice;
mosaicview(img, sl_rez; nrow = 1)
Out[65]:
In [67]:
#Ukoliko bismo sada na ovakvu sliku primenili filtar koji vrši neki vid usrednjavanja, bez vođenja računa
#o tomme šta su ivice i različiti regioni slike, naš rezultat pojačavanja ivica biće poništen (zašto? Pa ovaj
#filtar bi vršio uklanjanje visokih učestanosti tj. brzopromenljivih komponenti, a to je baš ivica)

redukovane_ivice = imfilter(sl_rez, filt_usr, "symmetric");
mosaicview(img, redukovane_ivice; nrow = 1)
Out[67]:
In [68]:
#Zaista, kao da ništa nismo postigli ovim postupkom
In [70]:
#Analogno, ako bismo prvo uradili niskopropusno filtriranje sa ovakvim filtrom, pa onda postupak izoštravanja ivica
#opet ne bismo postigli ništa

usr_slika = imfilter(img, filt_usr, "symmetric");
usr_bez_ivica = imfilter(img, filt_usr, "symmetric");
samo_ivice = usr_slika - usr_bez_ivica;
k = 2;  
sl_rez = usr_slika + k * samo_ivice;
mosaicview(img, sl_rez; nrow = 1)
Out[70]:
In [71]:
#Rešenje ovakvog problema leži u filtrima koji uzimaju u obzir da li se 
#neki piksel nalazi na granici između dve oblasti
#Pogledati bilateralni filtar
In [ ]: