Finding Affine Transform with Linear Least Squares
linear least squares is a method of fitting a model to data in which the relation between data and unknown paramere can be expressed in a linear form. \( Ax=b\) \( X^{*}= \underset{x}{\mathrm{argmin}}= \|Ax-b\|^{2} =(A^{T}A)^{-1}A^{T}b \)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
function M= affine_least_square(x0,y0, x1,y1, x2,y2, xp0,yp0, xp1,yp1, xp2,yp2) % This function finds the affine transform between three points % an affine transformation with a 3x3 affine transformation matrix: % % [M11 M12 M13] % [M21 M22 M23] % [M31 M32 M33] %Since the third row is always [0 0 1] we can skip that. % [x0 y0 1 0 0 0 ] [M11] [xp0] % [0 0 0 x0 y0 1 ] [M12] [yp0] % [x1 y1 1 0 0 0 ] [M13] [xp1] % [0 0 0 x1 y1 1 ] * [M21] = [yp1] % [x2 y2 1 0 0 0 ] [M22] [xp2] % [0 0 0 x2 y2 1 ] [M23] [yp2] % A * X = B %A -> 6x6 %X -> 6x1 in fact %X=A\B A=[x0 y0 1 0 0 0 ; 0 0 0 x0 y0 1 ; x1 y1 1 0 0 0 ; 0 0 0 x1 y1 1 ; x2 y2 1 0 0 0;0 0 0 x2 y2 1]; B=[xp0; yp0; xp1; yp1; xp2 ; yp2 ]; % X=A\B; % this is what we need but accroding to https://www.mathworks.com/matlabcentral/newsreader/view_thread/170201 %The following is better: X=pinv(A)*B; M11 =X(1,1); M12 =X(2,1); M13 =X(3,1); M21 =X(4,1); M22 =X(5,1); M23 =X(6,1); M=[ M11 M12 M13; M21 M22 M23; 0 0 1]; end |
And testing the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
clc; clear all; %This is a simple test that project 3 point with an affine trasnform and %then tries to find the transformation: % tform.T and M' should be equal %Points are located at: x0=0; y0=0; x1=1; y1=0; x2=0; y2=1; p1=[x0,y0; x1,y1; x2,y2]; %We rotate them (a roll-rotation around Z axes) theta degree, first %building the rotation matrix theta=24; A11=cosd(theta); A12=-sind(theta); A21=sind(theta); A22=cosd(theta); %Translation part Tx=1; Ty=2; tform = affine2d([A11 A12 0; A21 A22 0; Tx Ty 1]); fprintf('3x3 transformation matrix:') tform.T [x,y]=transformPointsForward(tform,p1(:,1),p1(:,2)); fprintf('transformed points:') [x,y] xp0=x(1,1); yp0=y(1,1); xp1=x(2,1); yp1=y(2,1); xp2=x(3,1); yp2=y(3,1); %finding the tranformation matrix from set of points and their respective %transformed points: M=affine_least_square(x0,y0, x1,y1, x2,y2, xp0,yp0, xp1,yp1, xp2,yp2); fprintf('3x3 affine transformation matrix from least_squares:') M' tform = affine2d(M'); [x,y]=transformPointsForward(tform,p1(:,1),p1(:,2)); [x,y]; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
3x3 transformation matrix: ans = 0.9135 -0.4067 0 0.4067 0.9135 0 1.0000 2.0000 1.0000 transformed points: ans = 1.0000 2.0000 1.9135 1.5933 1.4067 2.9135 3x3 affine transformation matrix from least_squares: ans = 0.9135 -0.4067 0 0.4067 0.9135 0 1.0000 2.0000 1.0000 |
Finding Affine Transform with Linear Least Squares Read More »