Ya anteriormente por mi trabajo había llegado a explorar algunas de las opciones que nos da por ejemplo Layar, que permite aplicar realidad aumentada tanto en páginas de revistas, como en plena calle.
Aunque obviamente no conozco el interior de sus algoritmos, para mí la realidad aumentada se basa en dos tipos de acciones:
- Realidad aumentada basada en localización: este tipo de realidad aumentada se basa en el uso conjunto del GPS, el acelerómetro y la brújula del móvil. A través de estos parámetros, podemos ser capaces de mostrarle al usuario una imagen en 2D/3D con el tamaño apropiado:
- Realidad aumentada basada en patrones: en este tipo de realidad aumentada, nos basamos en el reconocimiento de patrones (como pueden ser dibujos, partes de revistas, etc), para mostrar encima de ese patrón aquellos modelos que nosotros queramos:
Obviamente la primera también puede retroalimentarse de la segunda y aparte de basarse en los parámetros del móvil, tratar de encontrar patrones de la zona donde creamos estar (edificios, etc).
Aunque a día de hoy ya existen algunos frameworks libres o comerciales para realidad aumentada, decidí empezar por estudiar en qué era en lo que se basaba aquellos frameworks (sobretodo los de patrones), y decidí comenzar por comprender cómo un móvil/pc es capaz de reconocer formas, o patrones de una imagen.
Uno de los tutoriales más básicos que encontré es este videotutorial donde explica basándose en python algunas de las cosas que iré desgranando aquí.
El primer problema que nos vamos a encontrar a la hora de reconocer patrones de una imagen en Java, es la propia complejidad de la imagen. Nuestras imágenes se basan en matrices de pixels que será donde trataremos de buscar zonas que se asemejen a aquellas que tratamos de buscar.
La cuestión es que cada pixel en el mundo actual tiene color (gracias a dios) y este color está codificado en lo que se llama RGBA :
- R (Red): Componente de rojo de 0 a 255 ( 8 bits )
- G (Green): Componente de verde de 0 a 255 ( 8 bits )
- B (Blue): Componente de azul de 0 a 255 ( 8 bits )
- Alpha (Opacity): Grado de transparencia de 0 a 255 ( 8 bits )
Por esto es por lo que se suele decir que trabajamos a 32 bits de color puesto que cada pixel requiere de 32 bits para especificar su color. (Si queréis juguetear con las componentes RGBA para generar colores podéis usar esta web teniendo en cuenta que en CSS la opacidad va de 0.0 a 1.0, cosa que en la realidad se codifica de 0 a 255 si trabajamos con los binarios de la imagen).
Obviamente trabajar con tanta información es un problema, por lo que nuestra misión en un primer procesado antes de ponernos a buscar el patrón, es reducir esa cantidad de información. Para ello si seguimos el tutorial, lo que creamos es una función umbral, la cual nos convierte la imagen de color, a blanco y negro. Pero ojo, no es blanco y negro en sentido de gama de grises, sino que pixel por pixel analizaremos:
- Creemos que el pixel tiene peso en la imagen (imaginemos que es un borde bien definido de un dibujo): ese pixel lo convertiremos en negro puro (0,0,0,255).
- Si por lo contrario ese pixel no tiene relevancia en la imagen (por ejemplo el fondo): ese pixel se convierte a blanco puro (255,255,255,255).
Gráficamente sería algo como pasar de esta imagen a la versión de abajo:
El algoritmo sería el siguiente:
- Recorremos toda la matriz de pixels y hacemos la media de la componente RGB del pixel (R+G+B)/3 y lo almacenamos en otra matriz.
- Recorremos todas las medias que hemos hecho y calculamos cuál es el valor medio de los pixels de la matriz. (Si la matriz del paso anterior nos da por ejemplo 60, 70 y 80, el valor medio de la matriz sería 70).
- Recorremos la matriz obtenida en el primer paso y aquellos pixels que sobrepasen el valor medio, los ponemos a blanco (recordemos que en RGB 255 es blanco y 0 es negro) y aquellos que se queden por debajo del valor, los pintamos de negro.
En el tutorial de YouTube de sentdex veréis que el lo hace en python, pero yo os he dejado un par de imágenes de ejemplo y de código en GitHub migrado a Java:
En todo momento estamos usando imágenes en formato PNG, puesto que por su simplicidad nos permite manipular los pixels o recrear otras imágenes de manera más sencilla.


Muy interesante, estoy empezando recién con la programación y entre buscando códigos para mirar y estudiarlos, me tope con tu blog. Esta muy bueno... Gracias por compartirlo
ResponderEliminarMe alegra que te guste :)
EliminarSi estás interesado en el tema de reconocer patrones, hay técnicas con Machine Learning mucho más avanzadas que esta (a ver si un día saco tiempo y hago el ejemplo).
Gracias por visitarnos y por tu comentario!