Salta el contingut

Tutorial i exercisis

En aquesta pràctica es parteix d’una idea fonamental: una imatge digital es pot entendre com una matriu de píxels. Cada píxel té una posició dins de la imatge i conté informació visual, ja sigui un nivell de gris o diversos valors associats al color. Per aquest motiu, conceptes com la resolució espacial, la quantificació i el model de color són importants abans d’aplicar qualsevol tècnica de processament.

Al llarg del tutorial es veuran operacions molt bàsiques, però totes tenen una interpretació conceptual clara. Algunes modifiquen només el valor dels píxels, mentre que altres canvien la mida, la posició o la forma aparent de la imatge. Entendre aquesta diferència ajuda a connectar aquesta primera pràctica amb temes posteriors com el filtratge, la segmentació i la descripció d’objectes.

Manipulació bàsica d’imatges

Carreguem les imatges

I = imread("Imagenes\lena_gray_512.tif");
F = imread("Imagenes\lena_color_512.tif");

Mostrem les imatges

imshow(I)

figure_0.png

imshow(F)

figure_1.png

Calculem la resolució espacial de cada imatge

La resolució espacial indica el nombre de píxels que formen la imatge en amplada i alçada. Una resolució més gran pot representar més detall si la captura original també el conté, però canviar la mida d’una imatge ja digitalitzada no afegeix informació real. Quan ampliem o reduïm, el sistema ha d’estimar valors nous a partir dels píxels existents, i això pot suavitzar detalls o generar artefactes.

size(I)
ans = 1x2
   512   512
size(F)
ans = 1x3
   512   512     3

Calculem la resolució d’intensitat, o quantificació, de cada imatge

La resolució d’intensitat, també anomenada quantificació, indica quants nivells diferents pot representar cada píxel. En una imatge de 8 bits hi ha 256 valors possibles, de 0 a 255. Si es redueix aquest nombre de nivells, diferents intensitats de l’escena es representen amb el mateix valor, i això pot provocar pèrdua de contrast fi o bandes visibles en zones suaus.

max(max(I))
ans = uint8245
max(max(F))
ans = 1x1x3 uint8 array
ans(:,:,1) =

   255

ans(:,:,2) =

   248

ans(:,:,3) =

   225

Reescalem espacialment la imatge

Reescalar espacialment vol dir canviar el nombre de píxels de la imatge. Si reduïm la imatge, es perden mostres i per tant es pot perdre detall. Si l’ampliem, cal inventar valors intermedis mitjançant interpolació; per això una ampliació no recupera detall real que no fos a la imatge original.

I = imresize(I,[128,128]);
imshow(I)

figure_2.png

I = imresize(I,[64,64]);
imshow(I)

figure_3.png

I = imresize(I,[16,16]);
imshow(I)

figure_4.png

I = imread("Imagenes\lena_gray_512.tif");
I = imresize(I,[1028,1028]);
imshow(I)

figure_5.png

Reescalem els nivells d’intensitat de la imatge

Reescalar els nivells d’intensitat vol dir canviar el rang de valors dels píxels. Aquesta operació pot fer que una imatge es vegi més clara, més fosca o amb més contrast, però no canvia la posició dels objectes. És una transformació útil per preparar imatges abans d’aplicar llindars o filtres.

nivells_gris = [128,32,4];

I_128 = imquantize(I, linspace(0, 255, nivells_gris(1)));
I_32 = imquantize(I, linspace(0, 255, nivells_gris(2)));
I_4 = imquantize(I, linspace(0, 255, nivells_gris(3)));

imshow(I_128,[])

figure_6.png

imshow(I_32,[])

figure_7.png

imshow(I_4,[])

figure_8.png

Calculem l’histograma

L’histograma és una eina senzilla per estudiar la distribució dels nivells d’intensitat d’una imatge. Mostra quants píxels hi ha a cada valor, però no conserva informació sobre la seva posició. Tot i aquesta limitació, és molt útil per detectar si una imatge és fosca, clara, té poc contrast o presenta grups d’intensitats que podrien separar-se mitjançant un llindar.

histograma = imhist(I);

Visualitzem l’histograma

bar(histograma)

figure_9.png

Calculem cadascun dels canals de color de la imatge mitjançant “eliminar” els altres dos

Separar els canals de color ajuda a entendre que el color d’un píxel és una combinació de diverses components. En el model RGB, cada canal representa la contribució de vermell, verd o blau. En canvi, en el model HSV es descriu el color mitjançant el to, la saturació i la intensitat percebuda, fet que pot ser més adequat en algunes tasques d’anàlisi visual.

F_vermell = F;
F_vermell(:,:,2)=0;
F_vermell(:,:,3)=0;

F_verd = F;
F_verd(:,:,1)=0;
F_verd(:,:,3)=0;

F_blau = F;
F_blau(:,:,1)=0;
F_blau(:,:,2)=0;

imshow(F_vermell)

figure_10.png

imshow(F_verd)

figure_11.png

imshow(F_blau)

figure_12.png

Convertim la imatge de RGB a escala de grisos

La conversió a escala de grisos redueix una imatge de tres canals a una sola imatge d’intensitat. Normalment no es fa una mitjana simple dels canals, sinó una combinació ponderada que té en compte la sensibilitat visual al vermell, verd i blau. Es perd informació cromàtica, però es simplifica l’anàlisi quan el color no és essencial.

F_gris = rgb2gray(F);
imshow(F_gris)

figure_13.png

Convertim la imatge de RGB a HSV

El model HSV separa la informació de color en tres components més interpretables: el to indica el tipus de color, la saturació indica la puresa del color i el valor indica la brillantor. Aquesta separació pot facilitar tasques en què interessa analitzar el color independentment de la il·luminació.

F_hsi = rgb2hsv(F);
imshow(F_hsi)

figure_14.png

Calculem els canals H, S i V

imshow(F_hsi(:,:,1))

figure_15.png

imshow(F_hsi(:,:,2))

figure_16.png

imshow(F_hsi(:,:,3))

figure_17.png

Soroll gaussià

El soroll representa alteracions no desitjades dels valors dels píxels. Pot aparèixer per limitacions del sensor, de la il·luminació, de la transmissió o del procés de digitalització. En el cas del soroll gaussià, molts píxels pateixen canvis petits al voltant d’un valor mitjà, de manera que la imatge conserva l’estructura general però adquireix un aspecte més granulat.

Definim els paràmetres del soroll gaussià, és a dir, la mitjana i la variància

mitjana = 0;
variancia = 0.01;

La funció imnoise afegeix soroll gaussià multiplicatiu, cosa que es pot detectar fàcilment pel seu aspecte granulat

En el soroll multiplicatiu, la pertorbació depèn del valor del píxel. Això vol dir que les zones més intenses poden veure’s afectades de manera diferent que les zones fosques. Aquest model és útil per entendre sorolls que no s’afegeixen igual a tota la imatge.

I_gaussian_mult = imnoise(I,"gaussian",mitjana,variancia);

imshow(I_gaussian_mult)

figure_18.png

Mentre que el soroll gaussià additiu, que s’afegeix tal qual a la imatge, només difumina lleugerament els detalls

En el soroll additiu, a cada píxel se li suma una variació aleatòria independent del seu valor original. La imatge conserva l’estructura general, però les petites diferències locals poden quedar contaminades. Per això molts filtres de suavitzat intenten reduir aquest tipus de variació local.

soroll_gaussia = uint8(randn(size(I)) * sqrt(variancia) + mitjana);

I_gaussian_add = I + soroll_gaussia;

imshow(I_gaussian_add)

figure_19.png

Soroll sal i pebre

El soroll de sal i pebre és un exemple de soroll impulsional. A diferència del soroll gaussià, no afecta tots els píxels de manera suau, sinó que substitueix alguns valors per intensitats extremes, normalment negre o blanc. Aquest comportament explica per què, en pràctiques posteriors, els filtres no lineals com la mediana poden ser més adequats que un simple promig.

Definim els paràmetres del soroll sal i pebre, és a dir, la probabilitat que un cert píxel passi a ser un gra de sal o de pebre

probabilitat = 0.05;

Generem una imatge aleatòria que fem servir per canviar els píxels de la imatge original per punts de sal o pebre. Si un píxel aleatori està per sobre o per sota de la probabilitat definida, el píxel corresponent de la imatge original es canvia.

soroll_sal_pebre = rand(size(I));
I_soroll = I;

I_soroll(soroll_sal_pebre < probabilitat/2) = 0; % Soroll "sal"
I_soroll(soroll_sal_pebre > 1 - probabilitat/2) = 255; % Soroll "pebre"

imshow(I_soroll)

figure_20.png

Operacions aritmètiques

Les operacions aritmètiques actuen directament sobre els valors numèrics dels píxels. Sumar o restar pot modificar la brillantor, mentre que multiplicar o dividir pot canviar el contrast de manera global. Cal tenir present que les imatges digitals tenen un rang de valors limitat; si una operació produeix valors fora d’aquest rang, es pot perdre informació per saturació.

I = imread("Imagenes\lena_gray_512.tif");

F = imread("Imagenes\Contornos.tif");

G = imread("Imagenes\Office1.png");

H = imread("Imagenes\Office2.png");

G = rgb2gray(G);

H = rgb2gray(H);

montage({I,F,G,H})

figure_21.png

Suma aritmètica per una constant

I_50 = I + 50;

Reescalem per poder operar amb les imatges i fem servir la funció add per sumar-les

s = size(G);

H = imresize(H,[s(1),s(2)]);

GH_add = imadd(G,H);

montage({I_50,GH_add})

figure_22.png

Resta per una constant

I_75 = I - 75;

Reescalem per poder operar amb les imatges i fem servir la funció substract per restar-les

F = rgb2gray(imresize(F,[512,512]));

IF_resta = imsubtract(I,F);

montage({I_75,IF_resta})

figure_23.png

Producte per una constant

I_2 = I.*2;

Reescalem per poder operar amb les imatges i fem servir la funció immultiply per multiplicar-les

IG_prod = immultiply(I,imresize(G,[512,512]));

montage({I_2,IG_prod})

figure_24.png

Divisió per una constant

I__2 = I./2;

Reescalem per poder operar amb les imatges i fem servir la funció imdivide per dividir-les

I_div = imdivide(I,imresize(G,[512,512]));

montage({I__2,I_div})

figure_25.png

Operacions lògiques

En una imatge binària, cada píxel només pot pertànyer al fons o a l’objecte. Per això, les operacions lògiques es poden interpretar com operacions entre conjunts de píxels: AND correspon a una intersecció, OR a una unió i NOT al complement. Aquesta manera de pensar serà especialment important quan s’introdueixi la morfologia matemàtica.

Binaritzem les imatges per llindarització

G_bin = G>128;

H_bin = H>128;

Calculem l’AND lògic, equivalent a la intersecció si els objectes estan definits per 1

A = and(G_bin,H_bin);

imshow(A

figure_26.png

Calculem l’OR lògic, equivalent a la unió si els objectes estan definits per 1

O = or(G_bin,H_bin);

imshow(O)

figure_27.png

Calculem l’XOR lògic

X = xor(G_bin,H_bin);

imshow(X)

figure_28.png

Calculem el NOT lògic

N = not(G_bin);

imshow(N)

figure_29.png

Operacions amb la intensitat dels píxels

Les transformacions d’intensitat són operacions puntuals, perquè cada píxel es modifica segons el seu propi valor i no segons el veïnat. Aquest tipus d’operació no mou els objectes ni canvia la geometria de la imatge, sinó que redistribueix els nivells de gris. Això pot servir per aclarir zones fosques, comprimir zones molt brillants o ajustar el contrast global.

Calculem la imatge negativa

La imatge negativa inverteix els nivells d’intensitat: els valors foscos passen a ser clars i els clars passen a ser foscos. Aquesta transformació és simple, però ajuda a veure que moltes operacions puntuals només redistribueixen valors sense canviar la geometria de l’escena.

I_neg = 255-I;

imshow(I_neg)

figure_30.png

Calculem la transf. logarítmica, amb constant c = L-1/log(L) i L nivells de gris de la imatge. La transf. logarítmica aclareix zones fosques respectant les zones que ja eren clares.

imatge = imread("Imagenes\Espalda.jpg");
imatge = rgb2gray(imatge);
imshow(imatge)

figure_31.png

imatge_log = (255/(log(256)))*log(double(imatge) + 1);

imshow(uint8(imatge_log))

figure_32.png

Calculem la transf. exponencial, amb constant c = L-1/log(L) i L nivells de gris de la imatge. La transf. exponencial enfosqueix zones clares respectant les zones que ja eren fosques. És la inversa de la transf. logarítmica.

imatge_1 = imread("Imagenes\cells_internet.jpg");

imshow(imatge_1)

figure_33.png

imatge_exp = exp((log(256)/255)*double(imatge_1))-1;

imshow(uint8(imatge_exp))

figure_34.png

Transf. potència-arrel o correcció gamma: aglutina i generalitza les transf. logarítmica i exponencial

La correcció gamma permet controlar de manera flexible la relació entre intensitats d’entrada i sortida. Si gamma és menor que 1, s’aclareixen sobretot les zones fosques; si és major que 1, s’enfosqueixen sobretot les zones clares. És molt utilitzada perquè s’adapta millor a la percepció visual i als dispositius de visualització.

Primer pas: transformo els valors d’intensitat de l’interval \(begin:math:display\)0\,255\(end:math:display\) a \(begin:math:display\)0\,1\(end:math:display\)

imatge_1_gamma = (1./255.)*double(imatge_1);

Segon pas: defineixo el valor de gamma i transformo

Tercer pas: transformo els valors d’intensitat de nou a l’interval \(begin:math:display\)0\,255\(end:math:display\)

gamma = 20;

imatge_1_gamma = uint8(imatge_1_gamma.^gamma * 255);

imshow(imatge_1_gamma)

figure_35.png

Expansió i equalització de l’histograma

L’expansió i l’equalització de l’histograma intenten utilitzar millor el rang disponible d’intensitats. L’expansió reparteix els valors entre un mínim i un màxim, mentre que l’equalització busca una distribució més uniforme. Aquestes tècniques poden millorar el contrast, però també poden exagerar soroll o donar resultats poc naturals quan la imatge té il·luminació desigual.

Calculem l’histograma

h = imhist(I);
bar(h)

figure_36.png

Calculem els valors d’intensitat màxim i mínim per expandir l’histograma

maxi = double(max(max(I)));
mini = double(min(min(I)));
I_exp = 255.*(double(I)-mini)./(maxi-mini);

imshow(uint8(I_exp))

figure_37.png

h_exp = imhist(uint8(I_exp));
bar(h_exp)

figure_38.png

Equalitzem l’histograma, cosa que distribueix de manera uniforme els valors d’intensitat en tot l’interval

I_eq = histeq(I,256);

imshow(I_eq)

figure_39.png

h_eq = imhist(I_eq);
bar(h_eq)

figure_40.png

Operacions geomètriques

Les operacions geomètriques canvien la posició dels píxels o la mida aparent dels objectes. En rotacions, translacions o canvis d’escala, les noves posicions no sempre coincideixen exactament amb la graella discreta de píxels. Per això cal interpolar valors, i el mètode d’interpolació pot influir en la nitidesa, les vores i la qualitat visual del resultat.

Rotació d’angle theta

I_rot = imrotate(I,45);

imshow(I_rot)

figure_41.png

Translació en la direcció (x,y)

I_tras = imtranslate(I,[50,150]);

imshow(I_tras)

figure_42.png

Translació amb imatge completa

I_tras = imtranslate(I,[50,150],'OutputView','full');

imshow(I_tras)

figure_43.png

Simetries vertical i horitzontal

I_simv = flip(I,1);
I_simh = flip(I,2);

montage({I_simv,I_simh})

figure_44.png

Dilatació i reducció de factors d i r.

dilatacio_factor = 2;
reduccio_factor = 0.5;

I_dil = imresize(I,dilatacio_factor);
I_red = imresize(I,reduccio_factor);

montage({I_dil,I_red})

figure_45.png

Per a algunes de les transformacions geomètriques, cal escollir el mètode d’interpolació, per exemple, rotacions i traslacions

La interpolació defineix com es calcula el valor d’un píxel quan la transformació geomètrica situa una coordenada entre píxels existents. La interpolació nearest és ràpida però pot produir vores dentades; la bilinear dona resultats més suaus; i la bicúbica acostuma a conservar millor la continuïtat, tot i ser més costosa.

I_rot_n = imrotate(I,45,'nearest');
I_rot_b = imrotate(I,45,'bilinear');
I_rot_bb = imrotate(I,45,'bicubic');

imshow(I_rot_n)

figure_46.png

imshow(I_rot_b)

figure_47.png

imshow(I_rot_bb)

figure_48.png