原理
方法很棒https://blog.csdn.net/qq_41140138/article/details/104737705
方法一
function g = rotate_image1(f, theta)
[M,N]=size(f);
theta=theta*pi/180;
% img_rotate = ones(M,N);
T= [cos(theta),sin(theta);-sin(theta),cos(theta)];%旋转变换
% 计算显示完整图像需要的画布大小
hh = floor(M*sin(theta)+N*cos(theta))+1; %floor取整
ww = floor(M*cos(theta)+N*sin(theta))+1;
img_rotate = uint8(ones(hh, ww)*128);
for i=1:hh
for j=1:ww
p = round(T'*([i;j]-[hh/2;ww/2])+[M/2;N/2]);
% p = floor([i,j,1]*T^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1)
if (p(1)<=M)&&(p(1)>0)&&(p(2)<=N)&&(p(2)>0) %限制范围
img_rotate(i,j) = f(p(1),p(2)); %坐标变换关系
else
img_rotate(i,j) = 0; %没有的点赋值为0
end
end
end
imshow(img_rotate);
方法二:
close all;clear all;clc
f = imread('Lena.bmp');
[m,n]=size(f);
%theta=theta*pi/180;
theta=30*pi/180;
%反向映射
r_new = round(abs(m*cos(theta)) + abs(n*sin(theta)));
c_new = round(abs(m*sin(theta)) + abs(n*cos(theta)));
T2 = [1,0,0;0,1,0;-r_new/2,-c_new/2,1]; %x、y轴平移到原点
T3 = [1,0,0;0,1,0;m/2,n/2,1]; %x、y轴反平移
T1 = [cos(theta),sin(theta),0;-sin(theta),cos(theta),0;0,0,1];%旋转变换
T = T2*T1*T3;
dst = zeros(r_new,c_new);
for i = 1:r_new
for j = 1:c_new
%从新图像映射到原图像中去如果不在原图像中,新图像为0,如果在的,将该点的最邻近取值赋值过来
P = T'*[i;j;1] ;%P(1)为x的值 P(2)为y的值
if(round(P(1))>0 && round(P(1))<m && round(P(2))>0 && round(P(2))<n)
dst(i,j,1) = f(round(P(2)),round(P(1)),1);%取f的最邻近值
else
dst(i,j) = 0;
end
end
end
figure; imshow(uint8(dst)); title('最邻近插值');
方法三
img = imread('lena_color_512.tif');
[height, width, color] = size(img);
theta = 1/3*pi;
C = round([height/2, width/2]); % 原图像中心
R = [cos(theta) sin(theta); -sin(theta) cos(theta)];
% 计算新图像大小
nw = round(([0, 0]-C)*R + C);
ne = round(([0, width]-C)*R + C);
sw = round(([height, 0]-C)*R + C);
se = round(([height, width]-C)*R + C);
h = max([nw(1), ne(1), sw(1), se(1)]) - min([nw(1), ne(1), sw(1), se(1)]);
w = max([nw(2), ne(2), sw(2), se(2)]) - min([nw(2), ne(2), sw(2), se(2)]);
target = zeros(h, w, 3, 'uint8') + 255;
c = round([h/2, w/2]); % 新图像中心
% 旋转
for x = 1 : height
for y = 1 : width
P = [x, y];
Q = round((P-C)*R + c);
if (Q(1)>0 && Q(1)<=h) && (Q(2)>0 && Q(2)<=w) % 越界判断
target(Q(1), Q(2), :) = img(x, y, :);
end
end
end
imshow(target)
改进代码
%%
img = imread('Lena.bmp');
[height, width, color] = size(img);
theta = 1/4*pi;
C = round([height/2, width/2]); % 原图像中心
R = [cos(theta) sin(theta); -sin(theta) cos(theta)];
R = inv(R); % 逆矩阵
% 原图像四个角旋转后的坐标
nw = round(([0, 0]-C)*R + C);
ne = round(([0, width]-C)*R + C);
sw = round(([height, 0]-C)*R + C);
se = round(([height, width]-C)*R + C);
% 新图像
h = max([nw(1), ne(1), sw(1), se(1)]) - min([nw(1), ne(1), sw(1), se(1)]);
w = max([nw(2), ne(2), sw(2), se(2)]) - min([nw(2), ne(2), sw(2), se(2)]);
target = zeros(h, w, 3, 'uint8') + 255;
c = round([h/2, w/2]); % 新图像中心
for x = 1 : h
for y = 1 : w
Q = [x, y];
% 根据目标像素点计算原图像像素点
P = round((Q-c)*R + C);
if (P(1)>0 && P(1)<=height) && (P(2)>0 && P(2)<=width) % 越界判断
target(x, y, :) = img(round(P(1)), round(P(2)), :);
else
target(x, y, :) =0;
end
end
end
subplot(1,2,1), imshow(img),title('input image');
subplot(1,2,2),imshow(target),title('rotate image');