最近邻算法和双线性插值算法
实现灰度图的缩放
一. 算法分析:
1) 最近邻算法(Nearest neighbor interpolation)
所谓“最近邻算法”就是把这个非整数坐标作一个四舍五入,取最近的
整数点坐标处的点的灰度值。最近邻算法是一种简单的插值算法,它是通过
计算与点 0
(
P x y 临近的四个点,并将与点 0
(
P x y 最近的整数坐标点 ( ,
x y
)
)
,
,
0
0
)
的灰度值取为 0
(
P x y 点灰度近似值。
)
,
0
最近邻差值算法示意图
设变换的比例为 k , 0
k ,源图像中坐标点 ( ,
x y 的灰度值为 0( ,
f x y ,目
)
)
标图像中某一点图像的灰度值为 1( ,
f x y ,可以写出灰度值的变换关系式 :
)
,
(
f x y
1
0
0
)
(
f round x
0
0
(
/
),
(
k round y
0
/
k
))
2)双线性插值算法(Bilinear interpolation)
双线性插值法就是根据周围最接近的几个点(对于平面图像来说,共有
四点)的灰度值作线性插值计算(对于平面图像来说就是二维线性插值)来
估计这点的灰度值。
双线性插值法示意图
具体计算过程如下:
计算和:
x
0
x
,
y
0
;
y
根据 ( ,
f x y
),
(
f x
1,
y
)
插值求:
0(
,
f x y
)
0(
,
f x y
)
( ,
f x y
)
[
(
f x
1,
y
)
( ,
f x y
)]
;
根据 ( ,
f x y
1),
(
f x
1,
y
插值求: 0(
1)
f x y
,
1)
0(
,
f x y
1)
( ,
f x y
1)
[
(
f x
1,
y
1)
( ,
f x y
1)]
;
根据 0
(
,
f x y
),
(
f x y 插值求: 0
(
,
f x y
1)
,
0
)
0
(
,
f x y
0
0
)
(
,
f x y
0
)
[
(
,
f x y
0
1)
(
,
f x y
0
)]
( ,
f x y
)
[
(
f x
1,
y
)
( ,
f x y
)]
[
( ,
f x y
1)
( ,
f x y
)]
[
(
f x
1,
y
1)
( ,
f x y
)
( ,
f x y
1)
(
f x
1,
y
)]
二. 算法实现:
1) 最近邻算法(Nearest neighbor interpolation)
% Nearest neighbor interpolation
clear
f0=imread('lena.jpg');
[m,n]=size(f0);
k=input('please input scale factor k ( k>=0 ) = ');
% display source image
imshow(f0);
% the size of the zoom imag
km = round(k*m); kn = round(k*n);
% create a [km,kn] matrix
f1 = uint8(zeros(km,kn));
% nearest interplot
for x=1:km
for y=1:kn
if k~=0
else
end
f1=0;
end
f1(x,y)=f0(ceil(x/k),ceil(y/k));
end
f1=uint8(f1); % data type conversion
% show the interplotted image
if k~=0
imwrite(f1, 'lena1k.jpg', 'jpg');
end
figure;
imshow(f1);
Lena.jpg
最近邻算法放大k=1.5倍的图像
最近邻算法放大k=pi倍的图像
2)双线性插值算法(Bilinear interpolation)
% Bilinear interpolation
clear
f0=imread('lena.jpg');
[m,n]=size(f0);
k=input('please input scale factor k ( k>=0 ) = ');
% display source image
imshow(f0);
% the size of the zoom imag
km = round(k*m); kn = round(k*n);
% create a [km,kn] matrix
f1 = uint8(zeros(km,kn));
% bilinear interplot
for x = 5:km-5
for y = 5:kn-5
x0 = x/k ; y0 = y/k;
if (x0/double(uint16(x0)) == 1.0) & (y0/double(uint16(y0)) ==
1.0)
else
f1(x,y) = f0(int16(x0),int16(y0));
a = double(uint16(x0));
b = double(uint16(y0));
f0=double(f0);
f1(x,y)=uint8((b+1-y0)*[(x0-a)*f0(a+1,b)+(a+1-x0)*f0(a,b)]+(y0-b)
*[(x0-a)*f0(a+1,b+1)+(a+1-x0)*f0(a,b+1)]);
end
end
end
% show the interplotted image
if k~=0
imwrite(f1, 'lena2.jpg');
end
figure;
imshow(f1);
Lena.jpg
双线性插值算法放大k=1.5倍的图像
双线性插值算法放大k=pi倍的图像
三. 算法说明:
最近邻算法在 0
0
(
P x y 点各相邻像素间灰度变化较小时,这种方法是一种简
)
,
单快速的算法,但当 0
0
(
P x y 点相邻像素间灰度值差异很大时,这种灰度估值方
)
,
法会产生较大的误差,甚至影响图像质量。在大多数情况下,双线性插值算法的
准确度要高于最近邻域法,当然效果也要好得多,最明显的就是在放大时,图像
边缘的锯齿比最近邻域法小非常多。当然它同时还带来个问题:就是图像会显得
比较柔和。双线性插值算法一般可以得到令人满意的效果,但这种方法具有低通
滤波性质,使高频分量受到损失,使图像细节退化而变得轮廓模糊。在应用中,
双线性灰度插值的斜率不连续还可能会产生一些不期望的结果 。
为得到更高精度的灰度值,在更高程度上保证几何变换后的图像质量,实现
更精确的灰度插值效果,一般可采用三次内插等更高阶插值算法。