工作:

抉择典型图像(football.jpg)为钻研对象
1.显示原图像
2.将图像旋转45°并进行显示(不调用自带函数,利用矩阵变换)

原理:

(原文链接:https://blog.csdn.net/Bryan_Q...)

以坐标原点为核心旋转的原理

点p0绕坐标原点逆时针方向旋转角度失去点p1

$$ \begin{bmatrix} cos() & -sin & 0\\ sin & cos() & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix}$$

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

(这合乎MATLAB的零碎空间坐标设置,绕核心旋转能够统一化几何变换问题,原点旋转解决具备个体化)

从上图可知,以任意图形核心为坐标原点旋转须要三步:

(1)将坐标系I变成坐标系II
注:坐标系I合乎MATLAB的零碎空间坐标设置,坐标系II中,图形核心是坐标原点。

$$ \begin{bmatrix} 1 & 0 & -0.5w\\ 0 & -1 & 0.5h \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} XI\\ YI\\ 1 \end{bmatrix} = \begin{bmatrix} XII\\ YII\\ 1 \end{bmatrix}$$

(2)将坐标系II旋转角

$$ \begin{bmatrix} cos() & -sin & 0\\ sin & cos() & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix}$$

(3)将坐标系II变成坐标系I
注:MATLAB中只能以坐标系I的模式出现图像,只能显示其x>0,y>0的局部。

$$ \begin{bmatrix} 1 & 0 & 0.5nW\\ 0 & -1 & 0.5nH \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} XII\\ YII\\ 1 \end{bmatrix} = \begin{bmatrix} XI\\ YI\\ 1 \end{bmatrix}$$

从而将三步联合起来,能够失去以任意图像核心为坐标原地旋转,最初出现残缺图像的变换矩阵:

前向映射

$$ \begin{bmatrix} 1 & 0 & 0.5nW\\ 0 & -1 & 0.5nH \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} cos() & -sin & 0\\ sin & cos() & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & -0.5w\\ 0 & -1 & 0.5h \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix}$$

它的逆变换为:
后向映射

$$ \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & -0.5nW\\ 0 & -1 & 0.5nH \\ 0& 0 & 1 \end{bmatrix} \begin{bmatrix} cos() & sin() & 0\\ -sin() & cos() & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0.5w \\ 0 & -1 & 0.5h\\ 0& 0 & 1 \end{bmatrix} \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix} $$

向前映射和向后映射的区别

参考博客:[(4条音讯) 图像变换——向前映射和向后映射_薇洛的打火机-CSDN博客](https://blog.csdn.net/glorydr...

总结:

MATLAB编程实现

(1)MATLAB自带函数实现图像任意角度旋转
旋转函数介绍:

B = imrotate(A,angle,method,bbox)
angle:旋转角度,单位为度,逆正顺负。
method:指定插值办法,邻点插值、双线性插值、双三次插值,(默认邻点插值)
bbox:定义输入图像大小的边界框

I=imread('football.jpg');I1=imrotate(I,-45);                  %旋转45°I2=imrotate(I,-45,'crop');           %旋转45°,并剪切图像,使失去的图像和原图像大小统一I3=imrotate(I,-45,'bilinear','crop');%双线性插值法旋转45°,并剪切图像,使失去的图像和原图像大小统一figure,subplot(2,2,1),imshow(I);title('srcImage');subplot(2,2,2),imshow(I1);title('I1');subplot(2,2,3),imshow(I2);title('I2');subplot(2,2,4),imshow(I3);title('I3');
(2)自编myimrotate()函数实现图像任意角度旋转
function [ A ] = new_myimrotate(B,degree)                             %定义旋转函数,degree要旋转的角度[h,w,d]=size(B);                                                      %获取输出图像B的行(高)h、列(宽)w和通道数d,为了旋转彩色图像所以有必要失去通道数dnH=round(h*abs(cosd(degree))+w*abs(sind(degree)));                    %旋转图像后失去的新高度,“round()函数四舍五入“,“abs()函绝对值和复数的模”,“cosd()以度为单位的参数的余弦”nW=round(w*abs(cosd(degree))+h*abs(sind(degree)));                    %旋转图像后失去的新宽度A=zeros(nH,nW,d);                                                     %定义生成指标图像的行列以及通道数M1=[1 0 -0.5*nW;0 -1 0.5*nH;0 0 1 ];                                   %坐标系变换矩阵M1M2=[cosd(degree) sind(degree) 0;-sind(degree) cosd(degree) 0;0 0 1];  %角度旋转变换矩阵M2,我用的是顺时针方向M3=[1 0 0.5*w;0 -1 0.5*h;0 0 1];                                      %坐标系变换矩阵M3    for i=1:nW        for j=1:nH            temp=M1*M2*M3*[i;j;1];                                    %失去旋转前的矩阵temp            y=temp(2,1);                                              %y取矩阵temp的第一行第二列,y对应j,为高度            x=temp(1,1);                                              %x取矩阵temp的第一行第一列,x对应i,为宽度            y=round(y);                                               %y四舍五入取整,邻近插值法            x=round(x);                                               %x四舍五入取整,邻近插值法           if(x>=1&&x<=w)&&(y>=1&&y<=h)                               %判断的失去的(x,y)点是否在原图像上               A(j,i,:)=B(y,x,:);                                     %将原图像的像素点赋值给对应的旋转后图像上的点           end                                                        %(”会纳闷为啥不是A(i,j,:)=B(x,y,:);因为i,x对应的是列,即宽,而j,y对应的是行,即高“)        end                                                           %要弄清楚元素坐标与元素在矩阵中地位的转换关系    endend
主程序
I=imread('football.jpg');I1=myimrotate(I,45);                %调用myimrotate()函数旋转45° I2=myimrotate(I,-45);               %调用myimrotate()函数旋转-45°figure,subplot(1,3,1),imshow(I);title('srcImage');subplot(1,3,2),imshow(uint8(I1));   %matlab中读入图像的数据类型是uint8,而在图像矩阵运算的时候,应用的数据类型却是double类型title('旋转45°:I1');subplot(1,3,3),imshow(uint8(I2));title('旋转-45°:I2');

程序运行后果: