仿射变换能够保持图像的“平直性”,包括旋转,缩放,平移,错切操作。一般而言,仿射变换矩阵为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