Matlab图像几何变换之图像旋转

本文详细介绍了在Matlab中如何实现图像的旋转操作,包括使用内置函数imrotate进行图像旋转的方法,以及通过自定义函数myimrotate实现图像任意角度旋转的过程。文章还探讨了旋转图像的原理,包括以坐标原点为中心旋转和以任意图形中心点为坐标原点旋转的步骤,并提供了具体的编程实现代码。

转自:https://blog.youkuaiyun.com/Bryan_QAQ/article/details/78805201

结尾补充了一点内容。 

 Matlab图像旋转

以坐标原点为中心旋转的原理:

点p0p0绕坐标原点逆时针方向旋转θθ角度得到点p1p1. 
这里写图片描述
从①②可以得到旋转变换的矩阵公式: 

以任意图形中心点为坐标原点旋转原理:


从上图可知以任意图形中心点为坐标原点旋转我们需要三步: 
(1)将坐标系Ⅰ变成坐标系Ⅱ 
(2)在坐标系Ⅱ中旋转θθ角 
(3)将坐标系Ⅱ变成坐标系Ⅰ

(1)将坐标系Ⅰ变成坐标系Ⅱ
由Figure1得到Figure2可知,变换矩阵为: 

2)在坐标系Ⅱ中旋转θθ角

见上面以坐标原点为中心旋转的原理

(3)将坐标系Ⅱ变成坐标系Ⅰ

由Figure3得到Figure4可知,变换矩阵为(其实就是(1)中变换矩阵的逆变换): 

Matlab编程实现
(1)Matlab自带函数实现图像任意角度旋转
旋转函数介绍:
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');

(2)自编myimrotate()函数实现图像任意角度旋转

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');

补充:博主是按照顺时针旋转方向编写矩阵,以下为逆时针旋转程序的编写

调用函数:

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*c 0.5*r 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*nW 0.5*nH 1];                                      %坐标系变换矩阵M3
    for i=1:c
        for j=1:r
            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<=nW)&&(y>=1&&y<=nH)                               %判断的得到的(x,y)点是否在原图像上
               A(y,x,:)=B(j,i,:);                                     %将原图像的像素点赋值给对应的旋转后图像上的点
           end                                                        %(”有人疑惑为啥不是A(i,j,:)=B(x,y,:);因为i,x对应的是列,即宽,而j,y对应的是行,即高“),我这里以x为横坐标,y为竖向纵坐标
        end
    end
end

主函数:

clc                                 
I=imread('lena.bmp');
figure,imshow(I);
title('srcImage');
I1=myimrotate(I,30);     %调用myimrotate()函数旋转30° 
    %调用myimrotate()函数旋转-90°
%对旋转后的图像插值
for i=2:698
    for j=2:698
        if I1(i,j)==0&&I1(i,j-1)>0 &&I1(i,j+1)>0 &&I1(i-1,j)>0&&I1(i+1,j)>0
            I1(i,j)=I1(i-1,j);
        end
    end
end  
figure,imshow(uint8(I1));
title('旋转30°:I1');

可以看出,改变旋转方向需对旋转图像进行插值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值