6

I want to transform an image.

As far as I was able to find out, I can achieve this with a matrix, right?

So here is my problem: how do I get this matrix if the only thing I know are the following starting and ending points?

$$\begin{matrix} \text{Starting Points} & \text{Target Points} \\ \mathrm{TL}(3,5) & \mathrm{TL}'(0,3) \\ \mathrm{TR}(5,5) & \mathrm{TR}'(3,3) \\ \mathrm{LL}(2,2) & \mathrm{LL}'(0,0) \\ \mathrm{LR}(6,1) & \mathrm{LR}'(3,0) \end{matrix}$$

enter image description here

dfeuer
  • 9,069
WiiMaxx
  • 163
  • I don't think an affine transformation will work. In general, it will only allow you to map 3 points to 3 points. To map 4 points, you need something a bit more complex, like a "perspective" mapping. – bubba Jul 12 '13 at 11:08
  • @bubba and how do i map perspective? – WiiMaxx Jul 12 '13 at 11:16
  • Sorry ... The 4 point to 4 point mapping is described in this answer: http://math.stackexchange.com/questions/62936/tranforming-2d-outline-into-3d-plane/63100#63100 – bubba Jul 12 '13 at 11:26
  • 1
    For more info, look up the terms "homography", "perspective mapping", or "collineation". – bubba Jul 12 '13 at 11:29
  • There is code here: http://www.codeproject.com/Articles/36145/Free-Image-Transformation – bubba Jul 12 '13 at 11:53
  • If you have access to the Qt package, use QTransform::quadToSquare – bubba Jul 12 '13 at 12:05

4 Answers4

8

Many graphics packages have functions to construct a 4-point-to-4-point transform of the type you need. For example, Qt has QTransform::quadToSquare and QTransform::quadToQuad, and OpenCV has GetPerspectiveTransform.

The transformation can not be linear or affine, it has to be a "perspective" transform.

If you want to code it yourself, this article tells you how. The formulae from that article are shown more clearly below:

If we want to transform the four points $(x_i, y_i)$ to the four points $(u_i, v_i)$ for $i=0,1,2,3$, we can use a perspective transform of the form: $$ u_i = \frac{a_0 x_i + a_1 y_i + a_2}{c_0 x_i + c_1 y_i + 1 } \quad ; \quad v_i = \frac{b_0 x_i + b_1 y_i + b_2}{c_0 x_i + c_1 y_i + 1 } $$ The eight unknown coefficients $a_0, a_1, a_2, b_0, b_1, b_2, c_0, c_1$ can be calculated by solving the following linear system:

$$ \begin{bmatrix} x_0 & y_0 & 1 & 0 & 0 & 0 & -x_0u_0 & -y_0u_0 \\ x_1 & y_1 & 1 & 0 & 0 & 0 & -x_1u_1 & -y_1u_1 \\ x_2 & y_2 & 1 & 0 & 0 & 0 & -x_2u_2 & -y_2u_2 \\ x_3 & y_3 & 1 & 0 & 0 & 0 & -x_3u_3 & -y_3u_3 \\ 0 & 0 & 0 & x_0 & y_0 & 1 & -x_0v_0 & -y_0v_0 \\ 0 & 0 & 0 & x_1 & y_1 & 1 & -x_1v_1 & -y_1v_1 \\ 0 & 0 & 0 & x_2 & y_2 & 1 & -x_2v_2 & -y_2v_2 \\ 0 & 0 & 0 & x_3 & y_3 & 1 & -x_3v_3 & -y_3v_3 \end{bmatrix} \begin{bmatrix} a_0 \\ a_1 \\ a_2 \\ b_0 \\ b_1 \\ b_2 \\ c_0 \\ c_1 \end{bmatrix} = \begin{bmatrix} u_0 \\ u_1 \\ u_2 \\ u_3 \\ v_0 \\ v_1 \\ v_2 \\ v_3 \end{bmatrix} $$

There are many available software packages for solving linear systems of equations. One option is the "Numerical Recipes" book/package, which has functions called ludcmp and lubksb. The first of these computes the LU decomposition of a matrix, and then the second one uses this LU decomposition to solve a linear system. There is a long discussion of how to use ludcmp and lubksb here.

In your particular example, we have $$ (x_0, y_0) = (3,5) \\ (x_1, y_1) = (5,5) \\ (x_2, y_2) = (2,2) \\ (x_3, y_3) = (6,1) \\ (u_0, v_0) = (0,3) \\ (u_1, v_1) = (3,3) \\ (u_2, v_2) = (0,0) \\ (u_3, v_3) = (3,0) \\ $$ The system of equations is $$ 3 a_0 + 5 a_1 + a_2 = 0 \\ 5 a_0 + 5 a_1 + a_2 - 15 c_0 - 15 c_1 = 3 \\ 2 a_0 + 2 a_1 + a_2 = 0 \\ 6 a_0 + a_1 + a_2 - 18 c_0 - 3 c_1 = 3 \\ 3 b_0 + 5 b_1 + b_2 - 9 c_0 - 15 c_1 = 3 \\ 5 b_0 + 5 b_1 + b_2 - 15 c_0 - 15 c_1 = 3 \\ 2 b_0 + 2 b_1 + b_2 = 0 \\ 6 b_0 + b_1 + b_2 = 0 $$ I solved this system of equations using Mathematica, and I got $$ a_0 = \frac{36}{49} \quad ; \quad a_1 = -\frac{12}{49} \quad ; \quad a_2 = -\frac{48}{49} \\ b_0 = \frac{24}{245} \quad ; \quad b_1 = \frac{96}{245} \quad ; \quad b_2 = -\frac{48}{49} \\ c_0 = \frac{8}{245} \quad ; \quad c_1 = -\frac{33}{245} $$ So, the required transformation (after some simplification) is $$ u = \frac{60 (3 x-y-4)}{8 x-33 y+245} \\ v = \frac{24 (x+4 y-10)}{8 x-33 y+245} $$ You can easily confirm that this transform maps the four given points correctly.

bubba
  • 43,483
  • 3
  • 61
  • 122
  • ok i know this will sound stupid to you but i don't know what variable which represend what value based on your link i suggest the first Matrix X(x0-n,y0-n) are my startpoints and Matrix C (c0-n) is the Matrix i'm looking so Matrix U(u0-n v0-n) is my Target but i have read there is no Matrix division so there is no way to U/X = C ????? – WiiMaxx Jul 12 '13 at 13:02
  • Well, in some sense, there is a concept of matrix division. If $XC = U$, then $C = X^{-1}U$. The "division" corresponds to matrix inversion. Solving a linear system of equations is somewhat equivalent to inverting a matrix. You will need to find a function for solving linear systems of equations. – bubba Jul 12 '13 at 13:25
  • Or, if it's easier, find a function for inverting matrices. Inverting the coefficient matrix is generally not a very good way to solve a linear system of equations, but it will probably work OK in this case. – bubba Jul 12 '13 at 13:29
  • so each function will solve one coefficient but how to i get this single linear function? :( will it be the 1x8 by 8x1 Multiplication? like U0= X0*a0+Y0*a1+1*a2+0*b0+0*b1+0*b2-X0*U0-Y0*U0 – WiiMaxx Jul 12 '13 at 13:29
  • 1
    You can't solve the equations one at a time, because each equation involves several unknowns. So, you have to solve the entire system of equations all together, simultaneously. There are many available software packages for doing this. Look up "linear system solver", for example. If you want to understand the internal details, you can read this article: http://msdn.microsoft.com/en-us/magazine/jj863137.aspx – bubba Jul 12 '13 at 23:30
  • One option for solving a system of linear equations: the "Numerical Recipes" book/package has functions called ludcmp and lubksb. The first of these computes the LU decomposition of a matrix, and then the second one uses this LU decomposition to solve a linear system. – bubba Jul 13 '13 at 00:23
  • There is a long discussion of how to use ludcmp and lubksb here: http://www.nr.com/forum/archive/index.php/t-1397.html – bubba Jul 13 '13 at 00:43
  • Thank you very much for spending your time to help me :) – WiiMaxx Jul 13 '13 at 08:25
  • I'm a little confused why the transformation has to be "perspective" and asked about it in a follow up question here: http://math.stackexchange.com/questions/1313214/why-can-the-transformation-derived-from-a-list-of-points-and-a-list-of-their-tra – null Jun 05 '15 at 11:55
  • Do the eight unknowns mean anything physically? Perhaps three represent rotations about X/Y/Z, another three represent translations, and two might represent scaling? Very tentative question. Thanks! – Ahmed Fasih Nov 28 '16 at 04:59
  • The assumption/constraint c2=1 will mess things up when the answer actually has a zero or near-zero in that position-- you'll get a divide-by-zero or instability. Idea for fixing that: leave c2 in the system as an unknown, so you have 9 unknowns; and add equation c0+c1+c2=1, so there will be 9 equations. I think this should fix it because c0+c1+c2≠0 is a reasonable constraint, whereas c2≠0 is not. – Don Hatch Jun 22 '23 at 22:20
  • Upon further thought, $c0+c1+c2≠0$ is not a reasonable constraint after all, e.g. $-x+1$ is a perfectly good and not-even-unusual denominator. So I don't know how to fix this method. An alternative method, which doesn't seem to have the problem, is given by @MvG in https://math.stackexchange.com/questions/296794/finding-the-transform-matrix-from-4-projected-points-with-javascript/339033?noredirect=1#answer-339033 – Don Hatch Jun 23 '23 at 12:17
3

Let's look for an affine transformation to do what you like. This transformation will act on points in the plane (vectors in $\mathbb{R}^2$) and produce points in the plane, and will be given by $T(\vec{x}) = A \vec{x} + \vec{v}$ for some matrix $A$ and vector $\vec{v}$ which we shall find. Since we take points in the plane and produce points in the plane, $A$ must be $2 \times 2$, say with entries $a,b,c,d$ and $\vec{v}$ is also in the plane, with entries $e,f$.

Now your points give us 8 constraints on 6 variables $a,b,c,d,e,f$ - let's write down a couple and you can finish the rest and just solve the resulting system of linear equations (say, by Gaussian Elimination, or by Wolfram Alpha).

First point maps $(3,5) \to (0,3)$ so $$ 3a+5b+e = 0 \text{ and } 3c+5d+f = 3 $$ Second point maps $(5,5) \to (3,3)$ so $$ 5a+5b+e = 3 \text{ and } 5c+5d+f = 3 $$ Third point maps $(2,2) \to (0,0)$ so $$ 2a+2b+e = 0 \text{ and } 2c+2d+f = 0 $$ Fourth point maps $(1,6) \to (3,0)$ so $$ 1a+6b+e = 3 \text{ and } 1c+6d+f = 0 $$

Summarizing we get to solve $$ \begin{bmatrix} 3 & 5 & 1 \\ 5 & 5 & 1 \\ 2 & 2 & 1 \\ 1 & 6 & 1 \end{bmatrix} \begin{bmatrix} a & c\\ b & d\\ e & f\end{bmatrix} = \begin{bmatrix} 0 & 3\\ 3 & 3 \\ 0 & 0 \\ 3 & 0\end{bmatrix} $$ You can use the first three to solve and plug it into the fourth to check it.

gt6989b
  • 54,422
  • Aaaand you're way faster than me. – dfeuer Jul 11 '13 at 21:53
  • mhh and after i get my matrix i can transform each point (x,y) as (x,y,1) by multiplying it with my matrix right so far? – WiiMaxx Jul 12 '13 at 06:27
  • @gt6989b after some more recherche and testing your suggestion my check with the fourth equation always fails so it thing we miss the Perspective which will create a 4x4 matrix right? – WiiMaxx Jul 12 '13 at 10:03
  • @WiiMaxx yes, you can introduce a perspective, that should give you another 2 parameters to work with... But I haven't done serious computer graphics since college. – gt6989b Jul 12 '13 at 13:31
  • @gt6989b but you are still far far better than me in this thing'S :) i didn't love it at school and now i need it and i'm not able to understand it with out a detailed example :( – WiiMaxx Jul 12 '13 at 13:36
  • An affine transform will work only when the original four points form a parallelogram. That's why the "checking" of the fourth point fails in this example. – bubba Jul 13 '13 at 01:10
2

What you're (presumably) looking to perform is called an affine transformation. An affine transformation in two dimensions is determined by how three points transform. So there may or may not be one that does what you want here. It's possible (and very common in computer graphics) to represent an affine transformation as a linear transformation by adding an extra dimension, but at this juncture I would speculate that you're probably better off sticking to the affine form for right now.

dfeuer
  • 9,069
0

You did not specify if you are looking for a linear transform or other? Since you mention matrix and no functions of start points, I am assuming it is a linear one you want.

Since you don't specify any other conditions (e.g., preservation of length, angles, etc.), your x- and y-coordinates do not need to be related by extra conditions, so you can write each start point as $(x_i,y_i)$ and each target point as $(x^\prime_i,y^\prime_i)$. Define $\bf{X} = [x_1 ... x_4 y_1 ... y_4]$ and $\bf{Y} = [x^\prime_1 ... x^\prime_4 y^\prime_1 ... y^\prime_4]$. Then you can set up an $8\times 8$ linear system $\bf{Y} = A \cdot \bf{X}$ with the elements of the matrix $A$ as unknowns. However, you will need to specify 4 more dummy points and their images to obtain a possible matrix solution.

Lucozade
  • 733