双线性差值算法对图像旋转的优化

引言:上一篇博客实现了图像旋转并解决了图像显示不完整和像素点缺失的问题。
这次通过双线性差值算法的应用对图像旋转的效果进行优化。

一、双线性差值算法

见我以前的博客
链接:https://blog.csdn.net/qq_43650722/article/details/104072475

二、本设计中的改善

见我上一篇博客中的方案二
链接:https://blog.csdn.net/qq_43650722/article/details/104077954
代码如下:

im=imread('fruit.png');

%旋转30°
%求出旋转矩阵
a=30/180*pi;
R=[cos(a),-sin(a);sin(a),cos(a)];%旋转矩阵
R=R';%求出旋转矩阵的逆矩阵

%求出图片大小
sz=size(im);
h=sz(1);
w=sz(2);
ch=sz(3);
c1=[h;w]/2;%原图中心


%计算显示完整图像需要的画布大小
hh=floor(width*sin(a)+height*cos(a))+1;
ww=floor(width*cos(a)+height*sin(a))+1;
c2=[hh,ww]/2;%求新画布中点

%初始化目标画布
im2=uint8(ones(hh,ww,3)*128);
for k = 1:ch
    for i = 1:hh
        for j = 1:ww
            p=[i;j];%遍历新图像像素点
            pp=round(R*(p-c2)+c1);%计算在原来图像中的位置
            %这里仍然使用round函数,但结果会比方案一好得多
            %逆向进行像素查找
            if(pp(1)>=1&&pp(1)<=h&&pp(2)>=1&&pp(2)<=w)
                im2(i,j,k)=im(pp(1),pp(2),k);
            end
        end
    end
end

%显示图像
figure;
imshow(im);
figure;
imshow(im2);


这个方案中不足的点在于由于采用了反向查找法让显示的图像没有像素缺失使得我们察觉不出图像的不足之处。实际上在旋转后的图片中部分像素是取了原图像中同一个像素,这就是由于粗略使用round函数取整而导致的。

要解决这个问题就可以引入双线性差值算法。

im=imread('fruit.png');

%旋转30°
%求出旋转矩阵
a=30/180*pi;
R=[cos(a),-sin(a);sin(a),cos(a)];%旋转矩阵
R=R';%求出旋转矩阵的逆矩阵

%求出图片大小
sz=size(im);
h=sz(1);
w=sz(2);
ch=sz(3);
c1=[h;w]/2;%原图中心


%计算显示完整图像需要的画布大小
hh=floor(width*sin(a)+height*cos(a))+1;
ww=floor(width*cos(a)+height*sin(a))+1;
c2=[hh,ww]/2;

%初始化目标画布
im2=uint8(ones(hh,ww,3)*128);
for k = 1:ch
    for i = 1:hh
        for j = 1:ww
            p=[i;j];%后图像
            pp=(R*(p-c2)+c1);%计算在原来图像中的位置
            mn=floor(pp);
            ab=pp-mn;%这里就代表了该坐标点离左上点的位置
            a=ab(1);
            b=ab(2);
            m=mn(1);
            n=mn(2);
            %线性差值方法
            if(pp(1)>=1&&pp(1)<=h&&pp(2)>=1&&pp(2)<=w)
                im2(i,j,k)=(1-a)*(1-b)*im(m,n,k)+a*(1-b)*im(m+1,n,k)...
                    +(1-a)*b*im(m,n+1,k)+a*b*im(m+1,n+1,k);
            end
        end
    end
end

%显示图像
figure;
imshow(im);
figure;
imshow(im2);

代码解读:

pp=(R*(p-c2)+c1);%计算在原来图像中的位置
            mn=floor(pp);
            ab=pp-mn;%这里就代表了该坐标点离左上点的位置
            a=ab(1);
            b=ab(2);
            m=mn(1);
            n=mn(2);
            %线性差值方法
            if(pp(1)>=1&&pp(1)<=h&&pp(2)>=1&&pp(2)<=w)
                im2(i,j,k)=(1-a)*(1-b)*im(m,n,k)+a*(1-b)*im(m+1,n,k)...
                    +(1-a)*b*im(m,n+1,k)+a*b*im(m+1,n+1,k);
            end

看下图就能明白了
在这里插入图片描述
再按照之前博文里给的差值算法公式,就能得出:
P = A ( 1 − a ) ( 1 − b ) + B ∗ a ( 1 − b ) + C ( 1 − a ) b + D ∗ a ∗ b ; P=A(1-a)(1-b)+B*a(1-b)+C(1-a)b+D*a*b; P=A(1a)(1b)+Ba(1b)+C(1a)b+Dab;
MATLAB代码表示就是:

im2(i,j,k)=(1-a)*(1-b)*im(m,n,k)+a*(1-b)*im(m+1,n,k)...
                    +(1-a)*b*im(m,n+1,k)+a*b*im(m+1,n+1,k);

运行结果:
在这里插入图片描述
在这里插入图片描述
下图是没用双线性差值算法处理后的图像
在这里插入图片描述
可以非常明显地看出,用双线性差值算法处理后的图像更加平滑,噪点更少。

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页