注:旋转中心很重要 坐标系为像素,按照像素位置(第(m,n)做为坐标)
以坐标原点为中心旋转的原理:
点p0绕坐标原点逆时针方向旋转θ角度得到点p1.
以任意图形中心点为坐标原点旋转原理:
从上图可知以任意图形中心点为坐标原点旋转我们需要三步: (1)将坐标系Ⅰ变成坐标系Ⅱ (2)在坐标系Ⅱ中旋转θ角 (3)将坐标系Ⅱ变成坐标系Ⅰ(1)将坐标系Ⅰ变成坐标系Ⅱ
由Figure1得到Figure2可知,变换矩阵为: (2)在坐标系Ⅱ中旋转θ角 见上面以坐标原点为中心旋转的原理 (3)将坐标系Ⅱ变成坐标系Ⅰ最近邻插值matlab代码
function [ A ] = myimrotate(B,degree,method) %定义旋转函数,degree为要旋转的角度[r,c,d]=size(B); %获取输入图像B的行r、列c和通道数d,为了旋转彩色图像所以有必要得到通道数dnH=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 ]; %坐标系变换矩阵M1M2=[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_r=temp(1,2); %y取矩阵temp的第一行第二列,y对应j,为高度 x_r=temp(1,1); %x取矩阵temp的第一行第一列,x对应i,为宽度 y=round(y_r); %y四舍五入取整 x=round(x_r); %x四舍五入取整 if(x>=1&&x<=c)&&(y>=1&&y<=r) %判断的得到的(x,y)点是否在原图像上 %最近邻插值 if strcmp(method,'near') A(j,i,:)=B(y,x,:); %将原图像的像素点赋值给对应的旋转后图像上的点 end %(”有人疑惑为啥不是A(i,j,:)=B(x,y,:);因为i,x对应的是列,即宽,而j,y对应的是行,即高“),我这里以x为横坐标,y为竖向纵坐标 %线性插值 if strcmp(method,'linear') b = x_r-x; a = y+1-y_r; if(x>=1&&x+1<=c)&&(y>=1&&y+1<=r) P1 = b*B(y, x) + (1-b)*B(y+1, x); P2 = b*B(y, x+1) + (1-b)*B(y+1, x+1); P = a*P1 + (1-a)*P2; else P=B(y,x,:); end A(j,i,:)=P; end %三次插值 if strcmp(method,'trib') x = floor(x_r); y = floor(y_r); if(x>1&&x+2<=c)&&(y>1&&y+2<=r) b = x_r-x; a = y_r-y; A_A=[s(1+a) s(a) s(1-a) s(2-a)]; C=[s(1+b);s(b);s(1-b);s(2-b)]; B_B=[B(y-1,x-1) B(y-1,x) B(y-1,x+1) B(y-1,x+2) B(y,x-1) B(y,x) B(y,x+1) B(y,x+2) B(y+1,x-1) B(y+1,x) B(y+1,x+1) B(y+1,x+2) B(y+2,x-1) B(y+2,x) B(y+2,x+1) B(y+2,x+2)]; A(j,i,:) = (double(A_A)*double(B_B)*double(C));% else% if x<1% x = x+1;% end% if y<1% y = y+1;% end% A(j,i,:)=B(y,x,:); end end end end endend%计算S值function [ re ] = s(x) x = abs(x); if x<1 && x>=0 re = 1-2*x^2 + x^3; end if x>=1 &&x<2 re = 4 - 8*x +5*x^2-x^3; end if x>=2 re = 0; endend复制代码