In the figure below the goal is to compute the homography matrix H which transforms the points a1 a2 a3 a4 to their counterparts b1 b2 b3 b4. That is:
[b1 b2 b3 b4] = H * [a1 a2 a3 a4]
What way would you suggest to be the best way to calculate H(3x3). a1...b4 are points in 2D which are represented in homogeneous coordinate systems ( that is [a1_x a1_y 1]', ...). EDIT: For these types of problems we use SVD, So i would like to see how this can be simply done in Matlab.
EDIT:
Here is how I initially tried to solve it using svd (H=Q/P) in Maltlab. Cosider the following code for the given example
px=[0 1 1 0]; % a square
py=[1 1 0 0];
qx=[18 18 80 80]; % a random quadrangle
qy=[-20 20 60 -60];
if (DEBUG)
fill(px,py,'r');
fill(qx,qy,'r');
end
Q=[qx;qy;ones(size(qx))];
P=[px;py;ones(size(px))];
H=Q/P;
H*P-Q
answer:
-0.0000 0 0 0 0
-20.0000 20.0000 -20.0000 20.0000 0.0000
-0.0000 0 0 0 -0.0000
I am expecting the answer to be a null matrix but it is not!... and that's why I asked this question in StackOverflow. Now, we all know it is a projective transformation not obviously Euclidean. However, it is good to know if in general care calculating such matrix using only 4 points is possible.
You can use the DLT algorithm for this purpose. There are MATLAB routines available for doing that in Peter Kovesi's homepage.
Using the data you posted:
Compute the transformation:
apply the transformation:
Compare the results:
output:
which is zeros for all intents and purposes..
EDIT:
So as you pointed out in the comments, the above method will not compute the 3x3 homography matrix. It simply solves the system of equations with as many equations as points provided:
Otherwise, MATLAB has the CP2TFORM function in the image processing toolbox. Here is an example applied to the image shown:
With the corners detected, now we can obtain the spatial transformation:
The result:
We can confirm the calculation ourselves:
which maps to the points in B:
You can try the
cp2tform
function, which infers spatial transformation from control point pairs. Since parallel is not preserved in your case, you should set thetransformtype
to be 'projective'. More info is hereCombine all the coordinates into column vectors. In 2D case they are:
ax
,ay
,bx
,by
;Define:
Calculate transformation matrix:
If you need to apply it on new observations
A_new
:Edit: you can also calculate
H
by:H = inv(input' * input) * input' * B;
but\
does if safely.I discussed a related problem in an answer to another SO question (includes a MATLAB solution). In the linked problem, the output quadrilateral was a rectangle, but my answer handles the general problem.