Sunday, April 1, 2012

Reconstrucción 3D de escenas

Últimamente he estado interesado en la reconstrucción tridimensional de escenas y hay cosas bastante interesantes al respecto. La reconstrucción 3D de una escena consiste en utilizar un montón de fotografías u otro tipo de información disponible para generar un modelo 3D de ella, usualmente para ser mostrado en un computador.
Fuente de imagen:IVC


El enfoque clásico para reconstruir una escena 3D es usar múltiples cámaras para capturar la escena desde diferentes  ángulos. Luego se extraen características (pixeles que se puedan identificar fácilmente en diferentes tomas) y se realiza triangulación (se resuelve un sistema de ecuaciones para encontrar la distancia que tiene cada punto identificable en ambas imágenes a la cámara).  Hay técnicas de reconstrucción que requieren calcular los parámetros de la cámara (posición, orientación, distancia focal, distorsión, etc) con la que fue capturada la imagen, otra técnicas no requieren calcular estos parámetros. Por ejemplo hay técnicas para hacer una reconstrucción 3D a partir de un video tomado de una cámara con parámetros desconocidos. Hay trabajos impresionantes, donde utilizan millones de imágenes tomadas de internet para reconstruir una ciudad completa (por ejemplo [1]).
Todas las técnicas que no requieren alterar la luz en la escena son llamadas técnicas pasivas, aquí entrarían las reconstrucciones a partir de tomas con cámaras comunes y corrientes. Por otro lado están las técnicas activas, como por ejemplo escaneo láser, en el que se envían pulsos de luz a la escena, se calcula cuanto tardan en volver y en base ello la distancia (profundidad) de los objetos de la escena al sensor. Estos sensores son muy caros, pero también muy precisos. Hay cámaras que utilizan este mismo principio, pero con pulsos de luz infraroja (Time Of Flight cameras), también hay otras que en lugar de medir el tiempo van enviando pulsos desfasados de la onda y en base a estos desfases calculan la profundidad. Una técnica diferente es la que ocupa Kinect, que proyecta un patron infrarojo sobre la escena, dibujando sus propias características (puntos infrarojos que pueden ser identificados) y aplicando triangulación (un trabajo de reconstrución 3D usando una kinect, muy interesante es KinectFusion). Estas técnicas son muy éxitosas para realizar reconstrucción 3D de escenas, pues no dependen de la textura de los objetos,  ya que no analizan la imagen del espectro visible para encontrar pixeles identificables entre distintas imágenes, sino que miden el tiempo de vuelo de la luz o proyectan sus propios patrones infrarojos! Hasta aquí, no tenemos más que un mapa de profundidad de la escena,  todavía falta camino para su reconstrucción. A partir de varios mapas de profundidad de la escena se va generando un modelo 3D, también hay múltiples técnicas para ello, como así también múltiples maneras de representar la escena. Sin embargo me detendré sólo en una técnica, llamada ICP (Iterative Closest Point) que busca "alinear" los distintos mapas de profundidad o en otras palabras conocer la posición de la cámara y así saber qué parte de la escena corresponde a qué mapa de profunidad. Este algoritmo recibe como entrada dos mapas de profundidad y entrega como resultado la traslación y rotación 3D necesaria para que el primer mapa de profundidad encaje mejor con el segundo (para que ambos mapas de profunidad sean muy similares). En base a ello es posible conocer la posición cámara y con ello saber qué parte del modelo 3D se debe rellenar con qué mapa de profunidad.
El problema de reconstrucción 3D de escena no se puede considerar del todo resuelto, pues cada técnica tiene sus limitaciones. Por ejemplo todas las técnicas dependen de la reflectancia de los materiales (si envío un pulso laser a una superficie y este es completamente absorbido, no podré calcular cuánto tardó en volver). Si utilizo pulsos infrarojos podré tener problemas de interferencia con la luz del sol, si utilizo técnicas pasivas necesitaré una buena iluminación y que la escena sea lo suficientemente rica en características para poder encontrar pixeles identificables en múltiples tomas.
Me imagino que para mitigar estos problemas se debería usar (o tal vez se usa) la luz combinada con sonido o algún dispositivo mecánico.
Queridos lectores humanos (si es que los hay) : Este artículo lo escribí muy a la rápida y ojalá les sea de alguna utilidad, disculpen los errores. Un saludo!

Friday, December 9, 2011

Tracking usando filtro de partículas en OpenCV


Una implementación muy simple de un tracker que usa filtro de partículas en OpenCV. Las partículas se generan mediante números aleatorios que siguen una distribución Gaussiana, se les asigna peso según distancia de histogramas HSV y frame a frame se van actualizando, conservando sólo las mejores partículas.

Puedes bajar el programa aca

Friday, April 29, 2011

Octave plot custom grid

Necesitaba graficar algo, pero quería cambiar el espaciado de la rejilla a 0.25

P = dlmread("serial500.txt"," ");
plot(P(:,1),P(:,2),"*")
set(gca(),"xtick",[0:0.25:1])
set(gca(),"ytick",[0:0.25:1])
grid
xlabel("x")
ylabel("y")
title("500 pares de nums")

Saturday, March 12, 2011

Un problema interesante

El otro día me comentaron acerca de un problema muy interesante y quiero compartirlo con ustedes, por supuesto que no les daré el nombre del problema para que no lo busquen...

Hay tres cajas, de las cuales sólo una contiene un premio. Tú escoges una de estas cajas y luego se te muestra una de las cajas que no escogiste y no contiene premio. Se te da la posibilidad de cambiar la caja que escogiste por la que queda ¿Qué te conviene hacer?

Tuesday, February 22, 2011

Reflexiones acerca de nuestra grandeza

La vida se agota, nada se puede hacer para evitarlo, nos parecen tan importantes y eternas ciertas cosas, como si nunca dejaremos de ver el sol llegar cada día, como si existiese alguna urgencia en este mundo. Cuando en realidad cada una de nuestras creaciones tiene como destino la destrucción, pero que más da, es preferible soñar con que tenemos asuntos muy importantes que atender, con que somos grandes y elocuentes, mucho mejores que aquellas rocas que agonizan en el espacio. Es preferible emitir un destello de luz antes de desaparecer, como intenando superar la inercia de lo interte, que no ha conseguido aún tener la más mínima inferencia en lo que le depara.

Monday, November 15, 2010

La Identidad de Euler

Se dice que si se tuvieran que escoger los números más populares, sin duda alguna entre los primeros escogidos estarían π, e, i, 1 y 0.
Hay una bella identidad que los relaciona, seguramente conocida por más de alguno de ustedes, yo la ví en el documental universo matemático:

ei π + 1 = 0

La identidad anterior es conocida como la Identidad de Euler.

Para corroborar su autenticidad sólo debemos recurrir a la famosa Fórmula de Euler:

ei θ = cos (θ) + i sen(θ)



Donde se verifica fácilmente que si θ = π se obtiene:

ei π = cos (π) + i sen(π) = -1



Pues cos(π) = -1 y sin(π) = 0

Sunday, September 26, 2010

Tip Octave

Cuando se carga una imagen en memoria usando imread se almacena como una matriz uint8, lo que significa que cada valor de la matriz es un número positivo de 1 byte, si se quiere trabajar con esos números hay que tener cuidado pues tomarán un valor máximo de 255.


octave:> img = imread("imagen.jpg");
octave:> img(1,1)
octave:> ans = 44
octave:> img(1,1)*1000
octave:> ans=255
octave:> %para evitar esto hay que hacer un casting
octave:> double(img(1,1))*1000
octave:> ans=44000
octave:>


Escribí esto aquí para que no se me olvide, pues me causó un gran dolor de cabeza mientras estaba probando un algoritmo de interpolación para un trabajo de la universidad.