图像的仿射变换原理和实现

     仿射变换能够保持图像的“平直性”,包括旋转,缩放,平移,错切操作。一般而言,仿射变换矩阵为2*3的矩阵,第三列的元素起着平移的作用,前面两列的数字对角线上是缩放,其余为旋转或者错切的作用。

    设仿射变换矩阵T = [a11,a12,a13 ; a21,a22,a23]; 图像上fixed points坐标为(xk,yk);moving points坐标为(Xk,Yk),其中k=1,2,...,n。

     为了求解该仿射变换矩阵T的6个未知参数,理论上至少需要6个方程联立求解,即需要3组点集对,n>=3,当n>3时用最小二乘法求解未知参数。并且这三组点不共线。

数学展开式如下图:


下面根据上面公式给出实现代码,图像无插值。

%% 放射变换
clear ;
g=rgb2gray(imread('lena.jpg'));
imshow(g);

%% 用3个点集对图像进行仿射变换,调用matlab系统函数
fixedPoints = [1,1; 1,100;100,100];
movingPoints = [20,20; 120,80; 160,200];
tform = fitgeotrans(movingPoints,fixedPoints,'affine');
dst_img = imwarp(g,tform);
figure;imshowpair(g,dst_img,'montage');title('系统函数的仿射')

%% 用3个点集对图像进行仿射变换,解方程求变换矩阵
% T = [a11,a12,a13;a21,a22,a33];
fixed_pt_matrix = [fixedPoints';ones(1,3)];%3*n
moving_pt_matrix = movingPoints'; % 2*n
T = moving_pt_matrix/fixed_pt_matrix; %2*3
for i = 1:size(g,2) % col
    for j = 1:size(g,1)% row
        coridate = T*[i,j,1]';
        dst_affine_img(round(coridate(2)),round(coridate(1)))=g(j,i);
    end
end
figure;imshowpair(g,dst_affine_img,'montage');title('计算的仿射变换')


再看一个对点集的简单测试,T =  [1,1,0;2,1,0];

%% 坐标点的仿射变换
[pt_x,pt_y] = meshgrid(1:10);
pt_x = pt_x(:);
pt_y = pt_y(:);
figure;subplot(211);plot(pt_x,pt_y,'ro');grid on;
title('原始点集')
dst_pt = zeros(length(pt_x),2);
tf_affine = [1,1,0;2,1,0];
for i = 1:length(pt_x)
        dst = tf_affine*[pt_x(i),pt_y(i),1]';
        dst_pt(i,:) = [dst(1),dst(2)];
end
subplot(212);plot(dst_pt(:,1),dst_pt(:,2),'bo');grid on
title('仿射后点集')
reference:
https://ww2.mathworks.cn/help/images/ref/fitgeotrans.html?s_tid=srchtitle

猜你喜欢

转载自blog.csdn.net/cuixing001/article/details/80211136