[C con Clase] [Windows API] Transformación Afín
Steven Davidson
srd4121 en njit.edu
Vie Abr 13 04:23:36 CEST 2012
Hola Lourdes,
On 4/12/2012 7:37 PM, Lourdes Celene Haros Becerra wrote:
> Qué tal, buen día!!
>
> Revisé las pagina que me sugeriste
> http://graficos.conclase.net/curso/index.php?cap=006c#Transformaciones_Afines
> y sí me sirvió mucho, pero sigo con dudas para implementar que la
> imagen fuente gire con respecto a imagen destino... encontré aqui
> http://es.scribd.com/doc/63650237/54/Coordenadas-homogeneas-y-representacion-matricial
> en la pagina 99 información al respecto, pero nosé cómo
> implementarla, no sé si podrían ayudarme. Porq ahi habla de hacer la
> rotación respecto a un punto de pivote cualquiera, creo que es lo que
> necesito. Mi pregunta es ¿El vector por el que tengo que multiplicar
> cambia? ¿Cómo sería?... porq la ecuación de rotación con pivote en el
> origen es x'=xcos(theta) -ysin(theta) y'=xsin(theta)+ycos(theta)
>
Bueno, en primer lugar, ten cuidado con los términos que usas. Dudo que
estés usando vectores, sino más bien parejas ordenadas para representar
puntos o como dices posteriormente píxeles de una imagen.
En una imagen, guardamos las intensidades en cada píxel; y un píxel
requiere una pareja ordenada para referirnos a un píxel. Analíticamente,
podemos representar una imagen como una función de intensidades: f(x,y).
Esto significa que por cada pareja de coordenadas (x,y) podemos conocer
la intensidad, f, en tal píxel.
Las fórmulas explicadas tanto en el capítulo 6 de nuestro curso de
programación como en el libro del enlace sirven para puntos, que
seguramente describen vértices de un polígono, de un modelo analítico de
una figura en dos dimensiones. Por ejemplo, los vértices de un
rectángulo, de un triángulo, o de cualquier otro tipo de polígono en
general, al igual que un segmento, o incluso coordenadas para describir
curvas.
En tu caso, necesitas una variación de estas fórmulas para que funcionen
con píxeles de una imagen. Como todas las coordenadas en una imagen (de
píxeles) son válidas, tenemos que aplicar cualquier transformación a
TODOS los píxeles y por tanto tenemos que recorrer TODAS las
coordenadas. El algoritmo entonces podría ser el siguiente:
Imagen Rotar_Imagen( Imagen f, Dimensión M, Dimensión N, Ángulo a )
1. Crear Imagen: g de M x N
2. Inicializar 0 intensidad a todos los píxeles de "g" // 0 => Negro
3. Para: x = 0 hasta M-1
4. Para: y = 0 hasta N-1
5. u <- x * cos(a) - y * sen(a)
6. v <- x * cos(a) + y * sen(a)
7. g(u,v) <- f(x,y)
8. Terminar( g )
(Nota: uso <- para indicar "copiar" o "asignar"). Podemos asignar otro
valor incialmente a todos los píxeles de la imagen resultante, pero creo
que 0 tiene más sentido. También date cuenta que estamos creando una
nueva imagen en este algoritmo y además la rotación es alrededor del
origen (0,0). Si quieres otro "centro" para la rotación, entonces aplica
una traslación en la rotación.
El problema de implementar este algoritmo es que los cálculos de las
coordenadas de (u,v) pueden resultar en las mismas más de una vez y por
tanto estaríamos copiando diferentes intensidades al mismo píxel.
También puede darse el caso de que no todos los píxeles de la imagen
resultante son asignados, excepto por el valor inicial.
Una solución alternativa es aplicar la transformación inversa. Esto
significa que analizamos cada píxel de la imagen resultante usando sus
coordenadas en la transformación inversa para generar las coordenadas de
la imagen original y así consultar sus intensidades. Como se trata de
una rotación, su inversa es una rotación del ángulo negativo. El
algoritmo ahora sería,
Imagen Rotar_Imagen( Imagen f, Dimensión M, Dimensión N, Ángulo a )
1. Crear Imagen: g de M x N
2. Para: u = 0 hasta M-1
3. Para: v = 0 hasta N-1
4. x <- u * cos(a) + u * sen(a)
5. y <- v * cos(a) - v * sen(a)
6. g(u,v) <- f(x,y)
7. Terminar( g )
El paso #6 no es tan directo, porque tenemos que comprobar que las
coordenadas calculadas para (x,y) realmente existen; si no, entonces hay
que asignar algún valor como por ejemplo 0 (negro).
Como posiblemente obtendremos una imagen rotada con algunos píxeles
negros (intesidad cero), podemos aplicar una mejor solución para
aproximar la intensidad de esos píxeles sin intensidad, como es una
interpolación lineal de los píxeles cercanos o vecinos, interpolación
bilineal, o interpolación bicúbica.
Espero que todo esto te sirva.
Steven
Más información sobre la lista de distribución Cconclase