
Lector de códigos QR
Mi proyecto como ya se ha visto en presentaciones pasadas es un lector de códigos QR, la finalidad es que el lector tenga un alcance mucho mayor que los lectores normales.
¿Por que un lector de códigos QR?
La tecnología es de estos códigos no es realmente nueva pero en los últimos tiempos se ha incrementado considerablemente el uso de los mismos. Los podemos ver en periódicos, revistas, anuncios en la calle y en distintos edificios (al menos en mi cuidad), por lo cual considero que es una habilidad muy útil tener conocimiento técnico de los mismos y poder crear un software que sea capaz de identificarlos y leerlos.
Además de todo esto, el proyecto no se planea dejar aquí, si no que tengo la intención de reutilizarlo en un momento futuro. Uno de los usos que le pienso dar es crear una versión para la construcción de la tesis de un compañero en donde se pretende utilizar los códigos en conjunto con robots inteligentes, que usen los robots para identificarse unos con otros.
Algunos otros usos de los códigos QR:
- Publicidad
- Orientación de robots
- Orientación sobre sitios
- Tarjetas de presentación
- Información de piezas en museos
- Información de productos
Dado que los QR code trabajan con visión computacional y esta rama tambien se utilizara para realizar realidad aumentada, es fácil implementar un sistema de realidad aumentada apoyándose en estos códigos. Tengo que aceptar que una de mis primeras ideas cuando me imagine el proyecto, fue utilizar QR codes con realidad aumentada en mi tarjeta de presentación.
En este vídeo me pareció muy interesante pues la persona se tatuó una especie de QR code en el pecho y utiliza realidad aumentada para correr una animación:
El siguiente vídeo se muestra diferentes figuras 3D dibujadas sobre QR codes impresos sobre tarjetas de papel:
Diseño del software
En un pricipio se planteó realizarse de la manera en que se muestra en el diagrama de secuencias inferior, teniendo solamente dos clases.
Pero debido a que el proyecto no es en sí muy extenso si no que es complicado, en algunas de sus partes y requirió mas un análisis de sus partes y de que filtros y métodos que iban a ser utilizados. En el diagrama superior se muestran los pasos que se tenían planeados y esos en realidad no han cambiado. Lo que pretendo ahora mostrar es los filtros que se utilizaron en la detección y el orden, dado que el código tiene un paradigma funcional, mostrare los pasos con el siguiente diagrama de flujo.
En el diagrama de flujo de muestran los pasos que se siguieron para poder detectar el QR y su posición.
¿Como funciona?
El programa generado se puede dividir en dos partes, en la primera que genera un preprocesamiento para encontrar con mayor facilidad espacios en los que puede haber un código QR:
- Primero se obtiene un "frame" de la cámara.
- Se modifica su tamaño a un maximo de 128x128.
- Se convierte a escala de grises.
- Se calcula el gradiente en vertical y horizontal utilizando una mascara de Sobel.
- Se hace una copia de la imagen.
- Se aplica un filtro de media a la copia de la imagen.
- Se resta la copia con filtro de la media a la imagen original.
- Se aplica un filtro Blur por ahora la intensidad del filtro es constante pero se buscara a futuro que esta cambie dependiendo de la mancha que se forma.
- Se aplica un filtro umbral.
- Después se recorre cada mancha con un BFS y se encuentran las dimensiones de un rectángulo que rodé cada mancha.
- Se recorta el pedazo donde esta el código QR en la imagen original la que tiene el tamaño original, que sera nuestra nueva imagen de trabajo.
- Se modifica el tamaño de la nueva imagen a 128x128.
- Se aplica un filtro para mejorar el contraste utilizando histogramas.
- Después de recorre cada fila de la imagen y se restan los vecinos de la derecha y de la izquierda de cada pixel, a este valor se le aplica un umbral para decidir si dicho pixel sera blanco o negro, por ahora de 120 pero se buscara después que se adapte a los valores de la imagen.
- Ahora que tenemos blancos y negros bien definidos, se recorre cada fila buscando las esquinas del código QR que tienen un patron de blancos y negros parecido a este: Negro, Blanco, Negro, Negro, Negro, Blanco Negro. Una vez encontrada una fila con ese patrón se busca en las columnas para asegurar que sea dicho cuadrado. Si tiene las características deseadas la función regresa un valor boolean con valor True.
- para poder obtener la matriz de los datos del código QR, lo que se quiere hacer es dividir la imagen en una malla, después verificar celda por celda de la maya obteniendo el porcentaje de blancos y negros en la imagen estos valores servirán como medida de probabilidad de ser blanco o negro, con esto definiremos por medio de umbrales si el valor es un negro, un blanco o si simplemente no podemos determinar que valor es.
- Una vez que tenemos el código de dos dimensiones, necesitamos decodificarlo utilizando algoritmos para decodificar códigos Solomon, pero debido a que implementar estos algoritmos aun es un poco avanzado para mí, buscaré una implementación ya existente que se pueda adaptar a mí código.
Desempeño
Para medir el desempeño del programa se midieron los frames por segundo que se calcularon a partir del tiempo de ejecución en diferentes ámbitos, los tres que se eligieron fueron los que creí que serian los más comunes en la forma en la que se usara para el proyecto de ubicuo.
Este primero muestra los frames por segundo en un ambiente estático, este solo se tomo tiempos poniendo la cámara en una sala sin personas.
En el siguiente no se escanea un código QR aun, pero se pone la cámara en una sola con multiples personas y además se genera gran cantidad de movimiento frente a la cámara.
En este ultimo caso solo se encuentra una persona en la sala y esta escanea un código QR durante el tiempo que se tomaron las medidas.
Conclusiones
El tiempo de lectura estático es algo más o menos decente, puesto que casi alcanza los 20 frames por segundo los cual es aceptable si se fuera a mostrar en un vídeo lo que se muestra en la cámara, Los frames por segundo de lectura con el código QR bajan notablemente casi hasta alcanzar números negativos, lo cual no es un problema si solo se utiliza leen códigos durante cortos periodos de tiempo.
El problema esta en que en un espacio con movimiento tienes picos donde el tiempo se eleva considerablemente.
Tomando en cuenta esto se considera que podría producir un desgaste de energía quizás innecesario, espero que estos números mejoren utilizando mejores filtros de reducción de ruido y encontrando una característica en las esquinas de los QR en imágenes que me permita reducir el tiempo de ejecución, para dar espacios de descanso a la maquina.
Librerías utilizadas
Para el proyecto se planteó utilizar las siguientes librerías:
- Opencv: Para usar la cámara web y algunos filtros de la librería.
- QR Tools para decodificar la matriz obtenida.
Pero debido a la falta de tiempo aun no se ha decodificado la matriz de el QR, así que la única librería que se utilizo fue Opencv para llevar a cabo todo el proceso de visón computacional.
Trabajo a futuro
Ahora hablare de algunas de las características del código QR que quiero agregar y mejorar.
Mejorar la detección
Se plantea que el QR sea detectable desde largas distancias, para eso se hace un preprocesamiento buscando figuras que tengan las características que tienen los QR codes antes de verificar que lo sean, la meta es mejorar este algoritmo agregando que el tamaño en el que se esparcen las orillas detectadas varié dependiendo de la distancia que hay entre esquinas, además de implementar un algoritmo mas eficiente.
En esta imagen se muestra la mancha que se forma con las esquinas a una distancia cercana:
En la siguiente imagen se muestra el resultado alejando solo unos centímetros el código QR, como se puede ver el desempeño disminuye bastante, puesto que el código se encuentra donde esta la mancha blanca que esta mas arriba en la imagen a la izquierda casi en el centro, todo lo demás es ruido en la imagen:
Agregar detección de movimiento
Se plantea además agregar detección de movimiento del código QR esto por ahora solo se planea hacerlo utilizando el fondo verde que se muestra en el código al inicio de esta publicación, simplemente siguiendo objetos que tengan dicho color.
Otras partes a mejorar
- Implementar un blur adaptativo para engordar los puntos de las esquinas
- Implementar un algoritmo mas realista para encontrar las esquinas
- Disminuir el espacio de búsqueda buscando mejores características en con el calculo de los gradientes de las esquinas o eliminar el calculo de gradientes pues produce perdida de tiempo
- Reducir el error en la búsqueda de patrones de las esquinas eliminando el ruido que se produce al calcular el error del patrón.
- Posiblemente implementar un grupo de mallas en horizontal y vertical respecto al QR code para obtener los valores de la matriz
- Buscar una libreria para decodificar los códigos Solomon
- Arregla las distorsiones que ocurren al voltear el QR code
Control de versiones
Por ultimo dejo el link al control de versiones para esta clase, en el se encuentran todas las tareas realizadas en clase, además de el proyecto final cuyo nombre es QRScanner en el repositorio.
https://github.com/MaxHernandez/Vision_computacional
Presentación
Referencias:
- Docstoc.com (2010) QR Barcode Detection. [online] Available at: http://www.docstoc.com/docs/55691974/QR-Barcode-Detection [Accessed: 14 May 2013].
- Utkarsh (2012) Scanning QR Codes | AI Shack. [online] Available at: http://www.aishack.in/2012/02/scanning-qr-codes/ [Accessed: 14 May 2013].
- Utkarsh (2012) Scanning QR Codes | AI Shack. [online] Available at: http://www.aishack.in/2010/05/corner-detection-in-opencv/ [Accessed: 14 May 2013].