Search code examples
matlabimage-processingmatrixgeometrycoordinate

How to Find Affine Transform Between Triangles?


Using Matlab, I'm trying to solve an affine transformation of 6 triangles (see A and Aprime)...

3 triangles are in A

triangle1: points 1,2,3 of A 
triangle2: points 4,5,6 of A 
triangle3: points 7,8,9 of A 

Where X/Y coordinates of A are :
A.x = [x1 x2 x3; x4 x5 x6; x7 x8 x9]
and A.y = [y1 y2 y3; y4 y5 y6; y7 y8 y9]

And there's also 3 triangles in Aprim.

triangle5:points 1,2,3 of Aprim 
triangle6:points 4,5,6 of Aprim 
triangle7:points 7,8,9 of Aprim

Where X/Y coordinates of Aprim are :
Aprim.x = [xp1 xp2 xp3; xp4 xp5 xp6; xp7 xp8 xp9]
and Aprim.y = [yp1 yp2 yp3; yp4 yp5 yp6; yp7 yp8 yp9]

I need to find affine transforms that map each triangle of A to triangle of Aprim in this way:

  • t1 is affine transform that map triangle1 of A to triangle1 of Aprim.
  • t2 is affine transform that map triangle2 of A to triangle2 of Aprim.
  • t3 is affine transform that map the points triangle3 of A to triangle3 of Aprim.

Problem #1 : In my code, tform only give me affine transform t3. I don't know how to change it to know affine transform for t1, t2, t3.
Problem #2 : My other problem is that in tform matrix, which elements are translation,rotation,scaling values? how to find scaling ,rotation angle and translation values?

Can anybody help me to correct my matlab code below? How to solve t1, t2 and t3?

My code is :

A.x=[309  367  295;273  268 298;295 367 298];            
A.y=[292  259  277;228  253  225;277 259 225];   
Aprim.x=[267  211  265;267  261 295;259  261 211]; 
Aprim.y=[301  222  325;301  270 306;213  112 222];
for  i=1:3
A_xprim(1:3,i)= transpose(Aprim.x(i,1:3));
A_yprim(1:3,i)=transpose(Aprim.y(i,1:3));


Ax(1:3,i)= transpose(A.x(i,1:3));
Ay(1:3,i)=transpose(A.y(i,1:3));

tform = maketform('affine',[A_xprim(1:3,i) A_yprim(1:3,i)],[ Ax(1:3,i)  Ay(1:3,i)]);
end 

Solution

  • #1: That's because you are trying to store all transformation structs in one variable. Try this:

    tform(i) = maketform('affine', ...);
    

    #2: The transformation matrix is stored in tform(i).data.T. And this is the documentation about its elements. But in your case the transformation matrix is actually the result of matrix multiplication of basic affine transforms (translation, rotation, scale and shear). For example we can't say first element shows the value of scale along x-axis or cosine of rotation angle.

    The other problem is that you said that you want to map each triangle of A to triangle of Aprim, but the code seem to to do the opposite. I edited your code to test the results:

    clc; clear; close all;
    A.x=[309  367  295;273  268 298;295 367 298];
    A.y=[292  259  277;228  253  225;277 259 225];
    Aprim.x=[267  211  265;267  261 295;259  261 211];
    Aprim.y=[301  222  325;301  270 306;213  112 222];
    for  i=1:3
        Axprim(1:3,i)= transpose(Aprim.x(i,1:3));
        Ayprim(1:3,i)=transpose(Aprim.y(i,1:3));
    
        Ax(1:3,i)= transpose(A.x(i,1:3));
        Ay(1:3,i)=transpose(A.y(i,1:3));
    
        tform(i) = maketform('affine',[Ax(1:3,i) Ay(1:3,i)],[ Axprim(1:3,i)  Ayprim(1:3,i)]);
    end
    
    [X, Y] = meshgrid(260:5:370, 220:5:300);
    n = numel(X);
    C = ones(n, 3);
    [~, I] = sort(X(:)+Y(:));
    C(I, 1) = linspace(0, 1, n);
    C = hsv2rgb(C);
    
    TX = [A.x A.x(:, 1)];
    TY = [A.y A.y(:, 1)];
    TPX = [Aprim.x Aprim.x(:, 1)];
    TPY = [Aprim.y Aprim.y(:, 1)];
    
    subplot(221); hold on; axis equal;
    
    scatter(X(:), Y(:), 100, C, '.');
    plot(TX', TY', 'linewidth', 2); 
    plot(TPX', TPY', '--', 'linewidth', 2);
    xlabel('X'); ylabel('Y');
    for i = 1:3
        subplot(2, 2, i+1);
        axis equal; hold on;
        [U, V] = tformfwd(tform(i), X(:), Y(:));
        scatter(U(:), V(:), 100, C, '.');
        plot(TPX', TPY', 'linewidth', 2);
        xlabel('U'); ylabel('V');
    end
    

    enter image description here