Download - DIGITALNA OBRADA SLIKE
DIGITALNA OBRADA SLIKE
Softver za obradu slike
Ognjen Joldžić, 21/04Zlatko Dejanović, 16/04
Daniel Kurtjak, 50/04
2
Zadaci
• kreirati softver za obradu slike (rad sa binarnim slikama)• potrebne funkcije
- isjecanje
- brisanje
- invertovanje
- rotacija (za n*90°, slika u ogledalu)
- detekcija iskošenja i ispravljanje
- uklanjanje šuma• proizvoljna tehnologija za implementaciju
3
Proširenja osnovnog zadatka
• rad sa slikama u boji i sivim slikama
• rad sa histogramima
• morfologija
• dodavanje šuma
• konverzija tipova slika
• “undo” opcija
4
Osnovni koncepti implementacije
• C# (.NET 2.0)
• modularni pristup
• jednostavno unapređivanje
SlikaLib
Geometrijske operacije (Ognjen.dll)
Osnovni interfejs
Morfološke operacije (Zlatko.dll)
Detekcija zakrivljenja (SkewDetection.dll)
Filtriranje (Kurtjak.dll)
5
Podržani tipovi slika
• bmp
• jpeg
• png
• gif
• tiff
• moguća konverzija između svih tipova
6
Osnovni interfejs
Glavni prozor
Prozori za slike
7
SlikaLib
• biblioteka sa osnovnim klasama
• distribucija u vidu .dll datoteke
• objekti u osnovnoj klasi (Slika):- objekat klase Bitmap (.NET)
- width (int)
- height (int)
- ImgType (RGB, Gray, Binary)
- ostale vrijednosti (buffer, maxValue, minValue...)
8
Osnovne operacije
• Crop (isijecanje)
- zadržavanje selektovanog dijela slike
Slika rez = new Slika(sirina, visina, original.ImageType); for (int i = ax, m = 0; i < ax + sirina; i++, m++) for (int j = ay, n = 0; j < ay + visina; j++, n++) if (original.ImageType == imgType.rgb) rez.setPixelRGBAt(m, n, original.getPixelRGBAt(i, j)); else rez.setPixelAt(m, n, original.getPixelAt(i, j)); return rez;
9
Osnovne operacije
• Cut
- funkcija “suprotna” crop
- selektovani dio slike se odbacuje
• Negativ
- kreiranje inverzne slike
- zavisi od tipa (u boji, siva, binarna)
10
Osnovne operacije
• Rotacija za n*90°
- n=±1
- promjena dimenzija slike
• Slika u ogledalu (flip)
- u odnosu na vertikalnu osu
- u odnosu na horizontalnu osu
- dimenzije slike su iste
11
Osnovne operacije
• Konverzija broja boja
- RGB -> Siva -> Binarna
- obrnuta konverzija nije moguća
- neke funkcije moguće samo za određeni tip slike
- jednostavni algoritmi za konverziju
12
Matematička morfologija
• Strukturni element
- opis
- podešavanje
- struktura u memoriji
- primjer osnovnog strukturnog elementa:
(-1,-1), (-1,0), (-1,1), (0,-1), (0,0), (0,1),
(1,-1), (1,0), (1,1)
13
Matematička morfologija
• Dilatacija
- proširivanje slike
- osnovne ideje realizacije
- funkcije getFirst() i hasNext()
- rubni pikseli
- smještanje rezultata
14
Matematička morfologijapublic static Slika dilatacija(Slika slika){ if ((strElement != null) && (strElement.hasElement())) { Slika copy = slika.getImgCopy(); Slika s = new Slika(copy.Width, copy.Height, imgType.binary); for (int i = 0; i < s.Width; i++) for (int j = 0; j < s.Height; j++) s.setPixelAt(i, j, 1); for (int i = 0; i < copy.Width; i++) for (int j = 0; j < copy.Height; j++) if (copy.getPixelAt(i, j) == 0) { element e = strElement.getFirst(); if (!(((e.x + i) < 0) || ((e.x + i) >= copy.Width) || ((e.y + j) < 0) || ((e.y + j) >= copy.Height))) s.setPixelAt((e.x + i), (e.y + j), 0); while (strElement.hasNext()) { e = strElement.getNext(); if (!(((e.x + i) < 0) || ((e.x + i) >= copy.Width) || ((e.y + j) < 0) || ((e.y + j) >= copy.Height))) s.setPixelAt((e.x + i), (e.y + j), 0); } } slika = s; } else { MessageBox.Show("Strukturni element je prazan skup! Postavite strukturni element.", "Greška"); } return slika;}
15
Matematička morfologija
• Erozija
- eliminisanje rubnih piksela slike
- osnovne ideje slične kao kod dilatacije
- uvođenje logičke promjenljive flag koja određuje da li će piksel biti iscrtan
16
Matematička morfologijapublic static Slika erozija(Slika slika){ if ((strElement != null) && (strElement.hasElement())) { Slika copy = slika.getImgCopy(); Slika s = new Slika(copy.Width, copy.Height, imgType.binary); for (int i = 0; i < s.Width; i++) for (int j = 0; j < s.Height; j++) s.setPixelAt(i, j, 1); for (int i = 0; i < copy.Width; i++) for (int j = 0; j < copy.Height; j++) if (copy.getPixelAt(i, j) == 0) { bool flag = true; element e = strElement.getFirst(); if (!(((e.x + i) < 0) || ((e.x + i) >= copy.Width) || ((e.y + j) < 0) || ((e.y + j) >= copy.Height))) if (copy.getPixelAt((e.x + i), (e.y + j)) == 1) flag = false; while (strElement.hasNext()) { e = strElement.getNext(); if (!(((e.x + i) < 0) || ((e.x + i) >= copy.Width) || ((e.y + j) < 0) || ((e.y + j) >= copy.Height))) if (copy.getPixelAt((e.x + i), (e.y + j)) == 1) { flag = false; break; } } if(flag) s.setPixelAt(i, j, 0); } slika = s; } else { MessageBox.Show("Strukturni element je prazan skup! Postavite strukturni element.", "Greška"); } return slika;}
17
Matematička morfologija
• Primjer (original, dilatacija, erozija):
18
Matematička morfologija
• Otvaranje
- erozija + dilatacija istim str.el.
public static Slika otvaranje(Slika s)
{
return dilatacija(erozija(s));
}
19
Matematička morfologija
• Zatvaranje
- dilatacija + erozija istim str.el.
public static Slika zatvaranje(Slika s)
{
return erozija(dilatacija(s));
}
20
Filtriranje
• Filteri
- uniformni
- Gausov
- median
- Laplasov
• Šumovi
- salt & pepper
21
Filtriranje
• osnovne ideje
• obraćanje pažnje na rubne piksele funkcijom getImgBoundary()
• analogija sa Matlab-om u realizaciji funkcija imFilter() i fSpecial()
• podrazumijevani parametri
Filtriranje
22
Salt & Paper Average Gauss Median Laplacian
Filtriranje public static Slika imFilter(Slika slika, float[,] kernel, int sirina, int visina, string ivicniTip)
{
...
for (int i = 0; i < copy.Width; i++)
for (int j = 0; j < copy.Height; j++)
{
float[,] f = getImgBoundary(copy, sirina, visina, i, j, ivicniTip);
float sum = 0;
for (int ii = 0; ii < sirina; ii++)
for (int jj = 0; jj < visina; jj++)
sum += f[ii, jj] * kernel[ii, jj];
}
...
return slika;
}
public static float[,] getImgBoundary(Slika slika, int sirina, int visina, int red, int kolona, string ivicniTip)
{
if (ivicniTip.Equals("zeros"))
{. . .}
else if (ivicniTip.Equals("symmetric"))
{. . .}
else if (ivicniTip.Equals("replicate"))
{. . .}
else if (ivicniTip.Equals("circular"))
{. . .}
return retValue;
}
23
24
Filtriranje
public static float[,] fSpecial(string type, int width, int height, float sigma, float alpha)
{ float[,] f = new float[width, height]; if (type.Equals("average")) {. . .} else if (type.Equals("laplacian")) {. . .} else if (type.Equals("gaussian")) {. . .}
return f;}
25
Filtriranje• Median filtarpublic static Slika medfilt2(Slika slika, int sirina, int visina, string boundaryType) { slika.makeBuffer(); Slika copy = slika.getImgCopy(); for (int i = 0; i < copy.Width; i++) for (int j = 0; j < copy.Height; j++) { float[,] f = getImgBoundary(copy, sirina, visina, i, j, boundaryType); for (int ii = 0; ii < sirina * visina - 1; ii++) for (int jj = ii; jj < sirina * visina; jj++) if (f[ii / sirina, ii % sirina] > f[jj /sirina, jj % sirina]) { float tmp = f[ii / sirina, ii % sirina]; f[ii / sirina, ii % sirina] = f[jj / sirina, jj % sirina]; f[jj / sirina, jj % sirina] = tmp; } slika.setPixelAt(i, j, f[sirina / 2, visina / 2]); } return slika; }
26
Filtriranje• Salt & pepper šum public static Slika imNoise(Slika s, string noiseType, float freq) { if (noiseType.Equals("salt & pepper")) { int f = (int)(freq * 100); Random r = new Random(); for (int i = 0; i < s.Width; i++) for (int j = 0; j < s.Height; j++) { int rdm = r.Next(0, 100); if (rdm < f / 2) s.setPixelAt(i, j, 0); else if (rdm >= (100 - f / 2)) s.setPixelAt(i, j, 1); } return s; } throw new Exception("Nije dobar parametar"); }