Aritmetika slike

Aritmetika slike je proces u kome uzimate dve slike istih dimenzija, obavite računicu na njihovim kanalima boja i dobijete novu rezultatntnu sliku koja je njihova kombinacija. Ove operacije mogu da se urade u komercijalnim programima kao što su Paint Shop Pro (Arithmetic Tool) i Adobe Photoshop (Calculations).

 

Sve procedure su relativno lake i daju prilično interesantne slike. Osnovni kôd je za učitavanje bmp slika sa kojim ste već dobro upoznati sa dodatkom procedura koje obavljaju konkretnu operaciju nad slikama- argumentima i procedurom za njihovo prikazivanje.

Izvorne slike (konji.bmp, goveda.bmp i cvet.bmp) su relativno lošeg kvaliteta.

konji.bmp goveda.bmp cvet.bmp

U sledećim odeljcima biće data neka vrsta pseudo koda i referenciran fajl sa izvornim kodom za konkretnu operaciju.

result[x][y].r = (image1[x][y].r + image2[x][y].r) / 2; result[x][y].g = (image1[x][y].g + image2[x][y].g) / 2; result[x][y].b = (image1[x][y].b + image2[x][y].b) / 2;

Usrednjavanje slika je kada usrednjavate zbir njihovih odgovarajućih kolornih komponenti, tj. za svaki piksel result[x][y] = (image1[x][y] + image2[x][y]) / 2.

Sabiranje

Sabiranje je kada dodajete odgovarajuće kanale boje jedne slike drugoj. Svaka kolorna komponenta ima vrednost između 0 i 255, stoga u slučaju da je zbir odgovarajućih kolornih komponenti slika veći od 255, mora da se uradi odsecanje (tj. svođenje na 255) i uzimanje minimuma od rezultata zbira i 255.

result[x][y].r = min(image2[x][y].r + image3[x][y].r, 255); result[x][y].g = min(image2[x][y].g + image3[x][y].g, 255); result[x][y].b = min(image2[x][y].b + image3[x][y].b, 255);

 

Nebo sa druge slike je prilično svetlo, tako da sabiranjem kolornih komponenti druge slike dovodi do premašivanja vrednosti 255 i zbog odsecanja rezultujuća slika je u gornjem delu ekstremno bela.

Izvorni kôd je dat u fajlu AddImages.c.

Odizumanje

Oduzimanje radi na sličan način, samo sada moraju da se odsecaju negativne vrednosti, tj. da se svode na

0.

result[x][y].r = max(image2[x][y].r - image1[x][y].r, 0); result[x][y].g = max(image2[x][y].g - image1[x][y].g, 0); result[x][y].b = max(image2[x][y].b - image1[x][y].b, 0);

Slika sa kravama je oduzeta od slike sa konjima, stoga su boje slike sa kravama postale negativne. To objašnjava pojavu purpurnih nijansi. Svetlo nebo oduzeto od livadskog cveća daje kao rezultat crni gornji deo rezultujuće slike.

Redosled slika kod oduzimanja je važan.

 

Izvorni kôd je dat u fajlu SubImage.c.

Razlika

Razlika (difference) je skoro ista kao oduzimanje, samo sada umesto odsecanja negativnih vrednosti uzimamo njihove apsolutne vrednosti.

result[x][y].r = abs(image1[x][y].r - image2[x][y].r); result[x][y].g = abs(image1[x][y].g - image2[x][y].g); result[x][y].b = abs(image1[x][y].b - image2[x][y].b);

Sada su mesta koja su crna u jednoj slici popunjena bojom druge slike. Izvorni kôd je dat u fajlu DiffImages.c.

Množenje

Kod množenja ne treba množiti svaku kolornu vrednost koja je u rasponu 0-255 jednu sa drugom, pošto je tada maksimalna dobijena vrednost 255 * 255 = 65025, a sa tako dobijenom kolornom vrednošću ne možete mnogo da uradite. Umesto toga, konvertujte vrednosti u decimalne u rasponu od 0 do 1, i onda ih pomnožite. Reazultat će uvek biti između 0 i 1. Potom dobijenu vrednost pomnožite sa 255.

result[x][y].r = int(255 * (image2[x][y].r / 255.0 * image1[x][y].r / 255.0)); result[x][y].g = int(255 * (image2[x][y].g / 255.0 * image1[x][y].g / 255.0)); result[x][y].b = int(255 * (image2[x][y].b / 255.0 * image1[x][y].b / 255.0));

Evo kako izgleda rezultat množenja slika sa kravama i konjima:

 

Svetlo nebo slike sa kravama može se posmatrati kao vrednost 1, a 1 pomnoženo sa pikselima slike sa konjima daje piksele konja, stoga gornji deo slike izgleda skoro kao originalna slika sa konjima. Donji deo rezultujuće slike je proizvod dva tamnija dela odgovarajućih slika, usled čega je on još tamniji.

Srednja vrednost

Srednja vrednost (average) se dobija sabiranjem dve slike i deljenjem rezultata sa dva.

result[x][y].r = (image1[x][y].r + image2[x][y].r) / 2; result[x][y].g = (image1[x][y].g + image2[x][y].g) / 2; result[x][y].b = (image1[x][y].b + image2[x][y].b) / 2;

Izvorni kôd je dat u fajlu AvrImages.c.

Min i Max

Ovaj slučaj obuhvata uzimanje samo pikselske vrednosti koja je niža ili viša. Primer za uzimanje niže vrednosti:

result[x][y].r = min(image1[x][y].r, image2[x][y].r); result[x][y].g = min(image1[x][y].g, image2[x][y].g); result[x][y].b = min(image1[x][y].b, image2[x][y].b);

Rezultat je veoma očigledan:

 

Slika sa kravama ima relativno svetlo nebo (visoke pikselske vrednosti), dok slika sa konjima na tim pozicijama ima tamnije vrednosti i u slučaju operacije min pikseli slike sa konjima prevlađuju na rezultujućoj slici. U donjem delu slike, slika sa konjima je svetlija u odnosu na sliku sa kravama, usled čega pikseli slike sa kravama preovlađuju u rezultujućoj slici.

Uzimanjem operacije max dobija se suprotan rezultat:

result[x][y].r = max(image1[x][y].r, image2[x][y].r); result[x][y].g = max(image1[x][y].g, image2[x][y].g); result[x][y].b = max(image1[x][y].b, image2[x][y].b);

AND, OR i XOR

Sada ćemo primeniti operatore "&", "|" i "^" na binarne vrednosti kolornih komponenti. Rezultati primene ovih operatora na obične slike su veoma neobični.

Evo operacije AND:

result[x][y].r = image1[x][y].r & image2[x][y].r; result[x][y].g = image1[x][y].g & image2[x][y].g; result[x][y].b = image1[x][y].b & image2[x][y].b;

 

Izvorni kôd je dat u fajlu AndImages.c.

Ili možda više volite operaciju OR?

result[x][y].r = image1[x][y].r | image2[x][y].r; result[x][y].g = image1[x][y].g | image2[x][y].g; result[x][y].b = image1[x][y].b | image2[x][y].b;

Rezultat operacije XOR naizgled nije mnogo očaravajući:

result[x][y].r = image1[x][y].r ^ image2[x][y].r; result[x][y].g = image1[x][y].g ^ image2[x][y].g; result[x][y].b = image1[x][y].b ^ image2[x][y].b;

Nikad se ne zna, možda nešto od ovoga može biti veoma korisno u nekom slučaju.

Pripremio Dragan Marković