Mostrando entradas con la etiqueta 2. Programas con procesamiento de imágenes mediante Matlab. Mostrar todas las entradas
Mostrando entradas con la etiqueta 2. Programas con procesamiento de imágenes mediante Matlab. Mostrar todas las entradas

Detección de la nariz en una imagen mediante Matlab

En este programa se va a realizar la detección de la nariz en una imagen 3D formada por un conjunto de datos que nos permite simular la periferia de un cráneo en 3D.
Los datos los tenemos en una matriz de 3 dimensiones en los cuales, la primera y segunda dimensión son los ejes x e y que nos permiten definir el ancho y largo de la imagen y la tercera dimensión diferencia entre imágenes las cuales han sido tomadas desde abajo hacia arriba para cortes con diferentes alturas en el cráneo.

Proyecto realizado junto con la colaboración de Encarni Sánchez García.

Para poder ejecutar el programa, se hace uso del siguiente código:

load 'TAC_Nasal_2_0'
%para corte 2.0 corte axial
v = volume(1:2:end,1:2:end,1:1:end);
figure
p = patch(isosurface(v, 700));
isonormals(v, p)
set(p, 'FaceColor', 'red', 'EdgeColor', 'none');
daspect([1 1 size(v,3)/size(v,1)*1.5])
view(3)
camlight; lighting phong
v = double(volume);
dim=size(v);
%for i=1:dim(3)
corte_20 = squeeze(v(:,:,30));
 norm = double(max(max(max(volume)))); 
figure, imshow((corte_20)/norm)%lo normalizamos entre el máximo, si no lo hacemos la imagen se verá blanca 
corte_20 = (corte_20)/norm;

%realizamos el histograma
[xh,yh] = histograma(corte_20,norm);
[pks,locs]=findpeaks(yh,'SORTSTR','descend','minpeakdistance',100,'Npeaks',20);

hold on
plot(xh(locs(1:3)),yh(locs(1:3)),'k^','markerfacecolor',[1 0 0]);



m1 = round((locs(1)+locs(2))/2);
m2 = round((locs(2)+locs(3))/2);
 m3= round((locs(1)+locs(3))/2);  % 
m11=((locs(1)+locs(2))/2);
m22=((locs(2)+locs(3))/2);

stem(xh(m1),norm,'r^')

text(xh(m1),2000,['T = ' num2str(xh(m1))]);

title(['histograma con umbral T']);
hold off


%segmentación con el algoritmo fcm

clusterNum = 3;
[ Unow, center, now_obj_fcn ] = FCMforImage(corte_20, clusterNum );
figure, imshow(Unow(:,:,1))  %unow tiene 3 capas  es en escala grises  tienes varias tonalidades de un mismo color  unow es una imagen en 3 capas


 figure, imshow(Unow(:,:,1))

  imshow(corte_20,[]);
for i=1:clusterNum

   figure,imshow(Unow(:,:,i),[]);
end

figure, imshow(Unow)%tiene gradaciones del color




 I=Unow(:,:,3);
figure, imshow(I)
BW = im2bw(I, graythresh(I));  %CONVIERTE LA IMAGEN I A BINARIA 
CC = bwconncomp(BW); %conectividad
L = labelmatrix(CC); %MATRIZ ETIQUETADA

RGB = label2rgb(L); %imagn de color etiquetada  creo que igual que bwlabel
RGB2 = label2rgb(L, 'spring', 'c', 'shuffle'); %(L) convierte una matriz de etiqueta, L, como los devueltos por labelmatrix, bwlabel, bwlabeln o cuenca, en una imagen de color RGB con el fin de visualizar las regiones marcadas. La función label2rgb determina el color para asignar a cada objeto basado en el número de objetos en la matriz de etiqueta y gama de colores en el mapa de colores. La función label2rgb recoge colores de toda la gama.
RGB2 = label2rgb(L, 'spring', 'c', 'shuffle'); %rgb2 se puede hacer extración si se elimina el fondo
figure, imshow(RGB)
figure, imshow(RGB2)
 imshow(RGB(:,:,1))
  %%ETIQUETADO
%%
close all
 ImageR=bwlabel(BW, 4); %imagen binaria  LE PASO LA IMAGEN BINARIA 

RGB = label2rgb(ImageR);
figure, imshow(RGB);
im_gray=rgb2gray(RGB);
im_edge=edge(im_gray);
im_edgeR=edge(RGB(:,:,1));
im_edgeG=edge(RGB(:,:,2));
im_edgeB=edge(RGB(:,:,3));
im_nueva=0.4*RGB(:,:,1)+0.4*RGB(:,:,3)-0.4*RGB(:,:,2);
im_edgeN=edge(im_nueva);
figure, imshow(im_edge);
figure, imshow(im_edgeR);
figure, imshow(im_edgeG);
figure, imshow(im_edgeB);
figure, imshow(im_nueva);
figure, imshow(im_edgeN);
im__2 = im2bw(im_nueva,0.1);
figure, imshow(im__2);
% obtencion del cuadrado con el que voy a recortar la imagen RGB:
parte_alta=length(im__2(:,1));
parte_baja=1;
parte_izquierda=length(im__2(1,:));
parte_derecha=1;
for j=1:length(im__2(1,:))
    for i=1:length(im__2(:,1))
        if im__2(i,j)==0
            if i
                parte_alta=i;
            end
            if i>parte_baja
                parte_baja=i;
            end
            if j
                parte_izquierda=j;
            end
            if j>parte_derecha
                parte_derecha=j;
            end
        end
    end
end
%una vez tengo el cuadrado paso a recortar la imagen RGB:
im_RGB_nariz=imcrop(RGB,[parte_baja parte_alta parte_derecha parte_izquierda]);
figure, imshow(im_RGB_nariz);

Además de las funciones que se utilizan que se adjuntan en el zip que podéis descargar aquí:


Resultados:
A continuación se representa la obtención de la nariz  a partir de la siguiente imagen inicial.
En esta primera imagen, se observa la periferia de un craneo, visto desde arriba. Los datos de entrada a nuestro programa son los datos del craneo en 3D, del cual obtenemos la representación de la parte que hace referencia a la nariz en 3D aunque mostramos solamente la imagen de la nariz vista desde abajo:

Vista de la detección de la nariz desde abajo en color:


Vista de la detección de la nariz desde abajo en blanco y negro:
Entrada principal

Detector de distanca con una cámara y un laser mediante Matlab

beruby - te devolvemos dinero por tus compras y reservas online

Medición de distancias con un láser y una cámara mediante Matlab:

Cálculo de la distancia de un objeto a una cámara en función de la distancia entre la cámara y el láser y del ángulo que existe entre la línea del eje central de la cámara y de la línea ficticia que une el punto luminoso del láser con la cámara:





Como vemos en la imagen, según las relaciones trigonométricas aplicadas al triángulo formado por la distancia en línea recta entre la cámara y el objeto, la línea que representa  la visión del la inferencia del láser en el objeto por la cámara y la línea más izquierda del objeto (longitud h), se puede deducir que tan(Θ)=h/d; luego la distancia será d=h/tan(Θ)

De dicha ecuación, conocemos la distancia h entre la cámara y el láser, pero el ángulo es lo que necesitamos calcular y lo realizaremos mediante la siguiente expresión:

Θ=pfc*rpc+desfase, donde:

Pfc: cantidad de píxeles desde el centro del plano focal hasta el puntero láser.
Rpc: radianes que ocupa cada pixel.

Con esto podría calcular la distancia del objeto a la cámara en una imagen. Si se quisiera hacer para un vídeo, es decir, continuamente en el tiempo, tendríamos que sumarle al ángulo Θ  un factor que contendría los pequeños desplazamientos en radianes del láser en las imágenes que se van obteniendo.


El código se divide principalmente en dos partes:
    • Reconocimiento de la imagen para obtener el puntero láser.
    • Cálculos con la imagen reconocida para obtener el ángulo Θ y consigo la distancia.

Podéis encontrar el código comentado justo debajo o simplemente podéis descargaros el fichero .m en el siguiente enlace:
https://www.mediafire.com/?i14uj31sg6ttugi

Codigo:
clear all
close all
clc

%capturamos una imagen de la webcam y la guardamos en im_rgb
vid = videoinput('winvideo', 1);
a=0;
capt1 = getsnapshot(vid);
imshow(capt1);
stoppreview(vid);
im_rgb=capt1;   
%separamos las 3 componentes de la señal original en color
im_r=im_rgb(:,:,1);
im_g=im_rgb(:,:,2);
im_b=im_rgb(:,:,3);

%analizamos la componente de color rojo y buscamos el valor maximo que
%correspondera con el centro del laser en la imagen

max_r=max(im_r(1,:));
for i=120:240
    for j=1:length(im_rgb(1,:,1))
        if (im_r(i,j)>max_r)
            max_r=double(max(im_r(i,:)));
            posicion_r=i;
        end
       
    end
end

%representamos la imagen original en color para comprobar que aparece el
%laser en la imagen

figure(1),imshow(im_rgb)              
%calculamos el numero de pixeles de los que difiere el centro del laser
%desde el centro de la imagen
pfc=posicion_r - 120;

%calculamos con valores reales y con simulaciones los valores de ganancia y
%desfase mediante la expresion distancia = h/tan(pfc*ganancia+desfase)*2 de
%forma que conociendo la distancia real y la altura h en cm a la que se
%encuentra la camara respecto del laser podemos calcular los parametros
%ganancia y desfase.
ganancia = 0.0024301218;
desfase = -0.056638255;

h=5.4;%en centimetros
%aplicamos la formula con la que obtenemos la distancia
distancia = h/tan(pfc*ganancia+desfase)

Conclusión: 
Este programa que permite detectar la distancia de un objeto a la cámara depende de cada cámara y de la distancia entre la cámara y el láser por lo que se tendrá que calcular la ganancia y el desfase mediante simulación real para cada conjunto cámara láser con el que queramos usar el programa.

Este programa se puede mejorar bastante, actualmente solo mide la distancia y la devuelve en la variable "distancia". Pero se pueden añadir diversas finalidades fácilmente como puede ser el que te vaya midiendo la distancia no solo una vez sino que cuando acaba la vuelva a medir (se implementaría simplemente con un bucle "while") y también que te muestre el valor de la distancia en la imagen que representamos.

Para comprobar el correcto funcionamiento os dejo una imagen que tomo con una distancia del objeto en el que se refleja el puntero láser y la cámara de 83 cm:
Esa imagen que he tomado con la webcam, al ser analizada por el programa nos devuelve un valor de la distancia de 83.1294 en cm por lo que se aproxima bastante a la distancia real de 83cm.

El programa lo he probado con distancias  mucho menores y mayores de la representada anteriormente y funciona gracias al ajuste de los parámetros ganancia y desfase comentados anteriormente.