24 junio 2009

Visión por Computadora

¿Qué Visión por Computadora? Emular la visión humana por medio de una computadora. (¿Uhhh?)


El propósito de la visión por computadora es hacer lo que la visión humana hace, pero, por medios artificiales, para poder entender esto, primero hay que entender un poco como funciona la visión humana ¿no? Pues si, es ahí en donde empiezan los problemas. Nosotros tenemos los sentidos para percibir e interpretar nuestro medio ambiente, las cosas que nos rodean, es ahí donde comienza nuestra realidad. Físicamente, nuestros ojos nos sirven como una especie de sensores que captan las ondas luminosas que se reflejan en los objetos y los captura, los pasa al cerebro como impulsos eléctricos y el cerebro se encarga de hacer todo lo demás. (Que fácil se escucha todo esto, en realidad es mucho más complicado, pero a grandes rasgos así es).


El sensor que se encuentra en una cámara fotográfica la podemos comparar (en este caso) con los ojos, es la que nos permite captar las información de las ondas luminosas del ambiente y la convierte a impulsos eléctricos, aquí en este caso, la cámara también funge un poco como cerebro, puesto que procesa las señales eléctricas obtenidas del sensor y las acomoda en una forma que puedan ser transferidas a otro medio. Aquí, no se puede limitar a las cámaras fotográficas como único ejemplo, puesto a que también lo es un aparato de resonancia magnética, o bien, un ultrasonido.


Una parte muy importante en los sistemas de visión por computadora es la iluminación, ya sea la del ambiente o la propia del sistema. ¿Por qué es necesario un sistema de iluminación? Pues porque las condiciones de iluminación del objeto que vamos a capturar pueden afectar el objeto. Nuestro sistema de visión humano no necesita de tan preciso sistema de iluminación ya que puede distinguir los objetos ya que sus algoritmos son demasiado complejos y perfectos que no los podemos comprender. (Si, todavía soy de los que piensan que la computadoras no van a poder igualar el cerebro humano :P) La técnica a utilizar en el sistema va a depender puramente de la aplicación de la misma, esto es, no existe una técnica única para los sistemas de visión, y por lo consiguiente se tiene que analizar cual es la más apropiada para utilizar.


Bueno, si ya tenemos el sensor y la iluminación, ¿qué es lo que nos hace falta? pues la computadora, una vez que el sensor nos capturó la información y la convertimos de una manera que la computadora la pueda leer, pues lo que nos hace falta, son los algoritmos para procesar la imagen. ¡PUM!


Es ahí donde entra el procesamiento digital de imágenes, es emular lo que el cerebro hace, no los ojos, eso ya lo hicieron los sensores, ahora es el turno de emular al cerebro. (good grief!) Existen un gran número de algoritmos y técnicas de procesamiento de imágenes, y al pasar del tiempo se vuelven más complejos y pueden atacar problemas especificos que antes no era posible. Pero hay muchas cosas que el cerebro humano puede hacer y un sistema de visión no (¿por ahorita?)


On the Threshold of Eternity - VWVG



Por ejemplo, si vemos la imágen del gran Vicente, una persona puede decir muchas cosas, desde la combinación de colores, hasta temas filosóficos acerca del porque del sí. Pero, si esta imagen es alimentada a un sistema de visión por computadora, pues no serían más que una fila de ceros y unos, haría falta de aplicar ciertos algoritmos para obtener cierta información, pero solamente será la información para la cual esta diseñado el algoritmo. Una computadora no puede decir nada de la pintura, no puede saber que se quiso transmitir cuando el pintor pintó la obra, ni siquiera se deprime cuando ve la imagen, ni mucho menos se siente identificada con el hastío que le transmite, ni se siente de ese mismo modo.




Technorati : ,

Del.icio.us : ,

Zooomr : ,

Flickr : ,

12 junio 2009

Ejemplo de extracción de Bits a una imagen PGM en LabVIEW 8.6

El ejemplo a continuación hace exactamente lo mismo que este post pasado, pero esta ocasión esta implementado en LabVIEW, utiliza el código mostrado en el post anterior donde se carga una imagen PGM y se aplica la extracción de bits a la imagen leída y se muestra en pantalla.

El codigo siguiente muestra como se abre la imagen y se carga en pantalla, luego se obtiene el arreglo 1D de los datos y a ese buffer se le aplica la extracción  de bits y luego se muestra en pantalla.

 

Extraccion de Bits PGM

 

A continuación se muestra el código para realizar la extracción de bits al arreglo de 1D de bytes.

Bit Extraction to 1D U8 Array

Y así es como queda la imagen  de los chiles al extraer el bit mas significativo de la imagen.

ResultadoDeExtraccionDeBitsenLabVIEW

 

Este ejemplo me ha servido para aplicar la teoría en la práctica. Pues estoy haciendo la implementación de  los algoritmos a mano, es divertido. (uy si, definitivamente necesito una vida)

11 junio 2009

Ejemplo para cargar una imagen PGM en LabVIEW sin IMAQ

¡También LabVIEW puede Procesar Imágenes!

Je je, antes de que alguien del cuerpo técnico y ventas de National Instruments lea esto, mejor rectifico.

Dado a la naturaleza de LabVIEW también se pueden implementar un par de algoritmos (ja ja, de acuerdo, el universo de posibilidades es infinito, “the sky is the limit”) de la manera en que se haría con MATLAB (según un ingeniero de campo de NI me platicó que al principio eran una sola compañía lo que ahora es Mathworks y NI, pero en algún punto en el tiempo se separaron, así que se disputan el origen del engine de matrices ambos, claro que el inge de NI juraba que era de ellos, jeje, me imagino que dirían los de Mathworks) , ya saben el paradigma orientado a datos que manejan estos de National Instruments, claro ellos tienen un Toolkit dedicado al procesamiento de imágenes, pero este post se enfocará en implementarlo sin el uso del tan famoso Vision Development Module.

Como ya he puesto en otros posts vamos a leer imágenes PGM ya que LabVIEW no cuenta con una librería para leer este tipo de imágenes. Las imágenes PGM son ampliamente usadas para probar algoritmos de procesamiento digital de imágenes,  son fotos en escala de grises cada byte representa un pixel, es decir 8 bits, 256 posibles escalas de grises.

El ejemplo que propongo consta de un VI (instrumento virtual) principal y 3 subVIs. (Los VIs se pueden ver como la contraparte de las funciones en los programas por texto). La primera parte consta de leer un archivo del disco duro, se lee como archivo binario, como resultado de este se obtiene un arreglo de bytes que contiene los valores leídos en el archivo. En seguida pasa por un parser para el encabezado del archivo PGM, que básicamente comienza con dos bytes en ascii representando “P5”, en seguida viene el ancho, seguido del alto de la imagen, y para finalizar el nivel de grises en que está codificada la imagen. En medio de estos debe de estar como separador un espacio, ya sea un espacio en blanco (0x20), un carrier return (0x0D), un line feed (0x0A) o un tab (0x09). También hay que notar que después del “P5” se pueden tener comentarios y se identifican con el símbolo (#) al principio de la línea. Para más información del formato PGM, favor de ir a la página de la especificación.

A continuación se muestra el VI principal que realiza el leer el archivo, procesar la información y mostrarla en pantalla.

ReadPGM_CaseTrue

 

ReadPGM_CaseFalse

 

Una de las funciones del VI “ParsePGMHeader.vi” es determinar si es un archivo válido, es por eso que la salida del VI se alambra a un case para determinar si es válido y continuar o de lo contrario terminar el programa, como se observa en las figuras anteriores. Tengo que agradecer a un miembro del foro de NI (JB) de donde tome el VI para mostrar un msgbox en LabVIEW si lo necesitan pueden checar el foro. (n.d.r: el post es algo viejo y es para una versión de LabVIEW algo vieja por ende, y no se si la versión 8.6 ya tenga algo embebido). A continuación se muestra el diagrama a bloques de “ParsePGMHeader.vi”

ParsePGMHeader

Este parser lo que hace es que lee el bufer de bytes que se leen de el archivo y busca el encabezado, de ahí saca el ancho y el alto de la imagen, (tengo que confesar que este algoritmo no cumple completamente con la especificación, ya que asume que la imagen es de 256 niveles de grises, pero eso no es necesariamente cierto según la especificación; y entonces los pixeles ya no serían necesariamente de un byte, sino de dos. :S) Así como también, determina si es un archivo válido. En seguida lee el valor isPGM? y se mete a un case, para determinar si se continúa con la ejecución o se detiene le programa.

En caso de ser verdadero, se agarra el buffer de datos y se obtiene el buffer de la imagen, como datos de entrada se tiene la salida del VI anterior, el cual le pasa el buffer, en donde empieza la imagen y el ancho y alto de la misma. La salida de este VI nos da un arreglo en 2D conteniendo la imagen. A continuacion se muestra el diagrama del VI “GetPGMImageData.vi”.

GetPGMImageData La salida de este VI se usa para dibujar la imagen PGM en un objeto picture. También da como salida el ancho y alto de la imagen. En seguida se muestra el “DrawPGMImage.vi”. A la cual se le pasa como entrada el arreglo en 2D conteniendo la imagen y a la salida se le conecta  un objeto picture. El diagrama se muestra a continuación.

 

DrawPGMImage 

Al final en el VI se agrega un nodo de propiedades para poder modificar el ancho y alto de la imagen a mostrar, dependiendo del tamaño de la imagen original.

Como decía al principio, es que se trata de cargar la imagen sin necesidad de tener el Toolkit de procesamiento de imágenes, ya que trae integradas funciones para leer archivos png, jpg y bmp, pero no los pgm. Igual, si quieren los archivos para hacer pruebas solo mándenme un email y se los envío con gusto. Todavía ando viendo como hacerle para poder subir archivos y linkearlos al blog, creo que no me va a quedar de otra que usar un disco virtual.

Simple, ¿no?

10 junio 2009

Cómo mostrar una imagen transformada con fft2 en GUIDE usando MATLAB7

Este ejemplo es para complementar el ejemplo anterior de “Un ejemplo simple de una interfaz gráfica usando GUIDE en MATLAB para Procesamiento Digital de Imágenes”. En esa ocasión el énfasis que puse fue en mostrar como se crea la interfaz gráfica y como se muestra una imagen en pantalla. Ahora se muestra como agregar el código para mostrar la transformada de Fourier usando la función fft2 que viene incluida en MATLAB.

Si se sigue el ejemplo anterior solamente tendremos que agregar el siguiente código al callback del botón relacionado al procesamiento de la imagen.

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


guidata(hObject, handles);

% Carga la imagen de la variable global a una local.
mImage = handles.myImage;

% Calcula la transformada de fourier
mImage2 = fft2(double(mImage));
% Acondiciona la imagen para mostrar las magnitudes centradas
s = fftshift(log(abs(mImage2)));
limites = [(min(s(:))) (max(s(:)))];
set(handles.axes2, 'CLim', limites);
image( s, 'Parent', handles.axes2, 'CDataMapping', 'scaled');
axis(handles.axes2, 'off');
guidata(hObject, handles);

No tengo manera de subir los archivos todavia, y no quiero ponerlos en un servidor externo así que si alguien le interesa alguno de los ejemplos que aqui se ponen, simplemente manden un email y se los mando

This is I

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