inmensia |
Realidad Aumentada (6/7)
Juan Mellado, 28 Mayo, 2011 - 10:41
Este paso es el último en lo que a manipulación de imágenes se refiere. Admite como entrada la imagen en escala de grises creada en el primer paso, y los cuadriláteros candidatos encontrados en el último. Para cada cuadrilátero extrae la región de la imagen que cubre cada uno de ellos eliminando la transformación de perspectiva, es decir, la deformación que se produce en el marcador debido a la perspectiva. Transformación de Perspectiva (Homography) A grandes rasgos, se trata de encontrar la operación que proyecte las cuatro esquinas de un cuadrilátero en las cuatro esquinas de un cuadrado. Y que además sirva para todos los puntos intermedios. Afortunadamente este es un procedimiento sobre el que existe mucha información, ya que es como el que se utiliza para aplicar texturas a los modelos tridimensionales, aunque en sentido contrario. ArUco, la librería de realidad aumentada que estoy portando a JavaScript, utiliza dos funciones de OpenCV para este paso: getPerspectiveTransform y warpPerspective. La primera calcula una matriz que multiplicada por un punto en el cuadrilátero origen devuelve un punto equivalente en el cuadrado destino. La segunda acepta una imagen, un cuadrilátero, una matriz de transformación, y retorna una nueva imagen del área cubierta por el cuadrilátero sobre la que se ha aplicado la matriz de transformación para eliminar la deformación debida a la perspectiva. El problema de estas dos funciones es que son demasiado complejas de portar directamente a JavaScript debido a que hacen uso de LAPACK, una librería matemática con la que resuelven el sistema de ecuaciones lineales necesario para calcular la transformación de perspectiva. Así que, aprovechando que estoy en un entorno mucho más controlado y menos genérico que al que tiene que enfrentarse OpenCV, he optado por una implementación mucho más liviana usando las ecuaciones de toda la vida expuestas por Paul Heckbert en su tesis ¿doctoral? titulada Fundamentals of Texture Mapping and Image Warping. Este "paper" es un clásico, e incluso tiene un apéndice con código en C, mucho más sencillo de portar a JavaScript que el de OpenCV. El resultado de este proceso es cada una de las figuras que he puesto en la primera imagen. Una para cada cuadrilátero candidato. ArUco utiliza un tamaño de 50x50 pixels para los cuadrados destino, aunque yo he preferido utilizar un tamaño de 49x49, ya que los marcadores son matrices de 7x7. Para terminar, dos detalles acerca de la implementación. El primero es que en realidad se recorre el cuadrado y se calculan los puntos en el cuadrilátero, y no al revés, ya que es mucho más sencillo recorrer el cuadrado. Y el segundo es que no he implementado ningún tipo de interpolación, por lo que en cuanto se gira un poco la imagen aparecen los clásicos "dientes de sierra". Esto último no ocurre en ArUco, ya que que OpenCV utiliza interpolación bilineal para obtener una imagen mejor. En general, esta función es una de las más serias candidatas a ser modificadas y optimizadas. Umbralización (Otsu) El método de Otsu se basa en el análisis del histograma de una imagen dada. Es decir, en el número de veces que aparece cada tono de gris dentro de ella. Divide el histograma en dos grandes grupos, de forma que a un lado quedan los valores que representan el "fondo" de la imagen y al otro los que representan el "frente". Matemáticamente se dice que calcula un valor tal que la varianza (dispersión de los tonos de gris) es mínima dentro de cada grupo, pero que es máxima entre los dos grupos. El algoritmo es sencillo de implementar, y como se observa en la segunda imagen, resultante de aplicar a la primera imagen el valor umbral calculado por el método de Otsu, hace realmente un gran trabajo. Actualizado 19/03/2012: Actualmente js-aruco implementa supersampling evitando la aparición de "dientes de sierra" en los bordes. Realidad Aumentada ¿No encontró lo que buscaba?Utilice el buscador para encontrar más páginas en esta web o en toda Internet. |