« L'absence est à l'amour, ce qu'est au feu le vent ; il éteint le petit, il allume le grand. »
- Roger Bussy-Rabutin
viernes, 26 de julio de 2013
viernes, 19 de julio de 2013
Detector de similitud de imagenes
Es muy útil poder cuantificar la similitud entre dos imagines para todo sistema de visión por computadora. Uno de los algoritmos más utilizados por su sencillez y efectividad es el Coeficiente de Correlación de Pearson. Si consideremos a una imagen digital como una muestra de datos de un evento "aleatorio", podemos reescribir el coeficiente de la siguiente forma:
donde el numerador representa a la covariancia de los datos (valores de los pixeles) de la imagen A y B y el denominador es el producto de la desviación estándar de los datos de la imagen A por la desviación estándar de los de la imagen B. Podemos implementar un detector de similitud en Matlab. Antes, hay que mencionar algunas características de la función cov(). Supongamos que tenemos dos conjuntos de datos:
La función cov() dará como resultado una matriz donde la posición (1,1) es la covarianza de la primer columna consigo misma, (1,2) es la covarianza de la primera con la segunda, (2,1) la segunda con la primera y (2,2) la segunda consigo misma:
>> cov(x,y)
ans =
4.5667 0.8333
0.8333 8.5667
En este caso las únicas posiciones que nos interesan son la (1,2) o la (2,1). Conociendo este detalle podemos implementar sin problemas un algoritmo de detección de similitud de la siguiente forma:
% Carga de imagenes
I = imread('dali.jpg');
I2 = imread('dali6.jpg');
subplot(1,2,1),imshow(I),title('Imagen A')
subplot(1,2,2), imshow(I2),title('Imagen B')
% Conversion a escala de grises y escalamiento
Is = rgb2gray(I);
[n m] = size(Is);
I2 = imresize(I2,[n m]);
I = rgb2gray(I);
I = double(I);
I2 = rgb2gray(I2);
% Cambio de forma matricial a vector y cambio de formato
Ir = reshape(I, [1 numel(I)]);
Ir = double(Ir);
Ir2 = reshape(I2, [1 numel(I2)]);
Ir2 = double(Ir2);
% Cálculo del CCP
Sx = std(Ir);
Sy = std(Ir2);
Cxym = cov(Ir,Ir2);
Cxy = Cxym(2,1);
p = Cxy/(Sx*Sy)
if p > 0.7
disp('La imagen es la misma')
else
disp('Las imagenes son diferentes')
end
donde el numerador representa a la covariancia de los datos (valores de los pixeles) de la imagen A y B y el denominador es el producto de la desviación estándar de los datos de la imagen A por la desviación estándar de los de la imagen B. Podemos implementar un detector de similitud en Matlab. Antes, hay que mencionar algunas características de la función cov(). Supongamos que tenemos dos conjuntos de datos:
x = [ 1 3 4 6 7 4];
y = [ 6 7 1 4 9 8];
Si queremos obtener la covariancia entre ambos conjuntos utilzando cov(x,y), lo primero que hará la función es concatenar ambos vectores de la siguiente manera:
[x y ]
1 6
3 7
4 1
6 4
7 9
4 8
La función cov() dará como resultado una matriz donde la posición (1,1) es la covarianza de la primer columna consigo misma, (1,2) es la covarianza de la primera con la segunda, (2,1) la segunda con la primera y (2,2) la segunda consigo misma:
>> cov(x,y)
ans =
4.5667 0.8333
0.8333 8.5667
En este caso las únicas posiciones que nos interesan son la (1,2) o la (2,1). Conociendo este detalle podemos implementar sin problemas un algoritmo de detección de similitud de la siguiente forma:
% Carga de imagenes
I = imread('dali.jpg');
I2 = imread('dali6.jpg');
subplot(1,2,1),imshow(I),title('Imagen A')
subplot(1,2,2), imshow(I2),title('Imagen B')
% Conversion a escala de grises y escalamiento
Is = rgb2gray(I);
[n m] = size(Is);
I2 = imresize(I2,[n m]);
I = rgb2gray(I);
I = double(I);
I2 = rgb2gray(I2);
% Cambio de forma matricial a vector y cambio de formato
Ir = reshape(I, [1 numel(I)]);
Ir = double(Ir);
Ir2 = reshape(I2, [1 numel(I2)]);
Ir2 = double(Ir2);
% Cálculo del CCP
Sx = std(Ir);
Sy = std(Ir2);
Cxym = cov(Ir,Ir2);
Cxy = Cxym(2,1);
p = Cxy/(Sx*Sy)
if p > 0.7
disp('La imagen es la misma')
else
disp('Las imagenes son diferentes')
end
miércoles, 17 de julio de 2013
S.
Pareciera ser el caso de que últimamente sólo escribo de mi vida cuando algo anda mal o estoy enojado. ¿Por qué no estoy escribiendo cuando siento que cada cosa en la tierra me sonríe? Nunca había tenido tan cerca de mi vida a una mujer tan perfecta. Puede interpretarse la palabra “perfecta” como la ausencia de defectos. Quizá por mis inevitables analogías de ingeniería prefiero usar el adjetivo “ideal” para tal fin. Al decir perfecta, en mi contexto, no me refiero a una mujer libre de defectos, sino a una mujer que dispara y desborda mis emociones de formas inexplicables como si tuviera marcado dentro de mi mente un margen entre lo común y lo extraordinario.
domingo, 7 de abril de 2013
Contador de objetos con webcam en Matlab
El programa es muy similar al contador de objetos dibujados en un archivo JPG como el de la entrada anterior:
winvid = videoinput('winvideo',1,'YUY2_320x240'); % Probablemente tengas que ajustar esta linea a tu webcam
capt1 = getsnapshot(winvid);
img = rgb2gray(capt1);
bin = img <= min(min(img))+20;
%filtro antiruido tomado de Floydbot
magic=strel('square', 2);
binf=imerode(bin, magic);
cen = regionprops(binf,'centroid'); % Calculo de centroides
num = numel(cen); % Conteo de centroides
El archivo .fig y .m vienen en la carpeta que pueden descargar en el siguiente enlace:
sábado, 6 de abril de 2013
Visión por computadora: Contador de objetos en Matlab
Supongamos que hemos dibujado algunos objetos en Paint, por ejemplo:
Podemos implementar un programa en Matlab que cuente los objetos dibujados en una imagen como la anterior de la siguiente forma:
clear, clc
imagen = imread('objetos.jpg');
img = rgb2gray(imagen); %Conversión RGB a Escala de grises
imshow(imagen)
title('Imagen Original')
binaria = img<=20; % Binarización de la imagen
cen = regionprops(binaria,'centroid'); % Calculo de centroides
num = numel(cen); % Conteo de centroides
fprintf('Numero de objetos: %d\n',num)
Para este ejemplo he guardado la imagen en formato JPG, pero Matlab soporta además los formatos PNG, BMP, GIF, TIFF y XWD. La imagen, como deben recordar, debe encontrarse en el directorio de trabajo que estemos utilizando para que pueda ser llamada por el programa. Próximamente veremos como contar objetos dibujados en una hoja de papel utilizando una webcam.
Podemos implementar un programa en Matlab que cuente los objetos dibujados en una imagen como la anterior de la siguiente forma:
clear, clc
imagen = imread('objetos.jpg');
img = rgb2gray(imagen); %Conversión RGB a Escala de grises
imshow(imagen)
title('Imagen Original')
binaria = img<=20; % Binarización de la imagen
cen = regionprops(binaria,'centroid'); % Calculo de centroides
num = numel(cen); % Conteo de centroides
fprintf('Numero de objetos: %d\n',num)
Para este ejemplo he guardado la imagen en formato JPG, pero Matlab soporta además los formatos PNG, BMP, GIF, TIFF y XWD. La imagen, como deben recordar, debe encontrarse en el directorio de trabajo que estemos utilizando para que pueda ser llamada por el programa. Próximamente veremos como contar objetos dibujados en una hoja de papel utilizando una webcam.
lunes, 18 de marzo de 2013
Guia para el estudiante universitario de nuevo ingreso
Este, como otros de mis escritos, es una carta más que quisiera enviarme al pasado, justo al comienzo de mi primer año en la universidad. Han pasado casi 4 años desde entonces y es han ahora cuando puedo ver de modo claro lo que debí haber hecho. Esta guía, ensayo o recopilación de consejos va orientada a estudiantes de ingeniaría y ciencias. Naturalmente deben existir consejos universales pero ya bastantes artículos pueden ser consultados en la red para ese caso. Mi labor solidaria recae en los detalles particulares que nadie te ha dado.
Existe una cuestión mental llamada disracionalidad. En pocas palabras, es la incapacidad de comportarse o resolver un problema racionalmente a pesar de tener la inteligencia adecuada. Existe la teoría de que este comportamiento existe porque para nuestros ancestros les era mejor evitar detenerse a pensar para huir rápidamente del peligro. Menciono esto porque cuando estés a mitad de carrera te darás cuenta que podías haber sabido lo que sabes en ese momento desde el principio de la carrera. Tienes toda la capacidad para aprender todo lo que necesitas en tu carrera desde un principio. Esto es un hecho y no una frase vacía de "motivación personal".
Ahora que tienes identificada la disracionalidad debes luchar contra ella. Pierde el miedo a aprender cosas que tomas por difíciles. Hasta aquí hemos hablado de capacidad (la tienes), pero el aprendizaje es como una escalera y no puedes simplemente saltar hasta el último escalón. Debes dominar los escalones más bajos. Comienza con estos:
Álgebra: Inevitablemente todo se reducirá a álgebra en algún punto así estés haciendo matemáticas complejas (desde Calculo, Ecuaciones Diferenciales, Variable Compleja hasta análisis de Fourier). No puedes sobre-confiarte en esta área. Desde un principio deberás repasar todo hasta el cansancio. Has una libreta de apuntes con todo lo relevante: métodos de localización de raíces de polinomios, fracciones parciales, etc...
Lógica*: Para lic. en física y matemáticas se verá bastante duro este punto y posiblemente sea algo completamente nuevo para muchos. No queda de otra más que tomar 3 o más libros de lógica o elementos de matemáticas de tu biblioteca. Te deben quedar claro los métodos de demostración y la lógica proposicional.
*Tal vez pueda omitirse para estudiantes de ingeniería.
Programación: No le temas. Desde el primer semestre notarás que tus compañeros que vienen de escuelas técnicas te llevarán ventaja en este punto. Algunos habrán comenzado a programar en C, Basic o Java desde la secundaria. No importa, bastan pocas semanas para alcanzarlos. Aún si eres tu el estudiante que llevó algún curso de programación no debes confiarte. Consigue Dev-C++ en este instante y empieza a repasar o a aprender. ¿Cómo empezar? Consigue todo el material que puedas en tu biblioteca. Si tienes un amigo que sepa programar muy bien, pídele ayuda.
Arduino: ¿Vas para electrónica o mecatrónica? Consigue un Arduino en tiendas de componentes electrónicos y aprende a programarlo con tutoriales en línea. Sé lo que digo. Incluso si vas para física te servirá para controlar tus propios experimentos, hacer adquisición de datos y computo físico. No hay prisa, yo también empecé haciendo un led parpadear.
Matlab: Debes entender desde un principio que WinPlot y los graficadores en linea son de lo más corriente. Sé que te parecerán más fáciles de usar, pero a la larga el dominar herramientas de software matemático como Matlab te darán muchas ventajas. Este software parece difícil de usar por su ventada de comandos, pero no lo es. Es como manejar un auto standard. Existen muchos tutoriales en español así que consiguelo cuanto antes y comienza a jugar con él.
Puedo asegurarte que estas son todas las bases que necesitas. Tómalos como un estudió extra, paralelo a tus primeras materias. El resto vendrá a su tiempo de acuerdo a tu programa de estudios. Quizá podría agregar para los estudiantes de electrónica/ mecatrónica/ ing. eléctrica comprar y leer Fundamentos de Circuitos Eléctricos de Sadiku desde el primer momento que ponen un pie en la universidad. ¿Y que hay de la parte personal y social? Me tomaría una entrada entera... o puedes leer el resto del blog...
Existe una cuestión mental llamada disracionalidad. En pocas palabras, es la incapacidad de comportarse o resolver un problema racionalmente a pesar de tener la inteligencia adecuada. Existe la teoría de que este comportamiento existe porque para nuestros ancestros les era mejor evitar detenerse a pensar para huir rápidamente del peligro. Menciono esto porque cuando estés a mitad de carrera te darás cuenta que podías haber sabido lo que sabes en ese momento desde el principio de la carrera. Tienes toda la capacidad para aprender todo lo que necesitas en tu carrera desde un principio. Esto es un hecho y no una frase vacía de "motivación personal".
Ahora que tienes identificada la disracionalidad debes luchar contra ella. Pierde el miedo a aprender cosas que tomas por difíciles. Hasta aquí hemos hablado de capacidad (la tienes), pero el aprendizaje es como una escalera y no puedes simplemente saltar hasta el último escalón. Debes dominar los escalones más bajos. Comienza con estos:
Álgebra: Inevitablemente todo se reducirá a álgebra en algún punto así estés haciendo matemáticas complejas (desde Calculo, Ecuaciones Diferenciales, Variable Compleja hasta análisis de Fourier). No puedes sobre-confiarte en esta área. Desde un principio deberás repasar todo hasta el cansancio. Has una libreta de apuntes con todo lo relevante: métodos de localización de raíces de polinomios, fracciones parciales, etc...
Lógica*: Para lic. en física y matemáticas se verá bastante duro este punto y posiblemente sea algo completamente nuevo para muchos. No queda de otra más que tomar 3 o más libros de lógica o elementos de matemáticas de tu biblioteca. Te deben quedar claro los métodos de demostración y la lógica proposicional.
*Tal vez pueda omitirse para estudiantes de ingeniería.
Programación: No le temas. Desde el primer semestre notarás que tus compañeros que vienen de escuelas técnicas te llevarán ventaja en este punto. Algunos habrán comenzado a programar en C, Basic o Java desde la secundaria. No importa, bastan pocas semanas para alcanzarlos. Aún si eres tu el estudiante que llevó algún curso de programación no debes confiarte. Consigue Dev-C++ en este instante y empieza a repasar o a aprender. ¿Cómo empezar? Consigue todo el material que puedas en tu biblioteca. Si tienes un amigo que sepa programar muy bien, pídele ayuda.
Arduino: ¿Vas para electrónica o mecatrónica? Consigue un Arduino en tiendas de componentes electrónicos y aprende a programarlo con tutoriales en línea. Sé lo que digo. Incluso si vas para física te servirá para controlar tus propios experimentos, hacer adquisición de datos y computo físico. No hay prisa, yo también empecé haciendo un led parpadear.
Matlab: Debes entender desde un principio que WinPlot y los graficadores en linea son de lo más corriente. Sé que te parecerán más fáciles de usar, pero a la larga el dominar herramientas de software matemático como Matlab te darán muchas ventajas. Este software parece difícil de usar por su ventada de comandos, pero no lo es. Es como manejar un auto standard. Existen muchos tutoriales en español así que consiguelo cuanto antes y comienza a jugar con él.
Puedo asegurarte que estas son todas las bases que necesitas. Tómalos como un estudió extra, paralelo a tus primeras materias. El resto vendrá a su tiempo de acuerdo a tu programa de estudios. Quizá podría agregar para los estudiantes de electrónica/ mecatrónica/ ing. eléctrica comprar y leer Fundamentos de Circuitos Eléctricos de Sadiku desde el primer momento que ponen un pie en la universidad. ¿Y que hay de la parte personal y social? Me tomaría una entrada entera... o puedes leer el resto del blog...
sábado, 9 de marzo de 2013
Arquitectura Maya
Algo que le pregunto a los arquitectos de México es: ¿porque no vemos oficinas de gobierno, monumentos y universidades construidos con arquitectura maya o azteca? ¿Porque no retomar este tipo de arquitectura tan imponente en todo el país? Espero esta recopilación de dibujos pueda servir para dar ideas para hoteles, restaurantes o edificios públicos. Pueden encontrar muchas más en éste enlace.
viernes, 1 de marzo de 2013
sábado, 23 de febrero de 2013
Convertidor Binario-BCD con displays en VHDL
Si consultaste Google, seguramente encontraste la función to_bcd()del blog VHDL Guru pero quizá te queden dudas sobre como implementarla en un código completo (Si, también tuve el mismo problema). Bien, en el caso del compilador ISE de Xilinx (se observará que estoy usando una tarjeta Basys 2) debe agregarse un archivo de paquete que incluya esta función. Esto puede hacerse usando la plantilla VHDL Package o creando simplemente un nuevo archivo .vhd en blanco y agregarlo al proyecto (El compilador detectará automáticamente que es un paquete al terminar de escribir el código).
El siguiente código es la correcta implementación del Paquete y Cuerpo de Paquete de manera que la función pueda ser utilizada en nuestro programa:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
package bcd is
function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector;
end bcd;
package body bcd is
function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
variable i : integer:=0;
variable bcd : std_logic_vector(11 downto 0) := (others => '0');
variable bint : std_logic_vector(7 downto 0) := bin;
begin
for i in 0 to 7 loop
bcd(11 downto 1) := bcd(10 downto 0);
bcd(0) := bint(7);
bint(7 downto 1) := bint(6 downto 0);
bint(0) :='0';
if(i < 7 and bcd(3 downto 0) > "0100") then
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 7 and bcd(7 downto 4) > "0100") then
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
if(i < 7 and bcd(11 downto 8) > "0100") then
bcd(11 downto 8) := bcd(11 downto 8) + "0011";
end if;
end loop;
return bcd;
end to_bcd;
end bcd;
Al guardar el código agregado al proyecto, la función se agregará automáticamente a la librería "work". De manera que habrá que usarla en nuestro programa:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.bcd.all; -- Aquí está nuestra función
entity display is
port ( salida : out std_logic_vector(7 downto 0);
selector: out std_logic_vector(3 downto 0);
binario : in std_logic_vector(7 downto 0);
clk : in std_logic );
end entity;
architecture mostrar of display is
signal a: std_logic_vector(1 downto 0) :=(others => '0');
signal PULSO: STD_LOGIC:='0';
constant SESENTA: integer :=99999;
signal RET: integer range 0 to SESENTA:=0;
signal BCD_out: std_logic_vector(11 downto 0);
signal bcd: std_logic_vector(3 downto 0);
begin
RETARDO: PROCESS(CLK) -- Divisor de frecuencia (de 50MHz a 50Hz)
BEGIN
IF (RISING_EDGE(CLK)) THEN
PULSO<='0';
RET<=RET+1;
IF RET=SESENTA THEN
RET<=0;
PULSO<='1';
END IF;
END IF;
END PROCESS;
process(pulso) begin -- Contador para selectores
if (pulso'event and pulso = '1') then
a <= a + 1;
end if;
end process;
BCD_out <= to_bcd(binario); -- Llamado a la función to_bcd
process (bcd) -- Decodificador BCD a 7 segmentos
begin
case bcd is
when "0000"=> salida <="00000011"; -- '0'
when "0001"=> salida <="10011111"; -- '1'
when "0010"=> salida <="00100101"; -- '2'
when "0011"=> salida <="00001101"; -- '3'
when "0100"=> salida <="10011001"; -- '4'
when "0101"=> salida <="01001001"; -- '5'
when "0110"=> salida <="01000001"; -- '6'
when "0111"=> salida <="00011111"; -- '7'
when "1000"=> salida <="00000001"; -- '8'
when "1001"=> salida <="00001001"; -- '9'
when others=> salida <="11111111"; -- 'x'
end case;
end process;
process (a) begin -- Ciclo de selectores
case a is
when "00" => bcd <= BCD_out(3 downto 0);
selector <= "0111";
when "01" => bcd <= BCD_out(7 downto 4);
selector <= "1011";
when "10" => bcd <= BCD_out(11 downto 8);
selector <= "1101";
when others => bcd <= "0000";
selector <= "1111";
end case;
end process;
end architecture;
miércoles, 13 de febrero de 2013
Suscribirse a:
Entradas (Atom)




