[MATLAB] 图像的插值算法2:最近邻插值

MATLAB图像插值算法文章集:

  1. 插值函数及其原理 https://blog.csdn.net/Effend/article/details/82870144
  2. 最近邻插值 https://blog.csdn.net/Effend/article/details/82897898
  3. 双线性插值 https://blog.csdn.net/Effend/article/details/82996871
  4. 双三次插值 (待完成)https://blog.csdn.net/Effend/article/details/82996899

1. 概要

顾名思义,最近邻插值就是在目标像素点上插入离对应原像素点最近的点的像素值,而不考虑图像可能的颜色变化。因此,该算法方法较为单一,原理也较为简单,计算量也是最少的。
但是,这个方法也有着很明显的缺点,那就是锯齿化高,在颜色变化程度越高以及放大率越大的图像上进行插值处理时,锯齿化现象越严重,这是因为该算法没有考虑颜色变化。
该算法作为要讨论的三种插值算法中的基础,研究其中的计算过程也是很有必要的。

2. 最近邻插值算法

接下来,我们依据原理设计相应算法,使用MATLAB语言编写。

算法步骤:
(1)用户输入图像文件、放大率;
(2)根据放大率进行图像变换;
(3)输出变化后的图像。

算法代码:

% 最近邻插值
% 输入图像文件及放大率
% 输出根据放大率变化后的新图像
function nearest_neighbor = nearest_neighbor(filename,R)

% 初始化,读入图像,图像数据为m*n*color
img = imread(filename);

% 变化后图像
[row,col,color] = size(img);    % 获得图像的行列数及色板数
row = round(row*R);     % 新图像行
col = round(col*R);     % 新图像列

% 新图像初始化
% 使用class获得原图像的数据类型,使得新图像数据类型与原图像保持一致
img_new = zeros(row,col,color,class(img));

% 对新图像的行、列、色板赋值
for i = 1:row
    for j = 1:col
        for n = 1:color
            x = round(i/R);
            y = round(j/R);
            % 为了避免x和y等于0而报错,采取+1处理即可
            if x == 0
                x = x+1;
            end
            if y == 0
                y = y+1;
            end
            img_new(i,j,n) = img(x,y,n);
        end
    end
end

% 显示原图像
figure;
imshow(img);
title("Original Image");

% 显示新图像
figure;
imshow(img_new);
title("New Image");

3. 算法分析

在最近邻插值算法中,最重要的是要找出对应的原图像上的像素点,然后将像素点的值赋给新图像。详细分析如下:
(1)通过imread函数获得图像的数据,在变量img中包括了图像的宽度、高度以及颜色;
(2)用size获得图像的行列数及色板数,并计算得到新图像的行列数;
(3)用计算得到的行列数及色板数创建一个新图像,为了保证图像颜色显示与原图像一致,通过class获得原图像类型,并通过zeros函数获得与原图像类型一致的,数值皆为0的新图像矩阵;
(4)对新图像的行、列、色板遍历赋值,对新图像的像素赋值中,需要找到与被赋值像素点对应的原图像上的像素点。由于使用的最近邻插值即是直接找到最靠近的像素直接赋值,所以使用round函数对行、列四舍五入,便可找到最近的像素点,再将原图像像素点的颜色赋值给新图像上对应的像素。(此处感谢TRY2333的评论反馈,round后的x和y需要进行时候为0的判断以避免报错的情况。)
(5)显示原图像和新图像。

4. 测试环境:

用2幅.jpg文件格式的图像作为示例运行,分别观察放大率<1及>1的情况,文件分别为img.jpg和img1.jpg,具体图像如下:
img.jpg 图像大小720*720
[MATLAB] 图像的插值算法2:最近邻插值_第1张图片
img1.jpg 图像大小350*350
[MATLAB] 图像的插值算法2:最近邻插值_第2张图片

5. 测试效果:

(1)用img.jpg运行函数,设定放大率R=0.8,即缩小原图像。
结果为:
[MATLAB] 图像的插值算法2:最近邻插值_第3张图片
可以发现,图像缩小符合预期,色彩也得到保留。
放大图像中的某个部分查看像素点:
[MATLAB] 图像的插值算法2:最近邻插值_第4张图片
从放大后的图像来观察,在用红框圈出的范围内,可以明显发现原图像通过最近邻插值算法缩小后,图像出现了少许的锯齿,并且图像的缩小使得原图像的一些像素丢失,图像精度下降。

(2)用img1.jpg运行函数,设定放大率R=1.5,即放大原图像。
结果为:
[MATLAB] 图像的插值算法2:最近邻插值_第5张图片
从上图可以看到,图像放大1.5倍,可以明显观察到锯齿化加深。
放大图像中的某个部分查看像素点:
[MATLAB] 图像的插值算法2:最近邻插值_第6张图片
在上图中,可以明显观察到新图像中由于放大,需要给新增加的像素点补值,这导致了新图像中出现比原图像更多的像素信息,而由于最近邻插值不会考虑图像颜色的变化,所以图像的锯齿化会加深,而且随着放大率越大,锯齿更为严重。
但在放大率在一定范围内时,图像的放大效果还是很显著的,而且计算速度快。

6. 总结:

最近邻插值的算法可以说是最为暴力的算法,追求简洁高效快速,直接将像素值赋值而抛弃颜色变化的过程。可以看到,无论是缩小图像还是放大图像,都会对图像的细致程度、精度造成影响,图像会呈现更深的锯齿。
但由于其计算速度快,在对于放大或者缩小率要求不高的情况下,使用该算法可以最快完成,而且该算法也无需进行优化操作,使用简单。

–注:本文为原创,未经允许,禁止转载!–

你可能感兴趣的:(MATLAB)