Procesamiento Audiovisual

   EMBED

Share

Preview only show first 6 pages with water mark for full document please download

Transcript

PROCESAMIENTO AUDIOVISUAL MINIPROYECTO: MORPHING Junio de 2006 Profesor: GINÉS GARCÍA MATEOS Alumnos: Daniel Paredes García ([email protected]) David Bernal Martínez ([email protected]) 3º I.T.I. SISTEMAS ÍNDICE 1. INTRODUCCIÓN..............................................................................................................................3 1.1. ¿QUÉ ES EL MORPHING?................................................................................................................3 2. MANUAL DE USUARIO ..................................................................................................................3 3. IMPLEMENTACIÓN........................................................................................................................4 3.1. CLASE MALLA...............................................................................................................................4 3.1.1. Atributos ...............................................................................................................................4 3.1.2. Métodos ................................................................................................................................4 3.2. UNIT 1 ...........................................................................................................................................5 2 1. Introducción 1.1. ¿Qué es el Morphing? El morphing es un efecto especial que consiste en una transformación de una imagen gradualmente en otra. Esta pensado de forma que el observador no aprecia en que momento una imagen cambio en la otra. Es un cambio suave entre las dos aun cuando este cambio se hace en pocos segundos. Normalmente la transformación se aplica entre personas. También existe una variante llamada View Morphing que consiste en obtener un giro de una imagen en 2D generando la ilusión del 3D. Desde que se aplicara en películas como Indiana Jones y la ultima cruzada o videos como Black or White de Michael Jackson la técnica ha avanzado mucho, de tal manera que los efectos de morphing hoy en día resultan casi invisibles. Aunque las técnicas que usa este programa son todavía muy básicas, los efectos ya son bastante buenos. Para esto el morphing implementado en esta practica usa dos técnicas, la transformación geométrica de una imagen en otra mediante la malla definida por el usuario y la media ponderada de los píxeles de las imágenes. Se usa una transformación geométrica de malla, esa es la diferencia con los programas profesionales de morphing. Estos últimos usan una transformación geométrica sin malla, sino definiendo puntos individuales análogos a las dos imágenes. 2. Manual de usuario Lo primero que se debe hacer para empezar a hacer un morphing es seleccionar las imágenes inicial y destino del morphing desde archivos de imagen. La imagen inicial se transformará en la de destino. Es importante aplicar un procesamiento previo a la imagen en algunos casos para que la cara sea de tamaño parecido y el morphing sea mas realista, en otro caso puede parecer que una cara se encoge en la otra (aunque esto también puede resultar divertido). Lo siguiente sería definir la malla. La malla es una cuadrícula que se debe ajustar a puntos significativos de la imagen. Se debe seleccionar un tamaño de malla, dependiendo de el detalle que queramos que tenga el morphing. Después se deben ajustar los puntos en las dos imágenes, teniendo en cuenta los puntos equivalentes en la otra imagen, la idea es que un punto se transforma en otro en la otra imagen, por ejemplo los ojos de la cara de la primera imagen se transforman en los de la segunda. Dado que puede ser una malla muy grande y puede resultar bastante tedioso volver a definir todos los puntos de la malla, el programa da la opción de guardar o cargar mallas ya definidas y guardadas anteriormente. En este punto tenemos dos opciones, las mas habitual es generar un video de transición entre las dos imágenes, pulsando en Ver tenemos el vídeo, podemos ajustar parámetros como el numero de frames o si se quiere que la malla se dibuje durante la transición. El video se puede guardar en un archivo ‘.avi’. Una barra de progreso muestra el avance en la generación del video, tardará mas según el numero de frames del video. Marcando la opción visualizar y pinchando en guardar se podrá ver el video al mismo tiempo que se genera el archivo. La otra opcion es generar una imagen intermedia. Se puede graduar el grado de la transformación para que este más cercano a la imagen inicial o a la final. El parámetro que gradúa la barra está entre 0 y 1, siendo 0 es mas cercano a la inicial y 1 a la final. Una vez hecho esto se puede visualizar el resultado o guardarlo. 3 3. Implementación 3.1. Clase Malla El programa trabaja con una clase llamada Malla, esta clase sirve para almacenar una imagen y su malla asociada (junto con su anchura y altura), ya que una malla no tiene sentido sin su imagen asociada. 3.1.1. Atributos • CvPoint ** malla : Malla de n x m puntos que contiene las coordenadas de dichos puntos. • Int n,m : Ancho y alto de la malla respectivamente. • IplImage * Imagen : Imagen asociada a la malla 3.1.2. Métodos • Malla(int x, int y, IplImage * imagen): Constructor. Crea una malla asociada a la imagen ya abierta imagen. x e y son el ancho y el alto de la malla generada. • void pintamalla(IplImage * img, CvScalar color= CV_RGB(200,0,0),int grosor=3): Pinta la malla con puntos, se pueden ajustar el tamaño de los puntos y el grosor de los puntos. • void pintamalla(IplImage * img, CvScalar color= CV_RGB(200,0,0),int grosor=3): Pinta la malla con una rejilla, el grosor y el color es ajustable pero opcional. • bool es_concavo(int minx, int miny): Devuelve si uno de los cuadriláteros de la malla identificado por minx, miny (vértice inferior izquierdo) es cóncavo. • CvPoint mas_cercano(long x, long y): Devuelve el punto de la malla mas cercano al punto dado (x,y). • bool modificar_punto(long x, long y): Modifica el punto de la malla más cercano a (x,y) y lo sitúa en (x,y), si esto no convierte a ninguno de los cuadriláteros modificados al modificar dicho punto de la malla en cuadriláteros cóncavos. • CvSize Malla::get_max_bounds(): Devuelve la mayor distancia en X y en Y de cada uno de los puntos adyacentes en X y en Y, respectivamente. Este método se encuentra como privado ya que no se usa realmente y fue sustituida su utilización por la del método siguiente. • vSize Malla::get_max_bounds(CvPoint ** malla_m): Similar al método anterior pero la distancia devuelta (la mayor distancia en X e Y) corresponde a la de dos mallas conjuntamente (la que llama al método y la pasada como parámetro), que se recorren en el mismo bucle para mejorar el tiempo de ejecución. • void morphing_i(Malla* malla_i ,Malla *malla_dst,float g, CvSize rect): Hace un morphing con la malla_dst en el paso g (0 <= g <= 1) siendo malla_i la malla resultante. La malla_i debe ser creada previamente antes de llamar al método. El algoritmo consiste básicamente en los pasos mostrados en clase: obtener la malla intermedia mediante las mallas de las imágenes inicial y final; transformar la imagen inicial y final moviendo los puntos desde sus respectivas malla a la malla intermedia; realizar la media ponderada de las dos imágenes obtenidas, utilizando g como peso. Utiliza en procedimiento q_to_q_bilinear explicado a continuación. 4 • void q_to_q_bilinear (int i, int j, CvPoint ** malla, CvPoint ** m_i, IplImage * imagen_src, IplImage * r, CvSize rect): Transforma un cuadrilátero en otro cuadrilátero mediante transformaciones bilineales. Este procedimiento se realizó debido a la falta de ipl de un procedimiento que realizara esta acción. Los cuadriláteros se obtienen de las mallas malla y m_i, obteniendo el cuadrilátero cuya esquina superior izquierda se encuentra en la posición (i,j) de la malla. Para realizar dicha transformación de un cuadrilátero a otro se transforma el cuadrilátero inicial en un rectángulo intermedio, y dicho rectángulo intermedio se transforma en el cuadrilátero final mediante el procedimiento iplWarpBilinearQ de ipl. • void guardar(char * archivo): Guarda la malla en un archivo de texto plano con extensión ‘.m’. En el archivo guarda las dimensiones de la malla y el valor de X e Y de cada uno de los puntos que forman la malla. • void cargar(char * archivo): Carga la malla de un archivo con el formato que previamente se generó con el método guardar. • ~Malla(): Destructor. Libera los recursos asociados a la malla, excepto la imagen que debe ser creada/liberada desde fuera. • CvPoint ** Malla::getMalla(): Devuelve la matriz asociada a la malla. • int getN(): Devuelve el ancho de la malla. • int getM(): Devuelve el alto de la malla. 3.2. Unit 1 Esta unidad contiene el formulario del proyecto, cuyos componentes realizan las llamadas necesarias para trabajar con la clase malla. A continuación se detallan los procedimientos más importantes de esta módulo. • void cb_wSrc(int event, int x, int y, int flags, void * param): Callback asociado a la ventana que muestra la imagen inicial del proceso de morphing. Principalmente se utiliza para modificar la malla que tiene asociada la imagen y para liberar la memoria reservada por la imagen abierta. • void cb_wDst(int event, int x, int y, int flags, void * param): Similar al anterior pero para trabajar con la imagen de destino del morphing. • void __fastcall TForm1::CSpinEdit1Change(TObject *Sender): Define el ancho de las mallas utilizadas. Se encarga de crear de nuevo las mallas que tienen asociadas a las imágenes inicial y final, si es necesario, además de mostrarlas. • void __fastcall TForm1::CSpinEdit2Change(TObject *Sender): Similar al anterior pero para el alto de las mallas. • void __fastcall TForm1::Button1Click(TObject *Sender): Abre la imagen inicial, crea la malla a la que relaciona con la imagen abierta y lanza una ventana de highgui2 para mostrar la imagen y su malla. Si se ha abierto ya la imagen de destino, se modifica el tamaño de la imagen inicial para que su tamaño sea igual al de la imagen final para que ambas tengan el mismo tamaño y generar así el video con imágenes del mismo tamaño. • void __fastcall TForm1::Button2Click(TObject *Sender): Misma funcionalidad que el método anterior pero correspondiente a la imagen final. 5 • void __fastcall TForm1::Button4Click(TObject *Sender): Botón Cerrar. Se encarga de cerrar la aplicación, cerrando las ventanas en las que se muestran las imágenes inicial y final del morphing y de liberar la memoria que se reservó para dichas imágenes, si es necesario. • void __fastcall TForm1::Button5Click(TObject *Sender): Guardar la animación de morphing en un archivo de video. Utiliza el método Morphing (explicado más adelante), con los parámetros apropiados para realizar la función descrita. • void __fastcall TForm1::Button6Click(TObject *Sender): Ver una imagen intermedia. Muestra en una nueva ventana la imagen del morphing, realizado con las imágenes abiertas, en la iteración i (donde el valor de i varía entre 0 y 1). Utiliza el método morphing_i de la clase malla. • void __fastcall TForm1::Button3Click(TObject *Sender): Muestra una ventana con cada una de las imágenes generadas en cada paso del algoritmo tan pronto como son generadas para simular una animación. • void __fastcall TForm1::TrackBar1Change(TObject *Sender): Actualiza la variable i, usada para definir la imagen a mostrar al pulsar Button6. • void TForm1::Morphing(CvVideoWriter *aw, bool prev): Método que contiene las llamadas necesarias a la clase malla (morphing_i) para realizar el morphing entre las imágenes abiertas, guardando el resultado en un descriptor de un video (CvVideoWriter *aw, si aw no es NULL) y mostrando la ‘previsualización’, en una nueva ventana, del proceso de morphing mientras se genera si es necesario (bool prev). Durante la ejecución de este método se muestra una barra de progreso. • void __fastcall TForm1::Button7Click(TObject *Sender): Similar a pulsar Button6 pero guardando la imagen en disco sin mostrarla. • void __fastcall TForm1::Button8Click(TObject *Sender): Cargar la malla, desde un fichero externo, que se asocia a la imagen inicial, modificando el tamaño de la malla utilizada en la imagen final al tamaño de la nueva malla cargada si fueran de diferentes tamaños. Hace uso del método cargar de la clase Malla. • void __fastcall TForm1::Button9Click(TObject *Sender): Misma funcionalidad que el método anterior pero para la malla de la imagen destino. • void __fastcall TForm1::Button10Click(TObject *Sender): Guarda en un fichero la malla a la que está asociada la imagen inicial. Utiliza el método guardar de la clase Malla. • void __fastcall TForm1::Button11Click(TObject *Sender): Igual que el anterior pero con la malla a la que se encuentra asociada la imagen final. • void __fastcall TForm1::CSpinEdit3Change(TObject *Sender): Actualiza el valor de CSpinEdit3 que indica el número de frames que se utilizan en el morphing y que se utiliza para mostrar adecuadamente la barra de progreso ProgressBar1. 6