非常详细的一个说明,珍藏了。
今天,我们学习一下图像(2维平面)到图像(2维平面)的四种变换,等距变换,相似变换,仿射变换,投影变换 首先介绍它的原理,最后介绍matlab的实现
1.数学基础
射影变换矩阵HH属于射影群PL(n)PL(n)中的一个,仿射群是由PL(3)PL(3)中最后一行为(0,0,1)(0,0,1)的矩阵组成的子群,包括仿射群,欧式群,其中欧式群是仿射群的子群,其左上角的矩阵是正交的,当它的行列式为1是称为定向欧式群,距离是欧式群的不变量,但不是相似群的不变量,而夹角是这两个群的不变量。
听了这么多群,不变量的数学概念,可能有点晕,下面我用最直观的语言解释。线性空间中的线性变换可以用矩阵来描述,因此我们用矩阵来刻画这四种变换。我们以数学系的经典代数入门教材北大版的《高等代数》为例,研究这些变换是如何进行的
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/cde652f2921bed0f0062620a068311b1.png)
2. 等距变换
等距变换(isometric transform),保持欧式距离不变,当图像中的点用齐次坐标表示时,
其中 RR是旋转矩阵。 tt是平移矢量,有3个自由度(1旋转角 θθ+两个平移 tx,tytx,ty),需要2组点4个方程求解,等距变换的 不变量是:长度,角度,面积。用matlab实现等距变换如下:
clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
% test Eucludian transform
H_e=projective2d([cos(theta) -sin(theta) t(1);
sin(theta) cos(theta) t(2);
0 0 1]');
newimg=imwarp(I,H_e);
figure,imshow(newimg);
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/14539607703468dd6a0c61a9b5438cf8.png)
可以看出,等距变换就是对图像的旋转+平移
3. 相似变换
相似变换(similarity transform):等距变换+均匀缩放,当图像中的点用齐次坐标表示时,变换矩阵如下所示:
其中 RR是旋转矩阵。 tt是平移矢量, ss是缩放尺度,有4个自由度(1旋转角 θθ+2个平移 tx,tytx,ty+1个缩放尺度),需要2组点4个方程求解,相似变换的 不变量是:角度,长度的比例,面积的比例。用matlab实现相似变换如下:clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
%% test similar transform
H_s=projective2d([s*cos(theta) -s*sin(theta) t(1);
s*sin(theta) s*cos(theta) t(2);
0 0 1]');
newimg=imwarp(I,H_s);
figure,imshow(newimg);
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/02406f6090dfd2d4c81957478f1c4ec4.png)
可以看出,等距变换就是对图像的旋转+平移+缩放,这个图相对原图是变小了一些。
4. 仿射变换
仿射变换(affine transform):非奇异变换+均匀缩放,当图像中的点用齐次坐标表示时,变换矩阵如下所示:
其中 AA是仿射矩阵。 tt是平移矢量, ss是缩放尺度,有6个自由度(4个仿射矩阵的元素+2个平移 tx,tytx,ty),需要3组点6个方程求解。这里多说一句,仿射变换的 AA矩阵是可以做SVD分解的,即:clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
%% test affine transform
H_a=projective2d([1 0.5 t(1);
0 0.5 t(2);
0 0 1]');
newimg=imwarp(I,H_a);
figure,imshow(newimg);
可以看出,仿射变换就是对图像的旋转+平移+缩放+切变(shear),相比前两种变换图像的形状发生了改变,但是原图中的平行线仍然保持平行。
5. 射影变换
射影变换(projection transform):当图像中的点的齐次坐标的一般非奇异线性变换。
clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
%% test projective transform
H_P=projective2d([0.765,-0.122,-0.0002;
-0.174,0.916,9.050e-05;
105.018,123.780,1]);
newimg=imwarp(I,H_P);
figure,imshow(newimg);
可以看出,射影变换就是对图像的旋转+平移+缩放+切变+射影,相比前三种变换图像的形变更为自由,原图中的平行线经过变换之后已经不在平行,而可能相交于一点,射影变换就是把理想点(平行直线在无穷远处相交)变换到图像上。
6 应用
说了这么多,下边举一个简单的小应用,就是把通过求两幅对应点的单应性矩阵(射影矩阵),把一种图片变换成另一张的形状。如图:
选择两幅图像对应的四个点
第一幅
![第一幅](https://i-blog.csdnimg.cn/blog_migrate/11339737bc67a67fe08c58bde4e588c4.png)
第二幅
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/7051963c23d8e34f2b7098070ee40d78.png)
变换的结果
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/c5d0ae9ba1a02e79d6a4fb745fde832e.png)
%% Initial
clear;
clc;
img_num=2; %the number of image
compress_scale=0.4; %define image compress scale
points_p=[0 0;1 0;2 1;2 0]; %define cordinate of 2D plain in 3D space
%% define a cell that load image
Image=cell(1,img_num);
%% read the image
Image{1,1}=imread('book1.jpg');
Image{1,2}=imread('book2.jpg');
%% image compression, transform rgb to gray, and select feature points
feature=[];
for i=1:img_num
Image{1,i}=imresize(Image{1,i},compress_scale);
I{:,:,i}=Image{1,i};
Image{1,i}=rgb2gray(Image{1,i});
imshow(Image{1,i});
hold on;
for j=1:4
[x,y]= ginput(1); %select the corner
x=round(x);
y=round(y);
plot(x,y,'ro');
feature(j,2*i-1)=x; %feature is a matrix containing corner cordination
feature(j,2*i)=y;
end
close all;
end
%% calculate homegraphy matrix for each matrix
featurep1=feature(:,1:2);
featurep2=feature(:,3:4);
h = calc_homography(featurep2, featurep1);
Im=I{:,:,2};
[a,b]=size(I);
tform=projective2d(h);
J=imwarp(Im,tform); % matlab自带的处理图像变换的函数
figure,imshow(I{:,:,1});
figure,imshow(I{:,:,2});
figure,imshow(J)
函数calc_homegraphy的代码如下:
function T = calc_homography(points1, points2)
xaxb = points2(:,1) .* points1(:,1);
xayb = points2(:,1) .* points1(:,2);
yaxb = points2(:,2) .* points1(:,1);
yayb = points2(:,2) .* points1(:,2);
A = zeros(size(points1, 1)*2, 9);
A(1:2:end,3) = 1;
A(2:2:end,6) = 1;
A(1:2:end,1:2) = points1;
A(2:2:end,4:5) = points1;
A(1:2:end,7) = -xaxb;
A(1:2:end,8) = -xayb;
A(2:2:end,7) = -yaxb;
A(2:2:end,8) = -yayb;
A(1:2:end,9) = -points2(:,1);
A(2:2:end,9) = -points2(:,2);
[~,~,V] = svd(A);
h = V(:,9) ./ V(9,9);
T= reshape(h,3,3);
end