Las dos últimas semanas las he dedicado a solucionar el problema del movimiento de la cámara, que hace que las fotos se desplacen algunos píxeles en sentido horizontal y vertical.
Para ello he usado una fórmula que, dadas dos imágenes, devuelve un resultado comprendido entre -1 y 1, siendo el resultado más cercano a 1 cuanto más se parezcan las imágenes. Suponiendo que el desplazamiento máximo de las fotos sea de en torno a 5 píxels, lo que se hace es recortar la primera imagen de la secuencia (imagen A) 5 píxels por cada uno de los lados, y el trozo resultante se va comparando con trozos de las mismas dimensiones de la siguiente imagen (imagen B), quedándonos finalmente con el trozo que más se parezca al de la primera imagen (usando la fórmula citada anteriormente). Después se repite el proceso, usando esta vez como imagen A el trozo que hemos elegido de la anterior imagen B, y como imagen B la siguiente imagen de la secuencia.
El resultado es que las fotos de la secuencia se ven recortadas 5 píxels por cada uno de sus lados, pero habiendo disminuido bastante el pequeño desplazamieno de arriba a abajo y de izquierda a derecha que se podía ver cuando veíamos la secuencia a toda velocidad.
11 mar 2009
16 feb 2009
Hipótesis de mundo gris
Después de un par de semanas en donde he estado bastante liado con otras cosas, vuelvo a ponerme con el proyecto. He avanzado en diferentes aspectos, aunque el más importante es el de la realización de un algoritmo que suaviza los cambios de intensidad entre las imágenes, lo que se conoce como "mundo gris".
Lo he hecho usando una ventana de 5 imágenes, y por lo que he podido ver parece que funciona, ya que hay imágenes que las oscurece un poco y otras que las ilumina. El tamaño de la ventana está parametrizado para que se pueda cambiar y ver si el resultado mejora aumentando o disminuyendo esta. Este algoritmo hace que la transición entre una imagen y otra sea menos brusca al haber una intensidad uniforme en ellas.
También he hecho un pequeño programa para realizar una captura de imágenes con la webcam, lo que me facilitará el realizar mis propias secuencias de vídeo.
Esta semana intentaré avanzar en el "jitter removal", que consiste en suavizar los desplazamientos en el encuadre al realizar las diferentes fotografías de la secuencia.
Lo he hecho usando una ventana de 5 imágenes, y por lo que he podido ver parece que funciona, ya que hay imágenes que las oscurece un poco y otras que las ilumina. El tamaño de la ventana está parametrizado para que se pueda cambiar y ver si el resultado mejora aumentando o disminuyendo esta. Este algoritmo hace que la transición entre una imagen y otra sea menos brusca al haber una intensidad uniforme en ellas.
También he hecho un pequeño programa para realizar una captura de imágenes con la webcam, lo que me facilitará el realizar mis propias secuencias de vídeo.
Esta semana intentaré avanzar en el "jitter removal", que consiste en suavizar los desplazamientos en el encuadre al realizar las diferentes fotografías de la secuencia.
28 ene 2009
Filtro de mediana
En la última entrada comentaba que había hecho un programa que calculaba la imagen media de un conjunto de imágenes dado. Sin embargo el resultado no era del todo satisfactorio, por lo que he modificado el programa y ahora lo que hace es calcular la "imagen mediana" de un conjunto de imágenes dado. Es decir, cada pixel de la nueva imagen se calcula como aquel que ocupa la posición central de los valores ordenados del conjunto de imágenes.
Con esto se consigue eliminar los objetos móviles, que varían su posición de una imagen a otra, y lo que permanece es lo que se repite en todas las imágenes (por ejemplo: desaparecen los peatones y vehículos, y permanecen los edificios).
El resultado, aunque no es perfecto, sí que mejora al que daba el cálculo de la imagen media.
Con esto se consigue eliminar los objetos móviles, que varían su posición de una imagen a otra, y lo que permanece es lo que se repite en todas las imágenes (por ejemplo: desaparecen los peatones y vehículos, y permanecen los edificios).
El resultado, aunque no es perfecto, sí que mejora al que daba el cálculo de la imagen media.
20 ene 2009
Imagen promedio usando ventana
He estado más liado de lo que pensaba este mes, pero por fin puedo dedicarle más tiempo al proyecto.
Ya he conseguido arreglar el error que me salía al ejecutar las funciones que hice la última vez. Al parecer se estaba accediendo a posiciones de memoria no reservadas, y la solución era simplemente usar la función "malloc" para reservar la memoria necesaria.
También he conseguido acceder a los píxels de una imagen usando punteros, en lugar de los métodos CvGet2d y CvSet2d, lo cual es mucho más eficiente.
Y ahora ya puedo manejar imágenes grandes (1280x1024) sin que me salga desbordamiento de pila. El problema era que almacenaba los datos de cada imagen (los colores RGB de cada píxel) en un array de dos dimensiones, y al ser este demasiado grande se producía el desbordamiento. Ahora esa información la guardo en una imagen en blanco que me creo al comienzo de la función.
Por último, he ampliado el anterior programa que calculaba la imagen promedio de un conjunto de imágenes, y ahora lo que hace es mostrar la imagen promedio usando una ventana de imágenes que se va "moviendo". Es decir, si tengo 10 imágenes, y la ventana es de 3, calcula el promedio de las imágenes 1, 2 y 3, y la muestra. Luego el promedio de las imágenes 2, 3 y 4, y así hasta terminar en las 8, 9 y 10. El tamaño de la ventana en este caso sería de 3, pero se puede poner el tamaño que se quiera pasándoselo como parámetro a la función.
Ya he conseguido arreglar el error que me salía al ejecutar las funciones que hice la última vez. Al parecer se estaba accediendo a posiciones de memoria no reservadas, y la solución era simplemente usar la función "malloc" para reservar la memoria necesaria.
También he conseguido acceder a los píxels de una imagen usando punteros, en lugar de los métodos CvGet2d y CvSet2d, lo cual es mucho más eficiente.
Y ahora ya puedo manejar imágenes grandes (1280x1024) sin que me salga desbordamiento de pila. El problema era que almacenaba los datos de cada imagen (los colores RGB de cada píxel) en un array de dos dimensiones, y al ser este demasiado grande se producía el desbordamiento. Ahora esa información la guardo en una imagen en blanco que me creo al comienzo de la función.
Por último, he ampliado el anterior programa que calculaba la imagen promedio de un conjunto de imágenes, y ahora lo que hace es mostrar la imagen promedio usando una ventana de imágenes que se va "moviendo". Es decir, si tengo 10 imágenes, y la ventana es de 3, calcula el promedio de las imágenes 1, 2 y 3, y la muestra. Luego el promedio de las imágenes 2, 3 y 4, y así hasta terminar en las 8, 9 y 10. El tamaño de la ventana en este caso sería de 3, pero se puede poner el tamaño que se quiera pasándoselo como parámetro a la función.
17 dic 2008
La cosa avanza
El proyecto empieza a tomar forma. Esta semana me he dedicado a realizar dos funciones:
La primera consistía en mostrar una secuencia de imágenes, dando la impresión de "movimiento". He usado las que me bajé la otra vez del edificio en construcción. El resultado es una versión "a lo bruto" de lo que tendría que ser el proyecto una vez finalizado, ya que se notan mucho las transiciones entre imágenes. La implementación ha sido bastante sencilla, usando un bucle que va cargando una imagen y mostrándola en cada iteración. Las mayores complicaciones han venido del lado de la dirección de la imagen, ya que esta tiene que cambiar en cada iteración. Lo que hice fue pasar el contador del bucle a char, concatenarlo con la extensión de la imagen (.jpg por ejemplo), y usar el resultado como dirección. Aún así, al finalizar el programa (y mostrar correctamente las imágenes), me sale el siguiente error: "Stack around the variable 'xxxx' was corrupted", siendo "xxxx" una variable que uso para inicializar un puntero a char que es en donde guardaré la dirección de la imagen (ya que el compilador me decía que debía inicializar dicho puntero). He estado probando cosas pero sigo sin quitar ese error. Al menos no molesta demasiado por ahora...
La segunda de las funciones que he hecho ha sido algo más complicada. Consistía en hallar la imagen promedio de un número de imágenes. La principal complicación fue hallar el modo de acceder a cada píxel de la imagen. Buscando por diversos tutoriales de Internet vi diversos métodos, y finalmente me decanté por uno que al parecer no es muy eficiente, pero sí me resultó más sencillo de entender (los otros métodos no conseguí entenderlos del todo).
Simplemente hay que usar la función "cvGet2D(img,y,x)", donde "x" e "y" son las coordenadas del píxel al que se quiere acceder. Esta función devuelve en una variable del tipo CvScalar los valores RGB del píxel, del siguiente modo:
s.val[0]=blue
s.val[1]=green
s.val[2]=red
Para recoger la información del color de cada píxel de la imagen definí un array de dos dimensiones, del tamaño que tengan las imágenes a tratar (p.ej. 300x240), y que guardase en cada posición la información RGB mediante un struct. Lo demás es bastante sencillo: usando este array se va recogiendo la información de cada pixel de cada imagen, y se halla el promedio. Una vez obtenido este, se usa la función "cvSet2D(img,y,x,s)", que básicamente hace lo inverso que "cvGet2D", creando la imagen resultado.
Como he dicho, este método puede no resultar muy eficiente, y de hecho hay desbordamiento de pila si se usan imágenes de gran tamaño. Por eso intentaré averigüar cómo hacerlo de una manera más eficiente.
La primera consistía en mostrar una secuencia de imágenes, dando la impresión de "movimiento". He usado las que me bajé la otra vez del edificio en construcción. El resultado es una versión "a lo bruto" de lo que tendría que ser el proyecto una vez finalizado, ya que se notan mucho las transiciones entre imágenes. La implementación ha sido bastante sencilla, usando un bucle que va cargando una imagen y mostrándola en cada iteración. Las mayores complicaciones han venido del lado de la dirección de la imagen, ya que esta tiene que cambiar en cada iteración. Lo que hice fue pasar el contador del bucle a char, concatenarlo con la extensión de la imagen (.jpg por ejemplo), y usar el resultado como dirección. Aún así, al finalizar el programa (y mostrar correctamente las imágenes), me sale el siguiente error: "Stack around the variable 'xxxx' was corrupted", siendo "xxxx" una variable que uso para inicializar un puntero a char que es en donde guardaré la dirección de la imagen (ya que el compilador me decía que debía inicializar dicho puntero). He estado probando cosas pero sigo sin quitar ese error. Al menos no molesta demasiado por ahora...
La segunda de las funciones que he hecho ha sido algo más complicada. Consistía en hallar la imagen promedio de un número de imágenes. La principal complicación fue hallar el modo de acceder a cada píxel de la imagen. Buscando por diversos tutoriales de Internet vi diversos métodos, y finalmente me decanté por uno que al parecer no es muy eficiente, pero sí me resultó más sencillo de entender (los otros métodos no conseguí entenderlos del todo).
Simplemente hay que usar la función "cvGet2D(img,y,x)", donde "x" e "y" son las coordenadas del píxel al que se quiere acceder. Esta función devuelve en una variable del tipo CvScalar los valores RGB del píxel, del siguiente modo:
s.val[0]=blue
s.val[1]=green
s.val[2]=red
Para recoger la información del color de cada píxel de la imagen definí un array de dos dimensiones, del tamaño que tengan las imágenes a tratar (p.ej. 300x240), y que guardase en cada posición la información RGB mediante un struct. Lo demás es bastante sencillo: usando este array se va recogiendo la información de cada pixel de cada imagen, y se halla el promedio. Una vez obtenido este, se usa la función "cvSet2D(img,y,x,s)", que básicamente hace lo inverso que "cvGet2D", creando la imagen resultado.
Como he dicho, este método puede no resultar muy eficiente, y de hecho hay desbordamiento de pila si se usan imágenes de gran tamaño. Por eso intentaré averigüar cómo hacerlo de una manera más eficiente.
26 nov 2008
Primeros pasos
Bueno, después de pelearme con los IDEs y OpenCV durante semanas, por fin puedo ponerme en marcha.
Desde mi última entrada en el blog seguí probando otros entornos de programación, e incluso me bajé el Service Pack 1 de Vista, pero la cosa seguía sin ir. Me seguía saliendo el mismo error que comenté anteriormente. Así que decidí cortar por lo sano y formatear el ordenador. Reinstalé Vista, instalé el Visual Studio 2003 (que decidí usarlo ya que es el que está en los ordenadores de la universidad), y... nada, el mismo puñetero error. Como última opción antes de mandar todo a tomar por saco, probé a instalar OpenCV en el portátil de mi hermano, que también usa Vista. Instalé el Visual Studio 2003, compilé el código, lo ejecuté... y funcionaba perfectamente. Inexplicablemente, en el portátil de mi hermano funciona, y en el mio recién formateado no, usando el mismo entorno de programación. Así que, hasta que no descubra lo que falla en mi ordenador, tendré que hacer el proyecto en el de mi hermano.
Sobre el proyecto en sí, Juanjo (uno de mis tutores en el proyecto), me dio la dirección de la web de un chico que ha hecho el proyecto en el que se basa el mio. Le estuve echando un vistazo y me bajé un pack de imágenes para poder trabajar con ellas próximamente, así como un vídeo en donde se ve el resultado final de la reconstrucción. También me bajé el pdf en donde explica todo el proceso que siguió, aunque por ahora no entiendo mucho de lo que habla (sigo estando un poco pez en OpenCV).
Sobre OpenCV, me he puesto a hacer algunos ejemplos sencillos de tratamiento de imágenes que vienen en esta web. He intentado hacer un bucle que vaya cargando imágenes y las muestre por pantalla (usando el pack de imágenes que me descargué anteriormente), pero no sé como hacer que el string con la dirección de la imagen vaya cambiando en cada iteración. Imagino que habrá alguna forma de hacerlo, así que seguiré investigando, y seguiré probando cosillas con OpenCV hasta que me ponga definitivamente manos a la obra con el proyecto.
Un saludo.
Desde mi última entrada en el blog seguí probando otros entornos de programación, e incluso me bajé el Service Pack 1 de Vista, pero la cosa seguía sin ir. Me seguía saliendo el mismo error que comenté anteriormente. Así que decidí cortar por lo sano y formatear el ordenador. Reinstalé Vista, instalé el Visual Studio 2003 (que decidí usarlo ya que es el que está en los ordenadores de la universidad), y... nada, el mismo puñetero error. Como última opción antes de mandar todo a tomar por saco, probé a instalar OpenCV en el portátil de mi hermano, que también usa Vista. Instalé el Visual Studio 2003, compilé el código, lo ejecuté... y funcionaba perfectamente. Inexplicablemente, en el portátil de mi hermano funciona, y en el mio recién formateado no, usando el mismo entorno de programación. Así que, hasta que no descubra lo que falla en mi ordenador, tendré que hacer el proyecto en el de mi hermano.
Sobre el proyecto en sí, Juanjo (uno de mis tutores en el proyecto), me dio la dirección de la web de un chico que ha hecho el proyecto en el que se basa el mio. Le estuve echando un vistazo y me bajé un pack de imágenes para poder trabajar con ellas próximamente, así como un vídeo en donde se ve el resultado final de la reconstrucción. También me bajé el pdf en donde explica todo el proceso que siguió, aunque por ahora no entiendo mucho de lo que habla (sigo estando un poco pez en OpenCV).
Sobre OpenCV, me he puesto a hacer algunos ejemplos sencillos de tratamiento de imágenes que vienen en esta web. He intentado hacer un bucle que vaya cargando imágenes y las muestre por pantalla (usando el pack de imágenes que me descargué anteriormente), pero no sé como hacer que el string con la dirección de la imagen vaya cambiando en cada iteración. Imagino que habrá alguna forma de hacerlo, así que seguiré investigando, y seguiré probando cosillas con OpenCV hasta que me ponga definitivamente manos a la obra con el proyecto.
Un saludo.
3 nov 2008
Peleándome con los IDEs
Lo primero es buscar un entorno de programación en donde realizar el proyecto. Así que decidí descargarme el Eclipse GAVAB como han hecho otros compañeros. Sin embargo me ha dado algunos problemas extraños que no he conseguido solucionar (concretamente, en un pequeño programa de prueba, se me ejecutan primero los "scanf", y luego el resto del código).
Por tanto probé con el Visual Studio 2008 Express Edition. Aquí no tuve problemas al ejecutar código. El problema vino después, cuando me descargué las librerías de OpenCV. Una vez instalado, y siguiendo un sencillo tutorial, añadí los directorios de librerías, includes y demás al Visual Studio. Después probé un pequeño programa que carga una imagen y la invierte, mostrándola por pantalla, y compilaba perfectamente. El problema vino a la hora de ejecutar el código, ya que me muestra un error, concretamente este:
LDR: LdrpWalkImportDescriptor() failed to probe C:\Program Files\OpenCV\bin\cxcore110.dll for its manifest, ntstatus 0xc0150002
Busqué por Internet y encontré una posible solución, que consistía en instalar un service pack para Visual Studio, por lo que desinstalé la versión que tenía y me volví a bajar una versión nueva con el SP1. Lamentablemente me sigue saliendo el mismo error, así que estoy un poco desesperado. No consigo un IDE en donde poder desarrollar el proyecto, siempre surge algún problema. Lo seguiré intentando durante los próximos días, aunque conseguir que algo funcione en Windows Vista es todo un milagro.
Mientras tanto seguiré mirando documentación de OpenCV para intentar ir aprendiendo algo más de estas librerías.
Un saludo.
Por tanto probé con el Visual Studio 2008 Express Edition. Aquí no tuve problemas al ejecutar código. El problema vino después, cuando me descargué las librerías de OpenCV. Una vez instalado, y siguiendo un sencillo tutorial, añadí los directorios de librerías, includes y demás al Visual Studio. Después probé un pequeño programa que carga una imagen y la invierte, mostrándola por pantalla, y compilaba perfectamente. El problema vino a la hora de ejecutar el código, ya que me muestra un error, concretamente este:
LDR: LdrpWalkImportDescriptor() failed to probe C:\Program Files\OpenCV\bin\cxcore110.dll for its manifest, ntstatus 0xc0150002
Busqué por Internet y encontré una posible solución, que consistía en instalar un service pack para Visual Studio, por lo que desinstalé la versión que tenía y me volví a bajar una versión nueva con el SP1. Lamentablemente me sigue saliendo el mismo error, así que estoy un poco desesperado. No consigo un IDE en donde poder desarrollar el proyecto, siempre surge algún problema. Lo seguiré intentando durante los próximos días, aunque conseguir que algo funcione en Windows Vista es todo un milagro.
Mientras tanto seguiré mirando documentación de OpenCV para intentar ir aprendiendo algo más de estas librerías.
Un saludo.
Suscribirse a:
Entradas (Atom)