Matlab图像旋转
点 p0 绕坐标原点逆时针方向旋转 θ 角度得到点 p1 .
从①②可以得到旋转变换的矩阵公式:
[x1y11] = [x0y01] ⎡⎣⎢cos(θ)−sin(θ)0sin(θ)cos(θ)0001⎤⎦⎥
还可以得到逆运算矩阵公式:
[x0y01] = [x1y11] ⎡⎣⎢cos(θ)sin(θ)0−sin(θ)cos(θ)0001⎤⎦⎥
从上图可知以任意图形中心点为坐标原点旋转我们需要三步:
(1)将坐标系Ⅰ变成坐标系Ⅱ
(2)在坐标系Ⅱ中旋转 θ 角
(3)将坐标系Ⅱ变成坐标系Ⅰ
由Figure1得到Figure2可知,变换矩阵为:
⎡⎣⎢xⅡyⅡ1⎤⎦⎥ = ⎡⎣⎢xⅠyⅠ1⎤⎦⎥ ⎡⎣⎢10−0.5w0−10.5h001⎤⎦⎥ = ⎡⎣⎢xⅠ−0.5w−(yⅠ−0.5h)1⎤⎦⎥
见上面以坐标原点为中心旋转的原理
由Figure3得到Figure4可知,变换矩阵为(其实就是(1)中变换矩阵的逆变换):
⎡⎣⎢xⅠyⅠ1⎤⎦⎥ = ⎡⎣⎢xⅡyⅡ1⎤⎦⎥ ⎡⎣⎢100.5nW0−10.5nH001⎤⎦⎥ = ⎡⎣⎢xⅡ+0.5nW−yⅡ+0.5nH1⎤⎦⎥
从而将三步合起来,可以得到以任意图像中心为坐标原点旋转的变换矩阵:
⎡⎣⎢x1y11⎤⎦⎥ = ⎡⎣⎢x0y01⎤⎦⎥ ⎡⎣⎢10−0.5w0−10.5h001⎤⎦⎥ ⎡⎣⎢cos(θ)−sin(θ)0sin(θ)cos(θ)0001⎤⎦⎥
⎡⎣⎢100.5nW0−10.5nH001⎤⎦⎥ = ⎡⎣⎢x0y01⎤⎦⎥ ⎡⎣⎢cos(θ)sin(θ)−0.5wcos(θ)−0.5hsin(θ)+0.5nW−sin(θ)cos(θ)−0.5wsin(θ)+0.5hcos(θ)+0.5nH001⎤⎦⎥
它的逆变换为:
⎡⎣⎢x0y01⎤⎦⎥ = ⎡⎣⎢x1y11⎤⎦⎥ ⎡⎣⎢10−0.5nW0−10.5nH001⎤⎦⎥ ⎡⎣⎢cos(θ)sin(θ)0−sin(θ)cos(θ)0001⎤⎦⎥
⎡⎣⎢100.5w0−10.5h001⎤⎦⎥ = ⎡⎣⎢x0y01⎤⎦⎥ ⎡⎣⎢cos(θ)−sin(θ)−0.5nWcos(θ)+0.5nHsin(θ)+0.5wsin(θ)cos(θ)−0.5nWsin(θ)−0.5nHcos(θ)+0.5h001⎤⎦⎥
B=imrotate(A,angle,method, ‘crop’)
angle :旋转角度,单位为度,角度为正值时逆时针旋转
method :该可选参数为imrotate()指定插值方法
‘crop’:裁剪旋转后增大的图像
clc
I=imread('potted-plantsk.jpg');
figure,imshow(I);
title('srcImage');
I1=imrotate(I,30); %旋转30°
I2=imrotate(I,30,'crop'); %旋转30°,并剪切图像,使得到的图像和原图像大小一致
I3=imrotate(I,30,'bilinear','crop');%双线性插值法旋转30°,并剪切图像,使得到的图像和原图像大小一致
figure,imshow(I1);
title('I1');
figure,imshow(I2);
title('I2');
figure,imshow(I3);
title('I3');
function [ A ] = myimrotate(B,degree) %定义旋转函数,degree为要旋转的角度
[r,c,d]=size(B); %获取输入图像B的行r、列c和通道数d,为了旋转彩色图像所以有必要得到通道数d
nH=round(r*abs(cosd(degree))+c*abs(sind(degree))); %旋转图像后得到的新高度,“round()函数四舍五入“
nW=round(c*abs(cosd(degree))+r*abs(sind(degree))); %旋转图像后得到的新宽度
A=zeros(nH,nW,d); %定义生成目标图像的行列以及通道数
M1=[1 0 0;0 -1 0;-0.5*nW 0.5*nH 1 ]; %坐标系变换矩阵M1
M2=[cosd(degree) -sind(degree) 0;sind(degree) cosd(degree) 0;0 0 1]; %角度旋转变换矩阵M2,我用的是顺时针方向
M3=[1 0 0;0 -1 0;0.5*c 0.5*r 1]; %坐标系变换矩阵M3
for i=1:nW
for j=1:nH
temp=[i j 1]*M1*M2*M3; %得到旋转后的矩阵temp
y=temp(1,2); %y取矩阵temp的第一行第二列,y对应j,为高度
x=temp(1,1); %x取矩阵temp的第一行第一列,x对应i,为宽度
y=round(y); %y四舍五入取整
x=round(x); %x四舍五入取整
if(x>=1&&x<=c)&&(y>=1&&y<=r) %判断的得到的(x,y)点是否在原图像上
A(j,i,:)=B(y,x,:); %将原图像的像素点赋值给对应的旋转后图像上的点
end %(”有人疑惑为啥不是A(i,j,:)=B(x,y,:);因为i,x对应的是列,即宽,而j,y对应的是行,即高“),我这里以x为横坐标,y为竖向纵坐标
end
end
end
调用函数:
clc
I=imread('potted-plantsk.jpg');
figure,imshow(I);
title('srcImage');
I1=myimrotate(I,30); %调用myimrotate()函数旋转30°
I2=myimrotate(I,-90); %调用myimrotate()函数旋转-90°
figure,imshow(uint8(I1));
title('旋转30°:I1');
figure,imshow(uint8(I2));
title('旋转-90°:I2');
补充一下:
sin/cos/tan 三角函数,角度单位为弧度
asin/acos/atan 反三角函数,角度单位为弧度
sind/cosd/tand 三角函数,角度单位为度
asind/acosd/atand 反三角函数,角度单位为度