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 comentarios:

  1. el desarrollo es correcto pero, porque no compartes los archivos VI para facilitar el proceso?
    Gracias

    ResponderEliminar
  2. Puse un link con algunos de los archivos está en la parte superior de la página y dice:

    "AQUí ESTAN LOS ARCHIVOS PARA DESCARGAR"

    y la liga esta en:
    https://sites.google.com/site/dipuacj/files

    ResponderEliminar
  3. soy el anonimo anterior, gracias, te escribo desde hermosillo,, sonora mexico. carcas77@hotmail.com

    ResponderEliminar
  4. Gracias. Se agradece gente con esta iniciativa. En mi caso estudiante de ingeniería electrónica y mi aplicación será usada para un pfc de robótica. Un saludo

    ResponderEliminar
  5. Gracias por los comentarios, me alegra mucho que sirva de algo lo que he puesto aquí (a pesar que hace mucho que no actualizo nada), esa fue la razón de publicar esto.

    ResponderEliminar
  6. se necesita instalar algun toolkit para realizar este VI ???


    ya baje los archivos y pienso realizarlo
    buen aporte

    ResponderEliminar
  7. No es necesario ningún toolkit especial para ejecutarlo.

    Saludos

    ResponderEliminar
  8. Hola Gustavo muy interesante tu post, estoy tratando de convertir imagenes bmp a pgn en Labview, creo que podria partir de estos VIs para hacerlo, necesitaria algo mas?
    Saludos

    ResponderEliminar
  9. Buenos dias Luciano, si te puede servir, para empezar la clave esta en los dos formatos que quieres convertir, necesitas leer la imagen bmp, creo que para esto matlab ya tiene un VI que te dara como resultado una matriz de MxNx3, la cual tienes que manipular para convertir al formato que deseas.
    Solo tengo una duda, estas seguro que el formato es PGN? no encuentro ese, sera a caso PNG?

    Saludos!

    ResponderEliminar
  10. aca un ejemplo para controlar un servo con procesamiento digital de imagenes http://www.youtube.com/watch?v=2oMe8TEII9o&feature=g-upl&context=G2acb5cfAUAAAAAAAAAA

    ResponderEliminar

This is I

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