【数字图像处理】MATLAB实现图像旋转的三种算法

图像位置变换——图像旋转的MATLAB实现


代码实现

1)旋转方法0

缺点:容易产生空洞,效果不佳

% I = imread('img\peppers.png');
% [im] = dip(I,30);
% function [im]=rotate0(I,angle)
function [im]=dip(I,angle)   % 输入:图像矩阵I,旋转角度angle
[m,n,d] = size(I);           % 获得原图像尺寸,d为颜色通道

% 由于matlab中cos,sin角度为弧度,故进行转换
a = angle*pi/180;

% 图像四个顶点行坐标、列坐标(逆时针)
r1 = 1; r2 = m; r3 = m; r4 = 1;
c1 = 1; c2 = 1; c3 = n; c4 = n;
x = [r1,r2,r3,r4]; % 向量
y = [c1,c2,c3,c4];

% 根据旋转公式,得旋转后的坐标(x,y为原始图像坐标,x1,y1为旋转后坐标)
x1 = round(x*cos(a)-y*sin(a));
y1 = round(x*sin(a)+y*cos(a));

% 计算x1 y1的最大、最小值
x1_max = max(x1);
y1_max = max(y1);
x1_min = min(x1);
y1_min = min(y1);

% 得出画布扩展后的大小为m2,n2
m2 = x1_max - x1_min + 1;
n2 = y1_max - y1_min + 1;

% 计算x和y方向平移量det_x,det_y
if x1_min<=0
    delta_x = abs(x1_min)+1;
else
    delta_x = 0;
end
if y1_min<=0
    delta_y = abs(y1_min)+1;
else
    delta_y = 0;
end

im = zeros(m2,n2,d); % 初始化新图矩阵

% 对原图的每一行,每一列,根据旋转公式和平移量,得原新图对应坐标
for i=1:m
    for j=1:n
        x = round(i*cos(a)-j*sin(a)) + delta_x;
        y = round(i*sin(a)+j*cos(a)) + delta_y;
        im(x,y,:)=I(i,j,:);
    end
end

figure,imshow(uint8(I));title('原图');
figure,imshow(uint8(im));title('经旋转方法0旋转后的图像');

end

2)旋转方法1插值法:空洞填充

% I = imread('img\peppers.png');
% [im] = dip(I,30);
% function [im]=rotate1(I,angle)

function [im]=dip(I,angle) 
[m,n,d] = size(I); 
        
% 由于matlab中cos,sin角度为弧度,故进行转换
a = angle*pi/180;

% 原图像四个顶点行坐标、列坐标(逆时针)
r1 = 1; r2 = m; r3 = m; r4 = 1;
c1 = 1; c2 = 1; c3 = n; c4 = n;
x = [r1,r2,r3,r4];         % 向量
y = [c1,c2,c3,c4];

% 根据旋转公式,得旋转后的坐标(x,y为原始图像坐标,x1,y1为旋转后坐标)
x1 = round(x*cos(a)-y*sin(a));
y1 = round(x*sin(a)+y*cos(a));

% 计算x1 y1的最大、最小值
x1_max = max(x1);
y1_max = max(y1);
x1_min = min(x1);
y1_min = min(y1);

% 得出画布扩展后的大小为m2,n2
m2 = x1_max - x1_min + 1;
n2 = y1_max - y1_min + 1;

% 计算x和y方向平移量det_x,det_y
if x1_min<=0
    delta_x = abs(x1_min)+1;
else
    delta_x = 0;
end
if y1_min<=0
    delta_y = abs(y1_min)+1;
else
    delta_y = 0;
end

% 初始化新图矩阵
im = ones(m2,n2,d)*(-1); % 要进行黑洞填充为判断非背景点,画布初始化-1(非法值)

% 对原图的每一行,每一列,根据旋转公式和平移量,得原新图对应坐标
for i=1:m
    for j=1:n
        x = round(i*cos(a)-j*sin(a)) + delta_x;
        y = round(i*sin(a)+j*cos(a)) + delta_y;
        im(x,y,:)=I(i,j,:);
    end
end

% 进行插值--R通道
im_1 = im(:,:,1);

% 对新图的每一行
for i=1:m2
    % 找出新图第i行所有非背景点的行列坐标
    [x_1,y_1] = find(im_1(i,:)>0); % 找出所有大于0的点
    
    % 求第i行所有非背景点的列坐标的起止值
    y1_min = min(y_1);
    y1_max = max(y_1);
    
    %(y1_min,y_1max)范围内进行插值,对y1_min,y_1max之间的每一个像素点
    for j=y1_min+1:y1_max
        % 若为背景点,将前一个点赋给该点
        if(im(i,j)<0)
            im(i,j,:)=im(i,j-1,:);
        end
    end
end

figure,imshow(uint8(I));title('原图');
figure,imshow(uint8(im));title('经旋转方法1插值法旋转后的图像');

end

3)旋转方法2反变换

% I = imread('img\peppers.png');
% [im] = dip(I,30);
% function [im]=rotate2(I,angle)
function [im]=dip(I,angle) 
[m,n,d] = size(I); 

a = angle*pi/180;

r1 = 1; r2 = m; r3 = m; r4 = 1;
c1 = 1; c2 = 1; c3 = n; c4 = n;
x = [r1,r2,r3,r4]; 
y = [c1,c2,c3,c4];

x1 = round(x*cos(a)-y*sin(a));
y1 = round(x*sin(a)+y*cos(a));

x1_max = max(x1);
y1_max = max(y1);
x1_min = min(x1);
y1_min = min(y1);

% 得出画布扩展后的大小为m2,n2
m2 = x1_max - x1_min + 1;
n2 = y1_max - y1_min + 1;

% 计算x和y方向平移量det_x,det_y
if x1_min<=0
    delta_x = abs(x1_min)+1;
else
    delta_x = 0;
end
if y1_min<=0
    delta_y = abs(y1_min)+1;
else
    delta_y = 0;
end

% 初始化新图矩阵
im = ones(m2,n2,d)*(-1); 

% 对新图的每一行,每一列,根据旋转反变换公式和平移量,得原新图对应坐标
for i=1:m2
    for j=1:n2
        % 原图→新图,坐标+deltax,+delta_y
        % 新图→原图 反变换,因而坐标要先-delta_x,-delta_y
        x = round((i-delta_x)*cos(a)+(j-delta_y)*sin(a));
        y = round(-(i-delta_x)*sin(a)+(j-delta_y)*cos(a));
        if(x>0 && x<=m && y>0 && y<=n)
            im(i,j,:)=I(x,y,:);
        end
    end
end

figure,imshow(uint8(I));title('原图');
figure,imshow(uint8(im));title('经旋转方法2反变换旋转后的图像');

end

命令行窗口输入如下代码:

I = imread('img\peppers.png');
[im] = dip(I,30);

代码执行结果:
【数字图像处理】MATLAB实现图像旋转的三种算法_第1张图片

【数字图像处理】MATLAB实现图像旋转的三种算法_第2张图片
【数字图像处理】MATLAB实现图像旋转的三种算法_第3张图片

你可能感兴趣的:(学业专栏,#,数字图像处理,MATLAB)