Blog

Temas: Java Spring
Juan Mellado, 27 Abril, 2012 - 08:42

Spring FrameworkHe publicado un nueva tanda de artículos dentro de la serie dedicada a Spring. Esta vez unos cuantos temas sueltos referentes a los validadores y formateadores, binding y conversiones de tipos, así como un pequeño resumen de las capacidades de SpEL, el lenguaje para construir expresiones de Spring:

- Validadores

- Binding, Converter y Formatting

- SpEL (1): Expression Language

- SpEL (2): Expresiones Básicas

- SpEL (3): Expresiones Avanzadas

Normalmente hay ciertas características de Spring que se usan sin pensar más en ellas, como la forma de escribir las expresiones con las que se configura un sistema. Lo que se ignora a veces es que se puede utilizar el parser de expresiones de Spring dentro del código de las aplicaciones, como cualquier otro tipo de librería de utilidades.

La única forma de estar al tanto de estas cosas es estudiar toda la documentación oficial y probar en carne propia sus capacidades. Y en algunos casos, como el mío, ponerlas por escrito para futuras referencias. A veces es mejor leer un ejemplo escrito por uno mismo que mil escritos por otros.

En la siguiente tanda de artículos abordaré los temas específicos de la programación orientada a aspectos.

Temas: Java Spring
Juan Mellado, 25 Abril, 2012 - 08:25

Spring FrameworkA pesar de haber trabajado en los últimos años con varios proyectos que utilizaban Spring, al revisar la documentación oficial de referencia siempre acaba encontrándose uno algo nuevo. Algún detalle perdido aquí y allá. Algún comentario de los desarrolladores. Alguna actualización de la librería.

He añadido a la serie de artículos sobre Spring nuevas entradas, dedicadas al uso de anotaciones y algunas características concretas del ApplicationContext:

- Anotaciones (1): Dependencias

- Anotaciones (2): Componentes

- Anotaciones (3): Configuración

- ApplicationContext (1): Internacionalización

- ApplicationContext (2): Eventos

- ApplicationContext (3): Recursos

Lo siguiente será un par de temas sueltos y una introducción a SpEL, el lenguaje para construir expresiones de Spring.

Temas: Java Spring
Juan Mellado, 23 Abril, 2012 - 09:53

Spring FrameworkÚltimamente, por "necesidades del guión", he estado revisando la documentación de Spring, aprendiendo cosas nuevas y recordando algunas que había olvidado. He estado tomando algunas notas, de esas que al final acaban perdiéndose, así que al final me he decidido a pasarlas a limpio y colgarlas en la web.

Estoy siguiendo la documentación oficial, con un enfoque paso a paso de abajo arriba, lo que quiere decir que estoy generando mucho material. Para evitar polucionar el blog con decenas de posts sobre el tema los he juntado en forma de una serie de artículos dedicados a Spring.

Primera tanda de artículos:

- Introducción

- Ejemplo Básico

- Beans (1): Instanciación y Dependencias

- Beans (2): Definición

- Beans (3): Inicialización Perezosa y Autowiring

- Beans (4): Inyección de Métodos

- Beans (5): Ciclos de Vida

- Beans (6): Plugins y Factorías

Estos artículos abarcan la parte más básica de definición de los beans, los siguientes abordarán el uso anotaciones y alguna de las funcionalidades ofrecidas por el contexto.

Juan Mellado, 19 Marzo, 2012 - 17:39

Un vídeo que muestra en acción la última demo de js-aruco, mi librería de realidad aumentada escrita en JavaScript:

Demo online:
http://inmensia.com/files/aruco/debug-posit/debug-posit.html

Lo que se ve en el vídeo es la ejecución en Chrome 18 con el flag "--enable-media-stream" activo.

Juan Mellado, 19 Marzo, 2012 - 15:59

Realidad AumentadaHe actualizado los fuentes de js-aruco con los últimos cambios en los que he estado trabajando últimamente. La principal novedad es la posibilidad de calcular la pose en tres dimensiones de un marcador a partir de su proyección en dos dimensiones. Aunque también hay otros cambios importantes, así como varias mejoras realizadas para optimizar el rendimiento.

He publicado una nueva demo online con todos los cambios realizados:
- http://inmensia.com/files/aruco/debug-posit/debug-posit.html

Estimación de la Pose
Para calcular las poses en tres dimensiones he utilizado el método descrito en "Iterative Pose Estimation using Coplanar Feature Points". Este no es el método que utiliza la librería original que tomé como punto de partida, pero lo he preferido porque no requiere los parámetros de calibración de la cámara. Sus únicos parámetros de entrada son el tamaño real del marcador y la longitud focal de la cámara. El primero es sencillo, es lo que mide realmente de lado a lado el marcador (en milímetros). Y aunque el segundo suena un poco más difícil de calcular, en realidad se puede aproximar asumiendo simplemente que es igual al ancho de la imagen con la que se esté trabajando (en pixels).

El algoritmo devuelve dos poses estimadas caracterizadas por una matriz de rotación y un vector de traslación. Esto es así porque la proyección de un cuadrilátero en dos dimensiones puede corresponderse con dos posiciones distintas del mismo cuadrilátero en tres dimensiones. Para averiguar cual es la proyección más correcta, si es que existe alguna, se calcula el error que existe entre el modelo del marcador de partida, y el resultado de aplicar cada rotación y traslación calculada a la proyección dada. La pose estimada que produce el menor error se considera la más correcta de las dos.

He acabado realizando dos implementaciones, la primera basada en el código original utilizado por Daniel DeMenthon escrito en C, y la segunda basada en el código en C# descrito en un artículo por Andrew Kirillow. Dan resultados bastantes similares, aunque hay ciertas diferencias en el cálculo del método del error. Las he exportado con el mismo nombre, ya que la idea es utilizar un método u otro, y para ello basta con incluir posit1.js o posit2.js según cual método se prefiera. Está explicado en la web del proyecto.

Como añadido, he tenido que implementar en JavaScript el algoritmo de descomposición en valores singulares de una matriz, más conocido por su siglas en inglés "SVD". Para ello he seguido la implementación original descrita en "Numerical Recipes in C - Second Edition".

Stack Box Blur
Para aumentar el rendimiento general de la librería he sustituido el cálculo del Gaussian Blur, que se utilizaba para realizar el Threshold Adaptativo, por un Stack Box Blur.

El cálculo del Gaussian Blur era la parte que más tiempo de proceso llevaba de toda la librería. Utilizaba un tamaño de kernel de 7, lo que implicaba que para cada pixel de la imagen se tenían que realizar del orden de un centenar de accesos a memoria y otras tantas operaciones matemáticas. El Stack Box Blur utiliza un tamaño de kernel de 2, reduce considerablemente el número de accesos a memoria utilizando una pequeña pila (stack), evita tener que utilizar un buffer intermedio del mismo tamaño que la imagen, y gracias a una tabla precalculada apenas realiza unas pocas operaciones aritméticas por pixel. Y lo mejor de todo es que el resultado final es apenas indistinguible del original Gaussian Blur cuando se utiliza para calcular el Threshold Adaptativo.

He implementado una versión adaptada a las necesidades de la librería, que en este punto concreto trabaja con imágenes en escala de grises, utilizando un sólo canal, frente a las implementaciones originales, que sólo permiten trabajar con imágenes de tres o cuatro canales.

Supersampling
Una de las cosas que tenía pendiente prácticamente desde que implementé la librería era mejorar el warp. Este proceso es el que extrae de la imagen las áreas donde se encuentran los marcadores detectados y las proyecta en cuadriláteros con la idea de reconstruir el aspecto original real de cada uno de ellos. Su principal carencia era la falta de algún tipo de interpolación entre los pixeles adyacentes, por lo que las imágenes resultantes no eran todo lo buenas que podían llegar a ser cuando los marcadores estaban en ángulos "complicados" en vez de directamente enfrentados a la cámara.

Los cambios realizados han sido de dos tipos. Por una parte optimización del código existente, y por otra parte adición de supersampling. La optimización no ha sido demasiado difícil, ya que originalmente la función no estaba nada optimizada y ha sido fácil obtener una ganancia de rendimiento rápidamente. Desgraciadamente la implementación del supersampling se ha comido la ganancia y algo más. No estoy nada contento con la implementación, se basa en el uso de un par de decenas de variables locales, y eso resulta difícil que la máquina virtual pueda optimizarlo tratando de cachear valores en registros del microprocesador. La parte positiva es que las imágenes que se obtienen ahora son de muchísima más calidad, con bordes rectos en vez de dentados como ocurría antes.

Rendimiento
Utilizando como referencia la última demo, el rendimiento global del sistema en mi equipo es de 60 FPS estables con un consumo de entre el 7 y el 9 por ciento de CPU. Los FPS están perfectos, ya que es el máximo que permite el navegador, y la CPU no está demasiado mal, aunque me haría un poco más feliz ver una cantidad menor ahí. Afortunadamente creo que aún hay bastante margen de mejora.