Está en la página 1de 5

%Proyecto Pantalla Tactil Virtual "Virtual Touch Screen VTS"

%Codigo implementado en matlab por Carlos Eduardo Arbelaez Vega


%limpiar pantalla y reinicializar variables
clc;
clear all;
%ver la informacion de los adaptadores disponibles
imaqhwinfo;
%ver la informacion de un adaptador especifico por ejemplo winvideo
imaqhwinfo('winvideo');
%ver la informacion de un dispositivo de un adaptador especifico
imaqhwinfo('winvideo',1);
%inicializar la camara con algun adaptador, dispositivo y calidad seleccionado
%de modo que sea manual la toma de imagenes
vid = videoinput('winvideo', 1, 'YUY2_160x120'); % 'YUY2_160x120' 'YUY2_176x144
' 'YUY2_320x240' 'YUY2_352x288' 'YUY2_640x480'
propinfo(vid); %Muestra las propiedades de videoinput
set(vid, 'SelectedSourceName', 'input1');
set(vid, 'FramesPerTrigger', 1);
set(vid, 'TriggerRepeat', Inf);
set(vid, 'ReturnedColorSpace', 'rgb');
triggerconfig(vid,'manual');
%encender la camara y alistarse para adquirir imagenes a la memoria
start(vid);
%mostrar en una ventana lo que se esta visualizando por la camara
preview(vid);
%tomar una imagen para seleccionar el nuevo puntero
uiwait(msgbox('Ubique el objeto que sera el puntero dentro del rango de vision d
e la camara y presione ok','Atencion','modal'));
fabric = getsnapshot(vid);
% obtener el tamaño de la imagen tomada.
imageRes = vid.VideoResolution;
imageWidth = imageRes(1);
imageHeight = imageRes(2);
%cerrar y detener el video
closepreview(vid);
stop(vid);
delete(vid);
clear vid;
% mostrar la imagen tomada para seleccionar el puntero
colorNames = {'fondo', 'puntero'};% fondo y punteros que uno quiera p ejem{'punt
ero 1', 'puntero 2'};
nColors = length(colorNames);
sample_regions = false([imageHeight imageWidth nColors]);
% seleccion de la region puntero
f = figure;
for count = 1:nColors
set(f, 'name', ['Seleccione la region a tomar por ' colorNames{count}] );
sample_regions(:,:,count) = roipoly(fabric);
end
close(f);
% convertir la imagen fabric de RGB a una imagen L*a*b
cform = makecform('srgb2lab');
lab_fabric = applycform(fabric,cform);
a = lab_fabric(:,:,2);
b = lab_fabric(:,:,3);
color_markers = repmat(0, [nColors, 2]);
for count = 1:nColors
color_markers(count,1) = mean2(a(sample_regions(:,:,count)));
color_markers(count,2) = mean2(b(sample_regions(:,:,count)));
end
% clasificar cada pixel de acuerdo al la regla de la cercania (distancia euclidi
ana)
color_labels = 0:(nColors-1); % crea un arreglo que contenga el fondo y los punt
eros, 0 = fondo, 1 = puntero
% inicializar las matrices que van a ser usadas en la clasificacion de cercanias
.
a = double(a);
b = double(b);
distance = repmat(0,[size(a), nColors]);
% realizar la clasificacion.
for count = 1:nColors
distance(:,:,count) = ( (a - color_markers(count,1)).^2 + ...
(b - color_markers(count,2)).^2 ).^0.5;
end
[value, label] = min(distance, [], 3);
label = color_labels(label);
clear value distance;
% preparar las imagenes resultado de la clasificacion
rgb_label = repmat(label, [1 1 3]);
segmented_images = repmat(uint8(0), [size(fabric), nColors]);
for count = 1:nColors
color = fabric;
color(rgb_label ~= color_labels(count)) = 0;
segmented_images(:,:,:,count) = color;
end
%mostrar la imagen del puntero encontrado sin procesar
imshow(segmented_images(:,:,:,2),'InitialMagnification','fit');
title([colorNames{2} ' encontrado sin procesar'] );
% cambiar puntero a escala de grises y mostrarlo
puntero = color;
punterog = rgb2gray(puntero);
uiwait(msgbox('a continuacion se procesara el puntero a escala de grises','Atenc
ion','modal'));
imshow(punterog,'InitialMagnification','fit'), title([colorNames{2} ' en grises'
] );
% crear mascaras de lineas alrededor de los colores y mostrar
[junk threshold] = edge(punterog, 'sobel');
fudgeFactor = .5; %este factor cambia el
BWs = edge(punterog,'sobel', threshold * fudgeFactor);
uiwait(msgbox('a continuacion se procesara el puntero a una mascara de lineas','
Atencion','modal'));
imshow(BWs,'InitialMagnification','fit'), title([colorNames{2} ' en mascara de l
ineas'] );
% dilatar las lineas
se90 = strel('line', 3, 90);
se0 = strel('line', 3, 0);
BWsdil = imdilate(BWs, [se90 se0]);
uiwait(msgbox('a continuacion se procesara el puntero a lineas dilatadas','Atenc
ion','modal'));
imshow(BWsdil,'InitialMagnification','fit'), title([colorNames{2} ' en lineas di
latadas'] );
% eliminar objetos de area menor osea remover el ruido
bw = BWsdil;
bw = bwareaopen(bw,100); % remover objetos que contengan menos de 100 pixeles (a
ca cuadro el tamaño del puntero max y min)
uiwait(msgbox('a continuacion se procesara el puntero sin ruido','Atencion','mod
al'));
imshow(bw,'InitialMagnification','fit'), title([colorNames{2} ' sin ruido'] );
% llenar los hollos Este llena el interior de las figuras cerradas
BWdfill = imfill(bw, 'holes');
uiwait(msgbox('a continuacion se procesara el puntero con las lineas rellenadas'
,'Atencion','modal'));
imshow(BWdfill,'InitialMagnification','fit'), title([colorNames{2} ' en lineas r
ellenadas'] );
%marcar los borde de la imagen resultante
BWoutline = bwperim(BWdfill,6);
Segout = fabric;
Segout(BWoutline) = 255;
uiwait(msgbox('a continuacion se mostrara el puntero procesado','Atencion','moda
l'));
imshow(Segout,'InitialMagnification','fit'), title([colorNames{2} ' procesado']
);
%empezar la deteccion ciclica
%inicializar la camara con algun adaptador, dispositivo y calidad seleccionado
%de modo que sea manual la toma de imagenes
vid = videoinput('winvideo', 1, 'YUY2_160x120'); % 'YUY2_160x120' 'YUY2_176x144
' 'YUY2_320x240' 'YUY2_352x288' 'YUY2_640x480'
propinfo(vid); %Muestra las propiedades de videoinput
set(vid, 'SelectedSourceName', 'input1');
set(vid, 'FramesPerTrigger', 1);
set(vid, 'TriggerRepeat', Inf);
set(vid, 'ReturnedColorSpace', 'rgb');
triggerconfig(vid,'manual');
%encender la camara y alistarse para adquirir imagenes a la memoria
start(vid);
%mostrar ciclicamente en una ventana los frames tomados
for i = 1:100
frame = getsnapshot(vid);
% convertir la imagen frame de RGB a una imagen L*a*b
cform = makecform('srgb2lab');
lab_frame = applycform(frame,cform);
aframe = lab_frame(:,:,2);
bframe = lab_frame(:,:,3);
% clasificar cada pixel de acuerdo al la regla de la cercania (distancia euc
lidiana)
color_labels = 0:(nColors-1); % crea un arreglo que contenga el fondo y los
punteros, 0 = fondo, 1 = puntero
% inicializar las matrices que van a ser usadas en la clasificacion de cerca
nias.
aframe = double(aframe);
bframe = double(bframe);
distance = repmat(0,[size(a), nColors]);
% realizar la clasificacion.
for count = 1:nColors
distance(:,:,count) = ( (aframe - color_markers(count,1)).^2 + ...
(bframe - color_markers(count,2)).^2 ).^0.5;
end
[value, label] = min(distance, [], 3);
label = color_labels(label);
clear value distance;
% preparar las imagenes resultado de la clasificacion
rgb_label = repmat(label, [1 1 3]);
segmented_images = repmat(uint8(0), [size(frame), nColors]);
for count = 1:nColors
color = frame;
color(rgb_label ~= color_labels(count)) = 0;
segmented_images(:,:,:,count) = color;
end
% cambiar puntero a escala de grises
puntero = color;
punterog = rgb2gray(puntero);
% crear mascaras de lineas alrededor de los colores
[junk threshold] = edge(punterog, 'sobel');
fudgeFactor = .5; %este factor cambia el
BWs = edge(punterog,'sobel', threshold * fudgeFactor);
% dilatar las lineas
se90 = strel('line', 3, 90);
se0 = strel('line', 3, 0);
BWsdil = imdilate(BWs, [se90 se0]);
% eliminar objetos de area menor osea remover el ruido
bw = BWsdil;
bw = bwareaopen(bw,10); % remover objetos que contengan menos de 100 pixeles
(aca cuadro el tamaño del puntero max y min)
% llenar los hollos Este llena el interior de las figuras cerradas
BWdfill = imfill(bw, 'holes');
%marcar los borde de la imagen resultante
BWoutline = bwperim(BWdfill,6);
Segout = frame;
Segout(BWoutline) = 255;
%calcular los centroides
L = bwlabel(BWoutline);
s = regionprops(L, 'centroid');
centroids = cat(1, s.Centroid);
%mostrar el resultado final
imshow(Segout,'InitialMagnification','fit');
if centroids ~= 0
hold on;
plot(centroids(:,1), centroids(:,2), 'b*'); %dibuja los centroides
line(centroids(:,1),centroids(:,2)); %dibuja la linea que une los centroides
hold off;
end
%pausar para alcanzar a ver la imagen
pause(0.0000001);
end
%apagar la camara y borrar lo que se a adquirido de la memoria
stop(vid);
delete(vid);
clear vid;
close all;
clc;