Procesamiento de Imagenes con Matlab



Esta es una introduccion para el procesamiento de imagenes 
con Matlab usando el basicoejemplo que te expondre. 
En este tutorial nosotros vamos a segmentar las particulas 
en la imagen.




Tutorial

1 Descargar el SAND.TIF

2 Abrir Matlab con Image Processing Toolbox

3 En primer lugar, vamos a abrir la imagen. Comience con el comando uigetfile que abre una ventana emergente con todos los archivos del tipo '* tif'. Seleccione la imagen que desea procesar, en este caso 'SAND.TIF'. El comando imread leera la imagen. Tenga en cuenta que después de ejecutar el comando imread, la variable que aparece en la ventana de pila variable como una matriz de 512x512 con uint8 tipo (es decir, una imagen de 8 bits). El tipo uint8 significa que los píxeles tienen valores enteros en el rango de 0 a 255 Esto significa que si se añade 255 (o se resta) a la imagen (es decir, i = i + 255;), todos los píxeles tendrá un valor de 255 (o 0 en el caso de la resta de 255).

fname = uigetfile('*.tif');
     I = imread(fname);

4 Ver la imagen usando el comando imshow. El comando va a usar el minimo y maximo valor de pixel para dar un buen contraste con la imagen(si es necesario).

imshow(I,[])

5 Ver el histograma de las intensidades de pixeles usando el comando imhist. Observe que no hay mucho contraste entre las partículas y la matriz (como resultado del cambio gradual de la intensidad de la parte inferior izquierda a la superior derecha).

imhist(I)

6 Método 1 - Trate de segmentar la imagen utilizando un umbral de intensidad de 170 y luego mostrar la nueva imagen binaria, J1. La primera línea identifica aquí todos los píxeles que tienen una intensidad mayor que 170 como 1 (verdadero) y todas las intensidades por debajo o igual a 170 como 0 (falso). Observe que J1 es del mismo tamaño y I y que J1 es una matriz lógica (lo que significa que sólo puede tener de 0 y de 1). Este método hace un mal trabajo de segmentación de la imagen debido al cambio de intensidad en el fondo.

J1 = I > 170;
     imshow(J1,[])

7 Método 2 - Trate de segmentar la imagen utilizando una técnica de umbral de intensidad global automatizada (método de Otsu). La función graythresh utiliza el método de Otsu, que elige el umbral para minimizar la varianza intraclase de los píxeles en blanco y negro. La línea de píxeles da el umbral de intensidad definida por esta función y segmentos im2bw la imagen de acuerdo con el umbral definido mediante el comando graythresh. A continuación, mostrar la nueva imagen binaria, J2. Esto todavía no funciona, porque no hay suficiente separación entre los dos histogramas.


 level = graythresh(I);
     pixel = level * 255;
     J2 = im2bw(I,level);
     imshow(J2)

8 Método 3. En primer lugar, aplicar un filtro para encontrar el píxel más oscuro en cada región. Puede utilizar el comando ordfilt2 o el comando imerode para encontrar el píxel más oscuro en una región del tamaño de 'nSize' alrededor de cada pixel. Luego se repite el imagen usando imshow.

nsize = 40; 
     I_background = ordfilt2(I,1,true(nsize),'symmetric');
     I_background = imerode(I,strel('square',nsize));
     imshow(I_background,[])

9. Ahora queremos restar esto desde la imagen inicial I. Este procesamiento de imágenes nivela la intensidad de fondo de la imagen. Recuerda que nuestra imagen que se almacena como uint8, sin embargo, así que tenemos que transformarla en una matriz de doble precisión antes de restar. El comando imshow mostrará la nueva imagen nivelado.

 I_leveled = double(I) - double(I_background);
     imshow(I_leveled,[])


10 Ahora nos transformamos a una uint8 redimensionando los valores a números enteros entre 0 y 255 que vamos a guardar esto como nuestra nueva y mejorada imagen, I2. También vamos a ver el histograma de la imagen. Observe cómo las dos distribuciones han separado por la nivelación de la imagen.

   I_leveled = uint8((I_leveled - min(I_leveled(:)))/(max(I_leveled(:)) - min(I_leveled(:))) * 255);
     imhist(I_leveled)

11 Ahora nos vamos a segmentar manualmente la imagen utilizando una intensidad de 120.

 manual_threshold = 120;
     J3 = I_leveled > manual_threshold;
     imshow(J3,[])

12 Vamos a deshacernos de todo lo que por debajo de un cierto tamaño con el comando bwareaopen y luego mostrar la nueva imagen.

 BW2 = bwareaopen(BW,10)
     imshow(BW2)

o podríamos haber utilizado otro enfoque

  BW = J3;
     CC = bwconncomp(BW);
     L = labelmatrix(CC);
     stats  = regionprops(L);
     area = [stats.Area];
     size_thresh = 10;
     idx = find(area > size_thresh);
     BW2 = ismember(L, idx);
     imshow(BW2)

13 Vamos a rellenar los huecos

BW3 = imfill(BW2,'holes');
     imshow(BW3)

4. Intenté algo un poco diferente aquí, sólo por diversión. Así, en primer lugar, dilate las regiones blancas (partículas) utilizando una región de 5x5 cuadrados. Luego usé la técnica de Otsu para encontrar un umbral adecuado para SOLO las intensidades de los píxeles dentro de las regiones blancas dilatadas. He utilizado este umbral para segmentar las partículas y eliminado todos los objetos segmentados en las regiones negras ajustando su intensidad igual a 0 entonces me llena en los agujeros y eliminado todos los objetos de menor tamaño de 30 píxeles.

 BW_trial = imdilate(BW3,strel('square',5));
     imshow(BW_trial)
     level = graythresh(I_leveled(BW_trial));
     pixel = level * 255;
     BW4 = im2bw(I_leveled,level);
     BW4(~BW_trial) = 0;
     BW4 = imfill(BW4,'holes');
     BW4 = bwareaopen(BW4,30);
     imshow(BW4,[])


15 Ahora vamos a mostrar en la imagen original. En primer lugar, creamos una imagen binaria que contiene sólo los píxeles en el perímetro de nuestras partículas usando la función bwperim. Entonces, estamos generando una nueva imagen I2 RGB con 3 canales - I2 (:,:, 1) RED, I2 (:,:, 2) VERDE, I2 (:,:, 3) AZUL. Estamos estableciendo sólo los píxeles del perímetro a rojo cambiando su intensidad a 255 para el canal rojo y 0 para los canales verde y azul.

BW5 = bwperim(BW4);
     imshow(BW5,[])
     I2 = I; I2(BW5) = 255;
     I_RGB = I2;
     I2 = I; I2(BW5) = 0;
     I_RGB(:,:,2) = I2;
     I2 = I; I2(BW5) = 0;
     I_RGB(:,:,3) = I2;
     imshow(I_RGB,[])


6. Fin, guardar las imágenes con el comando imwrite.

imwrite(I_RGB,'image_RGB.tif','tif')
     imwrite(BW4,'image_binary.tif','tif')
     imwrite(I_leveled,'image_leveled.tif','tif')


0 comentarios:

Publicar un comentario

Gracias por tu visita!!