工作:
抉择典型图像(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');
程序运行后果: