Salta el contingut

Tutorial i exercisis

Introducció

Des del punt de vista del processament d’imatge, un filtre modifica una imatge calculant nous valors per als píxels. En molts casos, el nou valor depèn dels píxels que hi ha al voltant, és a dir, d’un veïnat local. Quan aquesta combinació és lineal, es pot descriure mitjançant una convolució amb una petita matriu de pesos anomenada kernel.

Encara que aquí es treballi principalment en el domini espacial, també és útil recordar la interpretació freqüencial. Les variacions lentes corresponen a zones suaus de la imatge, mentre que les variacions ràpides solen aparèixer a vores, textura o soroll. Els filtres de suavitzat redueixen aquestes variacions ràpides, i els filtres de realç les fan més visibles.

En aquesta pràctica s’estudien diferents filtres de suavitzat i realçament aplicats a imatges en escala de grisos. L’objectiu és comprendre com actuen aquests filtres, tant a nivell matemàtic com visual, i analitzar el seu comportament davant del soroll.

Manipulació bàsica d’imatges

Carreguem les imatges que s’utilitzaran al llarg de la pràctica i les convertim a escala de grisos quan és necessari, per treballar únicament amb nivells d’intensitat.

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

univers = imread("Imagenes\Universo.jpg");

univers = rgb2gray(univers);

Mostrem les imatges carregades per comprovar que s’han llegit correctament.

montage({lena,univers})

figure_0.png

Filtres de suavitzat

Els filtres de suavitzat redueixen el soroll i les variacions brusques d’intensitat, a costa de perdre detall fi en la imatge.

La mida del veïnat i els pesos del kernel determinen fins a quin punt es modifica la imatge. Un veïnat petit conserva millor els detalls, però pot reduir poc el soroll. Un veïnat gran suavitza més, però també pot eliminar vores febles o estructures petites que podrien ser importants en una segmentació posterior.

Producte de convolució. Definim un kernel de la mitjana 3x3, que assigna el mateix pes a tots els píxels del veïnat.

El filtre de la mitjana substitueix cada píxel pel promig dels valors del seu voltant. Això redueix variacions petites i soroll aleatori, però també pot desdibuixar vores perquè barreja píxels de costats diferents d’un contorn.

w = (1./9.)*[1,1,1;1,1,1;1,1,1];

Apliquem la convolució utilitzant conv2. Aquesta funció no gestiona automàticament les vores, cosa que provoca artefactes visibles.

lena_conv = conv2(lena,w);

montage({lena,uint8(lena_conv)}) % Observa les vores

figure_1.png

Filtre de la mitjana utilitzant imfilter. La funció imfilter permet aplicar el mateix kernel, però gestionant millor les vores.

lena_mitjana = imfilter(lena,w);

montage({lena,lena_mitjana})

figure_2.png

Padding en imfilter. Per defecte s’utilitza zero-padding, però es poden utilitzar altres opcions per millorar el resultat a les vores.

lena_mitjana_r = imfilter(lena,w,'replicate');

lena_mitjana_s = imfilter(lena,w,'symmetric');

montage({lena,lena_mitjana,lena_mitjana_r,lena_mitjana_s}) % Comparar especialment les vores

figure_3.png

Filtre gaussià. El filtre gaussià assigna més pes al píxel central i suavitza de manera més natural.

Un filtre gaussià és un filtre de suavitzat basat en la distribució gaussiana. Els píxels propers al centre del kernel tenen més pes que els píxels llunyans, de manera que el suavitzat és més progressiu que amb una mitjana uniforme. El paràmetre sigma controla l’amplada de la gaussiana: com més gran és sigma, més fort és el suavitzat i més detalls fins es poden perdre.

Kernel gaussià 3x3 amb sigma = 1

w_gaussia = (1./16.)*[1,2,1;2,4,2;1,2,1];

lena_gaussia = imfilter(lena,w_gaussia);

montage({lena,lena_gaussia})

figure_4.png

Filtres gaussians de mida més gran utilitzant fspecial

Quan s’utilitza un kernel gaussià més gran, el filtre pot tenir en compte un veïnat més ampli. Això és útil si el soroll és important, però també augmenta el risc d’eliminar textures fines o vores febles. Per aquest motiu, la mida del kernel i sigma s’han d’escollir segons l’escala dels detalls que es volen conservar.

w_gaussia = fspecial("gaussian",5,5);

lena_gaussia = imfilter(lena,w_gaussia);

montage({lena,lena_gaussia})

figure_5.png

Filtre de la mitjana genèric amb fspecial

w_mitjana = fspecial("average",5);

lena_mitjana = imfilter(lena,w_mitjana);

montage({lena,lena_mitjana})

figure_6.png

Aplicació del filtre de la mitjana per a la reducció de soroll gaussià. Primer afegim soroll gaussià i després apliquem el filtre per observar-ne l’efecte.

lena_soroll = imnoise(lena,"gaussian",0,0.01);

lena_soroll_fil = imfilter(lena_soroll,w_mitjana);

montage({lena,lena_soroll,lena_soroll_fil})

figure_7.png

Suavitzat previ per millorar la binarització. El suavitzat redueix petites variacions i facilita una binarització més estable.

univers_bin = univers>200;

w_mitjana = fspecial("average",25);

univers_fil = imfilter(univers,w_mitjana);

univers_fil_bin = univers_fil>200;

montage({univers,univers_bin,univers_fil_bin})

figure_8.png

Aplicació del filtre gaussià a la reducció de soroll

w_gaussia = fspecial("gaussian",3,3);

lena_soroll_fil = imfilter(lena_soroll,w_gaussia);

montage({lena,lena_soroll,lena_soroll_fil})

figure_9.png

Filtres estadístics

Els filtres estadístics també miren un veïnat local, però no calculen el resultat com una suma ponderada. En lloc d’això, utilitzen una estadística com el mínim, el màxim o la mediana. Aquesta diferència els fa més adequats en situacions on hi ha valors atípics, com passa amb el soroll de sal i pebre.

Aquests filtres es basen en estadístiques locals del veïnat.

Filtre del màxim. realça les zones brillants i elimina punts foscos aïllats.

El filtre del màxim assigna a cada píxel el valor més alt del seu veïnat. Per això expandeix les zones clares i pot fer desaparèixer petits punts foscos. És una operació no lineal i està relacionada amb la dilatació morfològica en escala de grisos.

w_estadistic = ones(3);

lena_max = ordfilt2(lena,numel(w_estadistic),w_estadistic);

montage({lena,lena_max})

figure_10.png

Filtre del mínim. realça les zones fosques i elimina punts brillants aïllats.

El filtre del mínim fa l’operació contrària: assigna a cada píxel el valor més baix del seu veïnat. Això expandeix les zones fosques i pot eliminar petits punts brillants. Conceptualment s’assembla a una erosió morfològica en escala de grisos.

lena_min = ordfilt2(lena,1,w_estadistic);

montage({lena,lena_min})

figure_11.png

Filtre de la mediana. És especialment eficaç per eliminar soroll impulsional, sal i pebre.

El filtre de la mediana ordena els valors del veïnat i tria el valor central. Com que no fa una mitjana, els valors extrems produïts pel soroll de sal i pebre tenen menys influència. Per això sol conservar millor les vores que el filtre de la mitjana quan el soroll és impulsional.

lena_mediana = medfilt2(lena,size(w_estadistic));

montage({lena,lena_mediana})

figure_12.png

Aplicació de filtres estadístics a soroll sal i pebre

probabilitat = 0.05;

soroll_impulsional = rand(size(lena));

lena_amb_soroll = lena;

lena_amb_soroll(soroll_impulsional < probabilitat/2) = 0;

lena_amb_soroll(soroll_impulsional > 1 - probabilitat/2) = 255;

lena_max = ordfilt2(lena_amb_soroll,numel(w_estadistic),w_estadistic);

lena_min = ordfilt2(lena_amb_soroll,1,w_estadistic);

lena_mediana = medfilt2(lena_amb_soroll,size(w_estadistic));

montage({lena,lena_amb_soroll,lena_max,lena_min,lena_mediana})

figure_13.png

Filtres de realçament

Els filtres de realçament busquen destacar canvis importants d’intensitat. Aquests canvis poden correspondre a vores d’objectes, canvis de textura, ombres o discontinuïtats en l’escena. Com que el soroll també pot produir canvis bruscos, és habitual aplicar algun suavitzat abans de calcular gradients o derivades.

Aquests filtres destaquen canvis bruscos d’intensitat i permeten detectar vores.

Derivada digital per definició. S’aproximen les derivades en les direccions x i y mitjançant kernels simples.

w_dx = [0,1,0;0,-1,0;0,0,0];
w_dy = [0,0,0;1,-1,0;0,0,0];

Gradient digital. Es combina la magnitud de les derivades en ambdues direccions.

El gradient mesura com canvia la intensitat en les direccions horitzontal i vertical. La seva magnitud és gran en punts on hi ha una transició forta, com una vora. Per això el gradient és una eina bàsica per detectar contorns i orientar altres descriptors.

lena_gradient = abs(imfilter(lena,w_dx)) + abs(imfilter(lena,w_dy));

lena_negativa = 255 - lena_gradient;

montage({lena,lena_gradient,lena_negativa})

figure_14.png

Filtres de Roberts, Sobel i Prewitt. Aquests filtres calculen el gradient utilitzant diferents aproximacions.

Roberts, Sobel i Prewitt són aproximacions discretes de la derivada de la imatge. Roberts és més local i pot ser més sensible al soroll, mentre que Sobel i Prewitt incorporen una mica de suavitzat en la direcció perpendicular. Això fa que la detecció de vores sigui sovint més estable, tot i que la resposta pot variar segons l’orientació de la vora.

Filtre de Roberts

wR_dx = [1,0;0,-1];
wR_dy = [0,1;-1,0];

lena_gradient_roberts = abs(imfilter(lena,wR_dx)) + abs(imfilter(lena,wR_dy));

lena_negativa_roberts = 255 - lena_gradient_roberts;

montage({lena,lena_gradient_roberts,lena_negativa_roberts})

figure_15.png

Filtre de Sobel

w_sobel = fspecial("sobel");

lena_gradient_sobel = abs(imfilter(lena,w_sobel)) + abs(imfilter(lena,w_sobel'));

lena_negativa_sobel = 255 - lena_gradient_sobel;

montage({lena,lena_gradient_sobel,lena_negativa_sobel})

figure_16.png

Filtre de Prewitt

w_prewitt = fspecial("prewitt");

lena_gradient_prewitt = abs(imfilter(lena,w_prewitt)) + abs(imfilter(lena,w_prewitt'));

lena_negativa_prewitt = 255 - lena_gradient_prewitt;

montage({lena,lena_gradient_prewitt,lena_negativa_prewitt})

figure_17.png

Laplacià digital. Detecta canvis d’intensitat en totes les direccions.

El Laplacià és una derivada de segon ordre. A diferència del gradient, no dona una direcció principal de canvi, sinó que respon a variacions d’intensitat en qualsevol orientació. Com que les derivades de segon ordre són molt sensibles al soroll, sovint es combinen amb un suavitzat previ, com passa amb el filtre Laplacian of Gaussian.

w_laplacia = [1,1,1;1,-8,1;1,1,1];

lena_laplacia = imfilter(lena,w_laplacia);

lena_laplacia_negatiu = 255 - lena_laplacia;

montage({lena,lena_laplacia,lena_laplacia_negatiu})

figure_18.png

Laplacian of Gaussian (LoG). Combina suavitzat gaussià i detecció de vores.

El LoG aplica primer un suavitzat gaussià i després un Laplacià. El suavitzat redueix la resposta al soroll, mentre que el Laplacià detecta canvis ràpids d’intensitat. Aquesta combinació és útil perquè les derivades de segon ordre són molt sensibles al soroll si s’apliquen directament.

w_soroll_gauss = fspecial('gaussian',3,1);

lena_soroll_gauss = imfilter(lena,w_soroll_gauss);

lena_log = imfilter(lena_soroll_gauss,w_laplacia);

lena_log_negatiu = 255 - lena_log;

montage({lena,lena_laplacia,lena_laplacia_negatiu,lena_log,lena_log_negatiu})

figure_19.png

Difference of Gaussians (DoG). Es resta el resultat de dos filtres gaussians amb sigma diferent.

La Difference of Gaussians compara dues versions de la imatge suavitzades amb valors de sigma diferents. En restar-les, es ressalten estructures que són visibles a una certa escala i es redueixen altres detalls. Aquesta idea de treballar amb escales diferents és molt important en visió per ordinador, especialment en detectors de punts d’interès com SIFT.

sigma1 = 0.5;
sigma2 = 2;

w_gaussia1 = fspecial('gaussian',9,sigma1);
w_gaussia2 = fspecial('gaussian',9,sigma2);

lena_gaussia_1 = imfilter(lena,w_gaussia1);
lena_gaussia_2 = imfilter(lena,w_gaussia2);

lena_dog = lena_gaussia_2 - lena_gaussia_1;

lena_dog_negativa = 255 - lena_dog;

montage({lena,lena_dog,lena_dog_negativa})

figure_20.png

Binarització del resultat DoG per ressaltar vores significatives

Després de calcular una resposta de vores o de diferència d’escales, sovint cal decidir quines respostes són prou importants. La binarització fa aquesta selecció mitjançant un llindar: els valors forts es conserven i els febles s’eliminen. Això facilita interpretar el resultat com un conjunt de vores candidates.

lena_dog = lena_dog > 5;

lena_dog_negativa = lena_dog_negativa < 250;

montage({lena,lena_dog,lena_dog_negativa})

figure_21.png