Create QTransform given 4 points defining the transformed unit square

Given 4 points being be the result of

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

how can I find QTransform transform ? (Even better: also given an arbitrary source rectangle)

Motivation: Given the four corner points of an image to be drawn in a perspectively distorted coordinate system, how can I draw the image using QPainter?

问题的例证

This is a screenshot illustrating the problem in GIMP, where one can transform a layer by moving around the 4 corners of the layer. This results in a perspective transformation. I want to do exactly the same in a Qt application. I know that QTransform is not restricted to affine transformations but can also handle perspective transformations.


You should be able to do this with QTransform.squareToQuad . Just pass it the QPolygonF you want to transform to.

I've sometimes had some issues getting squareToQuad to do what I want, and have had to use QTransform.quadToQuad instead, defining my own starting quad, but you might have more luck.


I think I found a solution, which calculates the transformation matrix step by step.

// 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());

Until now, trans describes a parallelogram transformation. Within this paralellogram, I find p4 (relatively) in the next step. I think that this can be done using a direct formula not involving an inversion of 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;

The values x and y are hard to explain. Given only one of them (the other set to 1 ), this defines the relative scaling of p4 only. But a combination of both x and y perspective transformation, the meaning of x and y are difficult; I found the formulas by trial and 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;

Some tests showed that this leads to the correct results. However, I did not tested special cases like those where two points are equal or one of them is on the line segment between two others; I think that this solution might break in such situations.

Therefore, I still search for some direct formulas for the matrix values m11 , m12 ... m33 , given the point coordinates p1.x() , p1.y() ... p4.x() , p4.y() .

链接地址: http://www.djcxy.com/p/10980.html

上一篇: 存储排序顺序/优先级的最佳方法?

下一篇: 创建QTransform给定4个点,定义变换后的单位正方形