28 julio 2011

Algoritmo de detección de iluminación defectuosa en indicadores de paneles de instrumentación – Parte I (Teoría)

 

El Presente proyecto fue realizado en Mayo del 2009 como proyecto final para una materia de Procesamiento Digital de Imágenes en la Maestría en Ciencias en Ingeniería Eléctrica en la Universidad Autónoma de Ciudad Juárez (UACJ).

 

Definición del Problema

En una empresa donde se manufacturan componentes electrónicos para la industria de la transportación se tiene un indicador analógico usado en camiones pesados y casas rodantes. Este indicador cuenta con iluminación de fondo, como es común en los vehículos automotrices para poder leer el indicador en condiciones de poca luz.

La iluminación esta dada por tres diodos emisores de luz (LED: Light Emisor Diode) ensamblados en la tablilla electrónica (PCB: Printed Circuit Board), la luz se distribuye por medio de un reflector plástico y se proyecta en la pantalla que contiene la graduación para la que esta diseñado. En la figura 1 se muestra un bosquejo de la posición de los LEDs en el objeto bajo prueba, aquí se muestra sin la pantalla para poder mostrar la localización de los emisores de luz. En la figura 2 se muestra una vista lateral para indicar de manera general la construcción del objeto bajo prueba en la parte de iluminación.

clip_image001

Figura 1. Vista superior del objeto bajo prueba

clip_image002

Figura 2. Vista lateral del objeto bajo prueba

El problema se presenta cuando uno o más de los indicadores no encienden por alguna razón, esto es algo común en una ambiente de producción en serie, es por eso que se cuenta con un equipo de prueba funcional, el cual tiene la necesidad de detectar este tipo de defectos. Por ejemplo un objeto defectuoso es cuando uno de los Led mostrados en la figura 1 no prende o no esta presente. No es una tarea trivial detectarlos en con un sistema de visión, debido que el objeto bajo prueba tiene la pantalla que sirve para difuminar la luz junto con el reflector y no es fácil determinar cuales son las características necesarias para discriminar un objeto bueno de uno defectuoso.

Desarrollo.

Se cuenta actualmente en la línea de producción con un equipo de prueba funcional, con un sistema de visión, con el cual se ejercita el indicador tal y como si estuviera instalado en el vehiculo y se verifica que sea funcional. El objetivo del presente proyecto es para agregar la funcionalidad de que revise cuando uno de los emisores de luz esta faltante o no enciende.

El equipo consta de una computadora personal para adquirir la imagen, hacer el procesamiento y controlar los instrumentos del equipo. Cuenta con una cámara industrial de 1.3 megapíxeles con interfase USB. El objeto bajo prueba y la cámara se encuentran en un gabinete cerrado para minimizar el efecto de la iluminación a causa de la variación en la iluminación externa. A continuación se presenta en la figura 3 un dibujo básico de los componentes del sistema de visión. En este no se incluye todo lo relacionado con el control del mecanismo y la alimentación del objeto bajo prueba.

clip_image003

Figura 3. Diagrama básico del sistema de visión

En la figuras 4 y 5 se muestran ejemplos de objetos reales tomados con el sistema de visión descrito en el párrafo anterior. Se muestran ejemplos de dos tipos de indicadores, los cuales podemos separar en dos tipos, unos con fondo blanco y otros con fondo negro. Al ser diferentes los fondos el tipos de características en cada imagen es totalmente diferente, es uno de los objetivos de este trabajo el definir características en común para ser usadas como límites de pasa o falla.

En la figura 4 se muestran los indicadores con fondo blanco, la primera imagen muestra como se ve cuando una pieza esta correcta y los incisos restantes muestran los tipos de casos cuando faltan los emisores de luz del 1 al 3. En la figura 5 se muestran los mismos tipos de ejemplos pero en este caso para los indicadores con fondo negro.

Para realizar el procesamiento de las imágenes se usará el software MATLAB versión 7.0.0.19920 (R14) y el Toolkit de procesamiento digital de imágenes. El formato de la imagen a utilizar en este ejemplo es el formato PGM[1] (Portable GrayMap). Al leer la imagen con MATLAB se obtiene una matriz bidimensional de tipo uint8 y las dimensiones son definidas por el tamaño de la imagen, ya que cada píxel es representado por un byte de la matriz, con valores de 0 a 255 en escala de grises.

clip_image005

Figura 4.Ejemplo de indicadores con fondo blanco

a) LEDs correctos b) LED 1 Defectuoso c) LED 2 Defectuoso d) LED 3 Defectuoso

clip_image007

Figura 5. Ejemplo de indicadores con fondo negro

a) LEDs correctos b) LED 1 Defectuoso c) LED 2 Defectuoso d) LED 3 Defectuoso

Se utilizó la siguiente metodología para resolver el problema. Para poder resaltar las características de la imagen, se hicieron pruebas con varias técnicas de mejoramiento de imagen y también se le aplicaron diferentes técnicas de segmentación para resaltar dichas características que nos ayuden a determinar un parámetro confiable de segregación.

El método de extracción de bits se aplicó a las imágenes con el fin de segmentar la imagen y obtener una imagen binarizada como resultado. Anil K. Jain[2] explica la extracción de bits en una imagen y define al píxel u de la siguiente manera:

clip_image009

Y se requiere que nuestro píxel resultado v de la extracción de bit sea:

clip_image011

El autor define kn como se muestra a continuación:

clip_image013

En donde:

clip_image015

  • u, es el valor del píxel al que le vamos a extraer el bit
  • B, es el número de bits usado para representar un píxel
  • n, es el bit que queremos extraer de cada píxel, B es el menos significativo y 1 es el más significativo
  • L, es en nivel máximo que puede tener nuestra imagen

A continuación se muestra el código de MATLAB para implementar la extracción de bits:

function x = BitExtraction(myImagen, B, n ,L)

myImagenNueva = myImagen;

[rows cols] = size(myImagen);

for I = 1 : rows

for j = 1 : cols

u = double(myImagen(I,j));

iEne = floor(u/2^(B-n));

iEneMenosUno = floor(u/2^(B-(n-1)));

BitExtraido = iEne – (2*iEneMenosUno);

if BitExtraido == 1

BitExtraido = L;

else

BitExtraido = 0;

end

myImagenNueva(I,j) = BitExtraido;

end

end

x = myImagenNueva;

Código 1. Función en MATLAB para realizar extracción de bits a una imagen PGM

En las siguientes figuras se observan ejemplos de extracción del bit más significativo aplicados a un indicador no defectuoso y los casos de indicadores defectuosos.

clip_image017clip_image019

Figura 6. Ejemplo de extracción del bit más significativo del inciso a) y b) de la figura 4

clip_image021clip_image023

Figura 7. Ejemplo de extracción del bit más significativo del inciso c) y d) de la figura 4

clip_image025clip_image027

Figura 8. Ejemplo de extracción del bit más significativo del inciso a) y b) de la figura 5

clip_image029clip_image031

Figura 9. Ejemplo de extracción del bit más significativo del inciso c) y d) de la figura 5

Las figuras 6 y 7 nos muestran las imágenes con el bit más significativo extraído de la figura 4, éstas son para el caso con los indicadores con fondo blanco. Las figuras 8 y 9 son los equivalentes de la figura 5 y son para el caso con indicadores con fondo negro.

Como se puede observar en las imágenes anteriores al aplicarles el método de extracción de bits, la falta de luz debido al componente emisor de luz faltante se acentúa resaltando dicha característica en las imágenes. También se puede apreciar que la diferencia se ve marcada en una circunferencia hacia la orilla del perímetro del indicador. Para obtener una imagen con que resalte de una manera mas eficiente las características se puede enmascarar la imagen y extraer solamente la región de interés para ser analizada posteriormente y en base a eso decidir si el objeto bajo prueba es defectuoso o no.

El siguiente código en MATLAB muestra la función usada para extraer la región de interés en este caso.

Function imMasked = maskDonnutRegion(myImage, CentX, CentY, Rinf, Rsup)

h=CentX; k=CentY;

N=1024; t=(0:N)*2*pi/N;

x = Rsup*cos(t)+h;

y = Rsup*sin(t)+k;

BW = roipoly(myImage,x,y);

mask1 = uint8(BW); t=(0:N)*2*pi/N;

x = Rinf*cos(t)+h; y = Rinf*sin(t)+k;

BW = roipoly(myImage,x,y);

mask2 = uint8(~BW);

imMasked = uint8(myImage).*mask1.*mask2;

Código 2. Función en MATLAB para realizar la selección de la región de interés

En el código anterior se usa la función roipoly[3] incluida en MATLAB y se usa para seleccionar una región poligonal de interés. Para este ejemplo el polígono se define de manera de círculo, y se usan dos círculos para definir el perímetro superior y el perímetro inferior en el cual se va a enmascarar la imagen.

A continuación se muestra los ejemplos de las imágenes resultado de la extracción del bit más significativo.

clip_image033clip_image035

Figura 10. Ejemplo de selección de región de interés del ejemplo de la figura 6

clip_image037clip_image039

Figura 11. Ejemplo de selección de región de interés del ejemplo de la figura 7

clip_image041clip_image043

Figura 12. Ejemplo de selección de región de interés del ejemplo de la figura 8

clip_image045clip_image047

Figura 13. Ejemplo de selección de región de interés del ejemplo de la figura 9

Como se puede apreciar en las imágenes anteriores se observa que la imagen resultante muestra cambios significativos entre las imágenes que no presentan defectos (primera imagen de las figuras 10 y 12) y las imágenes defectuosas.

A las imágenes resultantes se les aplicaron dos técnicas de medición estadísticas para analizar los resultados y ver si se pueden definir los límites para determinar si la imagen es buena o mala.

Una de las mediciones usadas es la media, la cual calcula el promedio de los valores de la imagen. La función usada es mean, se representa de la siguiente manera.

clip_image048

También se calculó la desviación estándar de las imágenes procesadas. La desviación estándar se representa de la siguiente manera. La función usada es std[4].

clip_image049

Una tercera técnica usada es la entropía, la función usada es wentropy[5], ésta función es usada para criterios de selección debido a que describe propiedades relacionadas con la información de una señal dada, en este caso una imagen en escala de grises. La definición de la función usada esta dada por:

clip_image050

clip_image051

clip_image052


[1] http://netpbm.sourceforge.net/doc/pgm.html

[2] Jain, Anil K. Fundamentals of Digital Image Processing, Prentice Hall, 1989, USA

[3] Ver ayuda de MATLAB: help roipoly

[4] Ver ayuda de MATLAB: mean y std.

[5] Ver ayuda de MATLAB: doc wentropy. Esta función esta incluida en el toolbox de wavelets.

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 inspiración no vino sola, gracias I :),

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.

¿Qué he escrito?

This is I

Mi foto
Blog dedicado a escribir sobre procesamiento digital de imagenes y dudas existenciales. / Blog to write about digital image processing and existencial doubts.

Cuenta Cuantos