【MATLAB图像融合】[5]图像插值算法:二次/三次插值
双线性插值
插值的使用是很重要的,在MATLAB中有默认的imresize函数可以实现各种常用的插值算法。在图像融合的一些处理中需要用到上/下采样,此时合理运用插值算法可以达成中间步骤。
作为经典的插值算法,双线性易于实现,原理简单.
思路
通过映射的方法,找出原像素点(x,y)到映射像素点(m,n)的灰度值的映射关系。
①、设处理前后图像的宽度和高度分别为w、h,w’、h’。
②、通过缩放比例,可以求得新图像B在(i,j)处对应原图像的点为(x,y)。举例:原图像256 256,想要生成512 512的大小,那么新图像的点(i,j)=原图像的点(i/2,j/2)。
方法
①、如果每个点都恰好有对应的点就最好不过了,但是
②、这两个值(x,y)可能为浮点数,而像素中的位置是整数,所以这个点在原图像中对应的可能是虚点,有理论值,但无确切对应点。
③、所以,根据该虚点周围的四个点来进行双线性插值得到新图像的灰度值。取(x,y)邻近的四个像素(x0,y0) 、(x0,y1) 、(x1,y0) 、(x1,y1),它们对应的灰度值为f(x0,y0) 、f(x0,y1)、 f(x1,y0)、 f(x1,y1)。
④、从x的方向先开始插值:



⑤、注:u,v分别是m,n的小数部分。公式中的m和n不能小于1,所以当m和n小于1时需要将其重新赋值为1。先对X插值和先对Y插值得到的结果是没有区别的。
MATLAB实现
function B=fchazhi(A,new_size)
A=double(A);
[old_h,old_w]=size(A); %获取原图大小。
new_w=new_size(1,1);
new_h=new_size(1,2);
B=zeros(new_w,new_h); %初始化一个新图大小的矩阵。
for i=1:new_w
for j=1:new_h
x=i*old_w/new_w; %计算新图像在原图像的映射位置(x,y);
y=j*old_h/new_h;
u=x-floor(x);
v=y-floor(y);
if x<1
x=1;
end
if y<1
y=1;
end
B(i,j)=A(floor(x),floor(y))*(1-u)*(1-v)+...
A(floor(x),ceil(y))*(1-u)*v+...
A(ceil(x),floor(y))*u*(1-v)+...
A(ceil(x),ceil(y))*u*v;
end
end
函数调用
clear;clc;
A=imread('lena.tif');
B=fchazhi(A,[512,512]); %参数2为你需要的尺寸。
subplot 121;imshow(A);title('原图像')
subplot 122;imshow(uint8(B));title('缩放后图像')
运行结果:
彩色图像处理再加入一个维度就可以了,不再单独给出代码。
双三次插值
双三次得到的图像相比二次插值来说更清晰,效果更好一些,高频细节保留的多一些。唯一不足就是计算量较大。算法思想有沿用二次插值的映射思想。
思路
双三次插值,函数f在点 (x,y) 的值可以通过矩形网格中最近的十六个采样点的加权平均得到,在这里需要使用两个多项式插值三次函数,每个方向使用一个。
图像A大小为x y,缩放K倍后的图像B的大小为m n,即K=m/x。A的每一个像素点是已知的,B是未知的,要求出目标图像B中每一像素点(X,Y)的值,必须先找出像素(X,Y)在源图像A中对应的像素(x,y),再根据源图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加。
同二次插值一样,首先计算出B中的像素点在图像A中对应的像素点位置,同样这个步骤会产生小数u和v,然后依据此得出A图像中最接近的16个点。
构造bicubic函数:

MATLAB实现
function out=fsanci(A,new_size)
A=double(A);
[old_h,old_w]=size(A); %获取原图大小。
new_w=new_size(1,1);
new_h=new_size(1,2);
B=zeros(new_w,new_h); %初始化一个新图大小的矩阵存放中间量。
sw=new_w/old_w;
sh=new_h/old_h;
row_1=A(1,:);row_n=A(old_h,:); %因为要取16个点,所以要增加边界。
tem_A=[row_1;row_1;A;row_n;row_n];
col_1=tem_A(:,1);col_n=tem_A(:,old_w);
IN=[col_1,col_1,tem_A,col_n,col_n];
out=zeros(new_w,new_h); %初始化一个新图大小的矩阵存放最终结果。
for w=1:new_w
i=floor(w/sw)+2;
u=(rem(w,sw))/sw;
for h=1:new_h
j=floor(h/sh)+2;
v=(rem(h,sh))/sh; %同二次插值。
A=[quan(v+1),quan(v),quan(1-v),quan(2-v)]; %计算权值。
C=[quan(u+1);quan(u);quan(1-u);quan(2-u)];
B=IN(i-1:i+2,j-1:j+2); %取出和新图一样大小的范围。
out(w,h)=A*B*C; %每次存入16个点到最终结果。
end
end
end
function w=quan(wx) %计算权值。
wx=abs(wx); %绝对值。
if wx<1
w=1-2.5*wx^2+1.5*wx^3; %公式中的a=0.5。
elseif wx>=1&&wx<2
w=2-4*wx+2.5*wx^2-0.5*wx^3;
else
w=0;
end
end
函数调用
clear;clc;
A=imread('lena.tif');
B=fsanci(A,[512,512]); %参数2为你需要的尺寸。
subplot 121;imshow(A);title('原图像')
subplot 122;imshow(uint8(B));title('缩放后图像')
运行结果:

以上就是本次分享的两个插值算法。 后面一节将介绍利用下采样生成的高斯金字塔。欢迎大家一起探讨学习。
