25 abril 2011

Ejemplo simple de Listbox en GUIDE de MATLAB 7.0

En el siguiente ejemplo se muestra como agregar un Listbox, introducir nuevos elementos a la lista y desplegar un valor seleccionado de la lista. El código se puede descargar aquí. La explicación paso a paso va como sigue:

Iniciamos tecleando “guide” desde la línea de comandos de MATLAB como se muestra en la siguiente figura:

image

Y nos mostrará el cuadro de dialogo de GUIDE como se muestra en la imagen siguiente:

image

Elegimos “Blank GUI (Default)” y presionamos “OK”, dependiendo de la velocidad de la máquina con que estemos trabajando nos mostrará el siguiente cuadro de dialogo… hay que esperar a que se inicialice todo.

image

Enseguida nos muestra la pantalla principal de GUIDE, que es donde vamos a empezar a agregar controles para hacer nuestra aplicación.

image

En este punto es bueno grabarlo con un nombre, por si las dudas para si algo, para poderlo estar grabando continuamente. En este caso yo lo nombré: “Ejemplo_ListBox.fig”, automáticamente genera el código “Ejemplo_ListBox.m” en el que vamos a estar trabajando.

A continuación seleccionamos la herramienta “Listbox” y dibujamos la lista en el área de trabajo como se puede observar en la imagen siguiente:

image

Una vez con el control “Listbox” en el área de trabajo lo siguiente es personalizarlo, para darle un nombre e inicializarlo de requerirse así. Tenemos que dar click izquierdo sobre el control y seleccionar “Property inspector” como se muestra en la imagen siguiente:

image

Una vez seleccionado “Property Inspector” nos debe aparecer una ventana como se muestra a continuación:

image

En la imagen anterior se muestran todas las propiedades de nuestro control, para este ejemplo solamente modificaremos los campos de:

1. String: Que es básicamente el texto que aparece en nuestra GUI

2. Tag: Que es el nombre que tiene en nuestra aplicación este objeto

Si lo ejecutamos (Ctrl + T) en este momento, debemos tener una ventana como se muestra a continuación:

image

Ahora vamos a agregarle un botón para mostrar en un mensaje el texto que tenemos seleccionado en el “Listbox”, yo lo llame “miBoton” y le puse “Mostrar Selección”

image

Ahora tenemos que agregarle código al botón para que muestre lo que tenemos seleccionado, para eso tenemos que dar click derecho sobre el botón y seleccionar “View Callbacks –> Callback” como se muestra en la imagen siguiente:

image

La pantalla siguiente nos lleva a nuestro editor y se muestra seleccionado el inicio del callback, notese que el callback es donde agregamos el código de la acción que va a realizar nuestro objeto, en este caso el botón.

image

Ahora agregamos el siguiente código en el miBoton_Callback:

% --- Executes on button press in miBoton.
function miBoton_Callback(hObject, eventdata, handles)
% hObject    handle to miBoton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

miTexto = get(handles.miCajaDeLista,'string'%Obtiene todos los valores de la lista

indice_seleccionado = get(handles.miCajaDeLista,'Value'); %Nos dice que posición esta seleccionada

h = msgbox(miTexto,'¿Qué tenemos?','help')    %Muestra la selección en una caja de texto

El código anterior simplemente muestra la selección en una caja de texto, para mostrar como agregar items en tiempo real a la lista acomodamos el tamaño de la lista y agregamos otro botón para introducir lo que nosotros necesitemos en el “Listbox”, como se muestra en la imagen siguiente:

 

image

A continuación se muestra el código de Agregar_Listbox_Callback, con este código se agrega un nuevo Item en la lista.

% --- Executes on button press in Agregar_Listbox.
function Agregar_Listbox_Callback(hObject, eventdata, handles)
% hObject    handle to Agregar_Listbox (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Muestra un cuadro de dialogo para introducir un nuevo item en la lista
prompt = {'Nombre'};
dlg_title = 'Agrega un Item a la Lista';
respuesta  = inputdlg(prompt,dlg_title);

% Obtiene todos el contenido de la lista
t = get(handles.miCajaDeLista, 'String');
if ischar(t); t = cellstr(t); end

% Agrega el nuevo Item en la lista
t = [t; respuesta];
% Muestra el nuevo Item en la lista
set(handles.miCajaDeLista, 'String', t);

A continuación se muestra como se ve cuando ejecutamos el GUI y le agregamos un nuevo Item.

image

Y como se despliega el Item seleccionado en el “Listbox”

image

01 diciembre 2010

Implementación de un cuantizador “midtread” en MATLAB 7.0

La cuantización es el paso necesario para convertir una señal analógica a una digital, cuando se muestrea una señal se convierte del mundo analógico al mundo digital, y es necesario expresarlo en 0s y 1s, dícese bits. Aunque no necesariamente es el proceso de una señal analógica per se, puede ser también, por ejemplo, una imagen que necesita ser representada con una cantidad menor de bits, y por lo consiguiente comprimirla, con pérdidas claro está.

Existen variados tipos de cuantización. El tipo de cuantizador se elige dependiendo de la aplicación en que vaya a ser implementado, esto, de acuerdo a las características de la señal. En este caso se hará un pequeño ejemplo con un cuantizador midtread la grafica siguiente muestra el comportamiento de un cuantizador midtread de 3bits.

cuantización

Figura 1. Características de un cuantizador midtread de 3 bits

El principal uso de este cuantizador es cuando tenemos una señal simétrica en el espectro positivo y negativo, por ejemplo una señal de audio, aunque también se puede aplicar en una imagen, como se muestra en el párrafo siguiente.

En la Figura 1 el eje equis (x) representa la señal a cuantizar y el eje ye (y) es la información ya cuantizada, delta () son los incrementos en los que se va a dividir la señal y esto depende del número de bits que sea el cuantizador, de lo anterior se puede desprender la siguiente tabla:

Código binario Nivel de Cuantización (y) Rango de la señal de entrada (x)

011

-3∆

–3.5∆ <= x < –2.5∆

010

-2∆

–2.5∆ <= x < –1.5∆

001

-1∆

–1.5∆ <= x < –0.5∆

000

0

–0.5∆ <= x < 0

100

0

0 <= x < 0.5∆

101

1∆

0.5∆ <= x < 1.5∆

110

2∆

1.5∆ <= x < 2.5∆

111

3∆

2.5∆ <= x < 3.5∆

La variable delta (∆) puede ser calculada de la siguiente manera

clip_image002

Ora si, vamos a ver el siguiente ejemplo, tenemos la señal de entrada x(n) = 254 254 252 254 255 253 y el rango válido de datos es de 250 a 255, que bien puede ser parte de una imagen ;) .

El primer paso es calcular delta.

clip_image002[4]

Sustituyendo ∆ en la tabla anterior tenemos:

Código binario Nivel de Cuantización (y) Rango de la señal de entrada (x)

011

-3(0.71428) = -2.14284

–2.5 <= x < –1.7857

010

-2(0.71428) = -1.42856

–1.7857 <= x < –1.07142

001

-1(0.71428) = 0.71428

–1.07142 <= x < –0.35714

000

0

–0.35714 <= x < 0

100

0

0 <= x < 0.35714

101

1(0.71428) = 0.71428

0.35714<= x < 1.07142

110

2(0.71428) = 1.42856

1.07142 <= x < 1.7857

111

3(0.71428) = 2.14284

1.7857 <= x < 2.5

Para poder tener los datos de forma como se muestra en la Figura 1, es necesario definir cual es la media de nuestro rango, que en este caso es:

clip_image002[6]

Si restamos a la señal de entrada la media obtenida en el paso anterior tenemos que:

x(n) – µ = 1.5 1.5 -0.5 1.5 2.5 0.5

ahora el siguiente paso es cuantizar cada valor utilizando la tablita arriba descrita…

x(0) = 1.5, cae entre 1.07142 y 1.7857 a lo cual corresponde un valor de cuantización de 1.42856 o sea 110 binario.

x(1) = 1.5, cae entre 1.07142 y 1.7857 a lo cual corresponde un valor de cuantización de 1.42856 o sea 110 binario.

x(2) = –0.5, cae entre –0.35714 y –1.07142 a lo cual corresponde un valor de cuantización de –1.42856 o sea 010 binario.

x(3) = 1.5, cae entre 1.07142 y 1.7857 a lo cual corresponde un valor de cuantización de 1.42856 o sea 110 binario.

x(4) = 2.5, cae entre 1.7857 y 2.5 a lo cual corresponde un valor de cuantización de 2.14284 o sea 111 binario.

x(5) = 0.5 cae entre 0.35714 y 1.07142 a lo cual corresponde un valor de cuantización de 1.42856 o sea 010 binario.

A continuación se presenta el código en MATLAB 7.0 para llevar a cabo esta cuantización:

x = [254 254 252 254 255 253];

bits = 3;
rango_superior = 255;
rango_inferior = 250;

delta = (rango_superior - rango_inferior)/((2^bits)-1)

mu = ((rango_superior - rango_inferior)/2) + rango_inferior

x_centrada = x - mu

x_cuantizada = floor(x_centrada/delta+0.5) * delta

y los resultados son:

delta =

    0.7143

mu =

  252.5000

x_centrada =

    1.5000    1.5000   -0.5000    1.5000    2.5000    0.5000

x_cuantizada =

    1.4286    1.4286   -0.7143    1.4286    2.8571    0.7143

29 noviembre 2010

DPCM (Differential Pulse Code Modulation), Método diferencial para compresión de señales, Parte I, puro rollo

La teoría del siguiente choro mareador y las figuras pirateadas fueron tomad@s de:
Data Compression: The Complete Reference. David Salomon. Fourth Edition. Springer. 2007. Section 4.26: DPCM
Digital Signal Processing: Fundamentals and Applications. Li Tan. Academic Press. 2008. Section 11.3: Examples of Differential Pulse Code Modulation, and Adaptive DPCM G.721

La compresión por DPCM es parte de la familia de métodos compresión por codificación diferencial. La idea general es usar valores pasados recuperados como base para predecir el dato actual de entrada. Esto se basa en el hecho, por ejemplo, que los pixeles en una imagen o muestras adyacentes en el audio digitalizado se encuentran correlacionadas. Los valores correlacionados son generalmente similares, así que sus diferencias son pequeñas, esto resultando en una compresión.
A continuación se muestra el esquema simple de compresión diferencial para poder entender el principio del DPCM.

image

                           Codificador                                 Decodificador
Figura 1. CoDec Diferencial

La imagen anterior muestra un ejemplo de un codificador diferencial, se observa como el dato actual image se almacena en una unidad de almacenamiento, llámese “Delay” (o retardo pues si no les gusta agringarse), para ser usado para codificar el siguiente dato, o sea, image. Claro, la explicación anterior esta sumamente simplificada, en este ejemplo se muestra el uso de un cuantizador, eso significa que se tiene una compresión con perdidas o “lossy” y esto significa que nuestro dato codificado es realmente image el cual ya contiene un error de cuantización. Esto significa que la codificación por diferencias (o diferencial, como ustedes gusten y manden) nos mete en un nuevo problema: La acumulación de errores.
Entonces hay que tomar ventaja de lo que se menciona anteriormente, los datos que se van a comprimir están correlacionados. Esto significa que en general un dato depende de varios de sus vecinos, no solamente del anterior. Una mejor predicción puede ser lograda usando N de los datos previos para codificar el valor actual image, entonces tendremos una función image image, para predecir el dato actual image.
Ora si, en seguida pueden observar (jeje, como visita al museo) el diagrama del DPCM. (oooooohhhh!)

image
                          Codificador                                   Decodificador
Figura 2. DPCM
Oquey, oquey, haber encuentren la(s) diferencia(s) entre la Figura 1 y la Figura 2. ¿Está fácil? ¿que no? …
Pues si, cambiamos “Delay” por “Pred.” y se acabo el asunto.
Si.
Como se explicaba antes, el predictor viene siendo la funcioncica esta:
imageimage
En donde tenemos que es una función que nos afecta un conjunto de N pixeles y en base a esto obtenemos una mejor predicción de nuestro valor actual, es decir tratamos de minimizar el error introducido por la cuantificación.
Esta es la primera parte de dos, en esta ocasión fue el rollo previo a un ejemplo peque para poder explicar la DPCM.

06 octubre 2009

¿Qué Onda?: Fundamentos Matemáticos de las WAVELETS. Parte I

Lo que se presenta a continuación es basado en un artículo de Albert Cohen y Jelena Kovacevic llamado Wavelets: The Mathematical Background.

 

Cuando se tiene una señal, existen una gran cantidad de maneras de representarla y en base a lo que necesitamos hacer con dicha señal es que elegimos la manera en que va a ser tratada. El objetivo es que la información obtenida de la señal tenga significado para nosotros, es ahí dónde se pueden lograr varios acercamientos. Entre ellos se encuentran la multiresolución y las transformaciones de dominio.

La multiresolución a grandes rasgos es ir representando la información de manera que los detalles son agregados de forma sucesiva. Para la representación de una señal, uno de los temas que se utilizan ampliamente son las transformaciones de dominio y con ello es menester hablar una de las técnicas más aplicadas, la transformada de Fourier. Con la transformada de Fourier cambiamos la representación de una señal en el dominio del tiempo al dominio de la frecuencia, pero no podemos saber en que instante de tiempo está ubicada la frecuencia, esto es en algunos casos una limitación.

Una manera de darnos una idea de la localización en tiempo de la frecuencia es construir bloques y aplicarles la transformada de Fourier. Si tenemos que clip_image002 es una señal de frecuencia, con Fourier obtenemos un pico en la frecuencia clip_image004 dada. A partir de esto podemos expresar clip_image006 dónde clip_image008 es la ventana usada para localizar la frecuencia en el tiempo, a esto se le llama Short-time Fourier Transform (STFT). Una de las principales desventajas con la STFT es que la localización en el espacio tiempo es fija. Con las wavelets se tiene un acercamiento diferente, la localización de la frecuencia es logarítmica y proporcional al nivel de frecuencia.

Se puede definir una familia de funciones de la siguiente manera que nos permita tener una representación en la escala del tiempo

clip_image010,

clip_image012

(1)

dónde clip_image014 es una función fija llamada “wavelet madre”, a representa el escalamiento de la función y b son los corrimientos en el tiempo.

Basado en la función representada en (1) y tomando en cuenta que es un espacio de Hilbert, se define la transformada de una función f de la siguiente manera:

clip_image016

(2)

Para que la transformada (2) pueda ser invertible, se tiene elegir una clip_image014[1] de manera que cumpla con la condición de admisibilidad mostrada a continuación:

clip_image018

(3)

Y para asegurar que la integral es finita se debe cumplir que clip_image020. En base a lo anterior tenemos que se puede reconstruir mediante:

clip_image022

(4)

Prácticamente, una transformada wavelet continua se aplica a una serie de puntos discretos de manera clip_image024. Si se restringe la transformada continua wavelet de manera que clip_image026, dónde clip_image028entonces para valores fijos clip_image030 y clip_image032. Entonces podemos definir la función wavelet de manera general cómo:

clip_image034,

clip_image036

(5)

Para saber si la transformada wavelet en el caso discreto caracteriza completamente la función f y logra reconstruirla de manera estable, se requiere introducir el concepto de frames.

Para que un frame exista, y por lo tanto reconstrucción a partir de la wavelet, se debe tener una secuencia clip_image038en un espacio de Hilbert H si para cada x perteneciente al espacio H se cumple lo siguiente:

clip_image040

(6)

En dónde los límites clip_image042 son independientes de x. A dicha secuencia se le asocia al operador F que representa a clip_image044y también se desprende de ahí F* que asocia la sumatoria de las secuencias clip_image046 en clip_image048.

La desigualdad expresada en (6) puede ser expresada en términos del operador hermitiano F* F de manera que:

clip_image050

(7)

En base a lo anterior podemos definir una secuencia clip_image052 dada por clip_image054 que también constituye un frame llamado dual frame con límites en clip_image056 y se asocia con el operador llamado clip_image058 por lo consiguiente tenemos que:

clip_image060

(8)

Y también tenemos que clip_image062 así que una x que forma parte del espacio de Hilbert es representada por:

clip_image064

(9)

Para reconstruir x debemos conocer clip_image052[1]. Teniendo en cuenta que:

clip_image066

(10)

Dónde el operador residual clip_image068 satisface lo siguiente:

clip_image070

(11)

Sustituyendo en (7) nos da como resultado la siguiente ecuación:

clip_image072

(12)

Si tenemos que A=B=1 después de renormalizar, entonces podemos definir lo siguiente:

clip_image074

(13)

De manera que elegimos valores de A-B/A+B que se aproximan a cero y también A y B de manera arbitraria cercanos a uno seguido de una renormalización, eligiendo valores a0 y b0 cercanos a uno y cero respectivamente. Lo anterior significa que se ha hecho un sobre-muestreo de la wavelet continua en un arreglo bastante denso. Una de las aplicaciones más usadas para usar el sobre-muestreo empleando frames es el de reducir el error de reconstrucción con una relación basada en el sobre-muestreo.

 

Continuará…

This is I

Blog dedicado a escribir sobre Sistemas Embebidos y el Internet de las Cosas o IoT que le llaman.