2012-07-16 8 views
7

Dadas 4 puntos que sea el resultado deCrear QTransform dados 4 puntos de definición de la unidad transformado cuadrados

QPolygon poly = transform.mapToPolygon(QRectF(0, 0, 1, 1)); 

cómo puedo encontrar QTransform transform? (Mejor aún: dado también un rectángulo de origen arbitrario)

motivación: Dadas las cuatro esquinas de una imagen que se pueden extraer en un sistema de coordenadas en perspectiva distorsionada, ¿cómo puedo sacar yo la imagen utilizando QPainter?

Illustration of the problem

Esta es una captura de pantalla que ilustra el problema en GIMP, donde uno puede transformar una capa moviendo alrededor de las 4 esquinas de la capa. Esto resulta en una transformación de perspectiva. Quiero hacer exactamente lo mismo en una aplicación Qt. Sé que QTransform no está restringido a transformaciones afines, sino que también puede manejar transformaciones de perspectiva.

+0

Nota: actualmente trato de resolver el problema. Comienzo con p1 (que es el punto superior izquierdo mapeado (0,0)): Por lo tanto, solo uso una matriz de traducción. p2 y p3 pueden alcanzarse usando una matriz de escala y cizallamiento. Pero tengo problemas para llegar a p4: no entiendo las matemáticas detrás de la transformación de perspectiva y, por lo tanto, no sé cómo el número de las entradas de la matriz en la tercera columna afecta la transformación. – leemes

Respuesta

2

Debería poder hacer esto con QTransform.squareToQuad. Simplemente pase el QPolygonF al que desea transformarse.

A veces he tenido algunos problemas para que squareToQuad haga lo que quiero, y he tenido que usar QTransform.quadToQuad en su lugar, definiendo mi propio quad inicial, pero es posible que tenga más suerte.

+0

Nuevamente, muchas gracias. Maldición, todo mi trabajo con todas las matemáticas fue en vano ... :) – leemes

1

Creo que encontré una solución que calcula la matriz de transformación paso a paso.

// some example points: 
QPointF p1(1.0, 2.0); 
QPointF p2(2.0, 2.5); 
QPointF p3(1.5, 4.0); 
QPointF p4(3.0, 5.0); 

// define the affine transformation which will position p1, p2, p3 correctly: 
QTransform trans; 
trans.translate(p1.x(), p1.y()); 
trans.scale(p2.x() - p1.x(), p3.y() - p1.y()); 
trans.shear((p3.x() - p1.x())/trans.m11(), (p2.y() - p1.y())/trans.m22()); 

Hasta ahora, trans describe una transformación de paralelogramo. Dentro de este paralellograma, encuentro p4 (relativamente) en el siguiente paso. Creo que esto se puede hacer usando una fórmula directa que no implique una inversión de trans.

// relative position of the 4th point in the transformed coordinate system: 
qreal px = trans.inverted().map(p4).x(); 
qreal py = trans.inverted().map(p4).y(); 

// this defines the perspective distortion: 
qreal y = 1 + (py - 1)/px; 
qreal x = 1 + (px - 1)/py; 

Los valores x y y son difíciles de explicar. Dado solo uno de ellos (el otro conjunto a 1), esto define la escala relativa de p4 solamente. Pero una combinación de transformación de perspectiva xey, el significado de xey son difíciles; Encontré las fórmulas por prueba y error.

// and thus the perspective matrix: 
QTransform persp(1/y, 0, 1/y-1, 
       0, 1/x, 1/x-1, 
       0, 0, 1); 

// premultiply the perspective matrix to the affine transformation: 
trans = persp * trans; 

Algunas pruebas mostraron que esto conduce a los resultados correctos. Sin embargo, no probé casos especiales como aquellos donde dos puntos son iguales o uno de ellos está en el segmento de línea entre otros dos; Creo que esta solución podría romperse en tales situaciones.

Por lo tanto, todavía busco algunas fórmulas directas para los valores de la matriz m11, m12 ... m33, dadas las coordenadas del punto p1.x(), p1.y() ... p4.x(), p4.y().

+0

¿No debería poder usar QTransform.squareToQuad? – dmd

+0

Aaaaah, muchas gracias @dmd, esto es exactamente lo que estaba buscando, por supuesto.No usé RTFM lo suficiente, o mejor dicho, el nombre de la función no era lo que esperaba para una función así, ¡que hace exactamente lo que quiero! – leemes

+0

@dmd, si lo escribe como respuesta, lo aceptaré. – leemes

Cuestiones relacionadas