matlib 多种方法实现图像旋转不使用imrotate函数

原理

方法很棒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'); 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值