双线性插值及Matlab实现
一、简单实例
采用简单实例进行对双线性插值的介绍,假设现有
3
×
3
3\times3
3×3大小的灰度图
s
r
c
src
src,如下所示:
[
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
]
\left[\begin{array}{ccc} 0.1&0.2&0.3\\0.4&0.5&0.6\\0.7&0.8&0.9 \end{array}\right]
⎣⎡0.10.40.70.20.50.80.30.60.9⎦⎤目标图像
d
s
t
dst
dst期望大小为
5
×
5
5\times5
5×5,则若要构建原始图像与目标图像之间的对应关系,根据之前的论述(最近邻插值及Matlab实现,后续有关扩展原始图像的内容也参看此篇),其映射公式为:
{
s
r
c
X
=
(
d
s
t
X
+
0.5
)
×
(
s
r
c
W
i
d
t
h
/
d
s
t
W
i
d
t
h
)
−
0.5
s
r
c
Y
=
(
d
s
t
Y
+
0.5
)
×
(
s
r
c
H
e
i
g
h
t
/
d
s
t
H
e
i
g
h
t
)
−
0.5
\left\{\begin{array}{l} srcX=(dstX+0.5)\times(srcWidth/dstWidth) - 0.5 \\ srcY=(dstY+0.5)\times(srcHeight/dstHeight)-0.5 \end{array}\right.
{srcX=(dstX+0.5)×(srcWidth/dstWidth)−0.5srcY=(dstY+0.5)×(srcHeight/dstHeight)−0.5其中
s
r
c
X
srcX
srcX、
s
r
c
Y
srcY
srcY分别为目标图像
d
s
t
X
dstX
dstX、
d
s
t
Y
dstY
dstY处所对应的原图像坐标,那么,假设现需要求解目标图像的第一个像素,则有:
{
s
r
c
X
=
(
1
+
0.5
)
×
(
3
/
5
)
−
0.5
=
0.4
s
r
c
Y
=
(
1
+
0.5
)
×
(
3
/
5
)
−
0.5
=
0.4
\left\{\begin{array}{l} srcX=(1+0.5)\times(3/5)-0.5=0.4 \\ srcY=(1+0.5)\times(3/5)-0.5=0.4 \end{array}\right.
{srcX=(1+0.5)×(3/5)−0.5=0.4srcY=(1+0.5)×(3/5)−0.5=0.4双线性插值所使用的像素信息为所计算的对应原始图像位置处周围的四个像素点,由于此时计算所得的坐标为
(
0.4
,
0.4
)
(0.4,0.4)
(0.4,0.4),因此如下对原始图像进行对称扩展,如下图所示:
红色点处即为所求点,根据对称扩展,此时决定所求点数值的四个像素分别为1、2、4、5,对应数值见上述矩阵,双线性插值便是在
x
x
x、
y
y
y方向分别进行加权运算,此时待求点为
(
0.4
,
0.4
)
(0.4,0.4)
(0.4,0.4),则
x
x
x方向上加权求得结果为:
以底边灰点为例,其距离像素点0.2较远,则其权重较低;距离像素点0.1较近,则其权重较高。同理,在计算完毕
x
x
x方向后,进行
y
y
y方向的计算为:
0.4
×
0.44
+
0.6
×
0.14
=
0.26
0.4\times0.44+0.6\times0.14=0.26
0.4×0.44+0.6×0.14=0.26,则目标图像的第一个像素点为0.26。这一过程经过计算后并不复杂,此处只做简单示例与Matlab实现,故不对其进行推导。全部求解完毕得到目标图像如下:
[
0.26
0.32
0.38
0.42
0.42
0.44
0.50
0.56
0.60
0.60
0.62
0.68
0.74
0.78
0.78
0.74
0.80
0.86
0.90
0.90
0.74
0.80
0.86
0.90
0.90
]
\left[\begin{array}{ccccc} 0.26&0.32&0.38&0.42&0.42\\ 0.44&0.50&0.56&0.60&0.60\\ 0.62&0.68&0.74&0.78&0.78\\ 0.74&0.80&0.86&0.90&0.90\\ 0.74&0.80&0.86&0.90&0.90 \end{array}\right]
⎣⎢⎢⎢⎢⎡0.260.440.620.740.740.320.500.680.800.800.380.560.740.860.860.420.600.780.900.900.420.600.780.900.90⎦⎥⎥⎥⎥⎤ 通过上述简单例子可以看出,双线性插值对于目标图像的每一个像素点的估计采用了其对应的四个像素点的加权组合,产生了新的像素信息,故结果较之最近邻插值较好,并且也不会过于像素化,但也不可避免的出现模糊,如下图所示为利用双线性插值实现图像放大三倍的结果以及比较。
二、Matlab实现
Matlab实现如下:
function R = bilinear(src, scale)
%% 双线性插值
src = double(src) / 255;
% 判断是灰度图还是RGB图像
if ismatrix(src)
R = zeros(floor(size(src) * scale));
else
R = zeros([floor(size(src, 1, 2) * scale), 3]);
end
% 扩展原始图像
misrc = zeros([size(src, 1, 2) + 2 * floor(scale), size(R, 3)]);
for i = 1 : size(R, 3)
tmp = padarray(src(:, :, i), [floor(scale), floor(scale)], 'symmetric');
misrc(:, :, i) = tmp;
end
for i = 1 : size(R, 1)
for j = 1 : size(R, 2)
srcX = floor((i + 0.5) / scale - 0.5);
srcY = floor((j + 0.5) / scale - 0.5);
u = ((i + 0.5) / scale - 0.5) - srcX;
v = ((j + 0.5) / scale - 0.5) - srcY;
tmp = (1 - u) * (1 - v) * misrc(round(srcX + scale), round(srcY + scale), :) ...
+ (1 - u) * v * misrc(round(srcX + scale), round(srcY + scale) + 1, :) ...
+ u * (1 - v) * misrc(round(srcX + scale) + 1, round(srcY + scale), :) ...
+ u * v * misrc(round(srcX + scale) + 1, round(srcY + scale) + 1, :);
R(i, j, :) = tmp(:);
end
end
end