[数字图像处理](六)插值运算

参考文章

(1条消息) 几种常用的插值和分段插值方法Matlab算法实现_树莓、的博客-CSDN博客_分段线性插值matlab

MATLAB 图像的插值算法2:最近邻插值_Effend的博客-CSDN博客_matlab最近邻插值

[数字图像处理](六)插值运算

前言

​ 本文章介绍的几种算法都是用变化后的坐标(((n*R || m*R)R 为变化率(如1.5))) 来计算映射到原始图像的位置,有很多博客和wiki都介绍了这些算法的数学原理,这里就不做介绍了就是数学不好。

​ 本文章就matlab代码,来解释算法的执行逻辑,以便于更好的理解算法的实际思想。

1____最近邻插值法

基本思想

下文会用到的标记

  • transim()变换后的图像

  • grayim()变换之前的图像

  • n,m——grayim的大小,c,l——transim的大小

  • R变换率——(n*R = c,m*R = l)


​ 最近邻插值法,本质上就是变换后图像的坐标等比映射到原图像取值

$ transim(i,j) = grayim( round(i/R),round(j/R) ) $

实现代码

%%	nearest_neighbor
clc;
clear all;
close all;

rgbim = imread('p2.png');
grayim = rgb2gray(rgbim);
[n,m] = size(grayim);
figure;
imshow(grayim);

%%  设置变换率
R = 2.8;
n = round(n*R);%    四舍五入
m = round(m*R);

%%   变换
transim = zeros(n,m,class(grayim));%	class的作用的把transim的数据类型变成和grayim一直的数据类型

for i = 1:1:n
    for j = 1:1:m
        x = round(i/R)	;%	映射到原图像
        y = round(j/R);
        if x == 0		%	考虑到边界问题
            x = x + 1;
        end
        if y == 0
            y = y + 1;
        end
        %------------
        transim(i,j) = grayim(x,y);
    end
end
%%  输出图像
figure;
imshow(transim);
imwrite(transim,'transim.png');

2____双线性插值法

前言

​ 我在学习了最近邻插值法之后,想学的是线性插值法,去了解了之后发现,这是一个处理一维图像的算法。在粗略的了解与思考之后发现其实也是可以做二维图像的,只不过说处理时只能参考横向偏移量,或者纵向偏移量,有一定的局限性。

​ 所以在这里我就直接跳过线性插值法,直接来说说双线性插值法

基本思想

​ 如果知道线性插值法是如何处理的,那么双线性插值法也就明白了。

​ 同时双线性插值法也是最近邻插值法的优化,在最近邻插值法中,我们直接用等比缩放的映射值来充当变换图像的灰度值(详见上),这样就浪费了很多领域的信息,如果把领域的信息利用起来,是不是就可以在一定程度上提升画质呢(通过之前学习的各种优化来推到)?

​ 双线性插值法就是这样的思路,利用到了映射之后的领域信息,以及映射的比率来确定横纵上的偏移量,我这有系统的说,肯定很多小伙伴是云里雾里,但是看了下面的描述,再来看这段文字,必定茅塞顿开。


双线性插值法

  1. 理解偏移量 (u,v)

    • 横向:(u = frac{i}{R} - floor(frac{i}{R}))

    • 纵向:(v = frac{i}{R}-floor(frac{j}{R}))

    如何理解这个偏移量呢?

    ​ 我们假设 $ i = 7,j = 131, R = 0.5 $

    ​ 那么(u = 3.5 - 3 = 0.5) 这个0.5就对应的是上图的u,从图像的意义来解释,这个值反应的是是这个映射坐标本质上是更靠近x还是x+1 (因为很有可能不同的i,在同一R的情况下,能得到相同的映射坐标x)那么在这个时候,有了u以及v这个偏移量,就能更好的反应出图像的映射关系,进而得到更真实的变化图像。

    ​ 同理,你也可以试着来设定一些y值来理解一下在纵向上的偏移量。

  2. 如果得到最终图像

    ​ 查看上图我们发现,我们运用的是3*3领域中的4个边角,从坐标的描述上我们就可以得到,下面的计算式子(如果看不懂的话,可以结合上面的图来分析)

    (transim(i,j) = u*v*grayim(x,y) + (1-u)*v*grayim(x+1,y) + u*(1-v)*grayim(x,y+1)+(1-u)*(1-v)*grayim(x+1,y+1);)

实现代码

%%  双线性插值法
clc;
close all;
clear all;

rgbim = imread('p2.png');
grayim = rgb2gray(rgbim);

figure;
imshow(grayim);

R = 0.4;    %   变换率
[n,m] = size(grayim);
ans = round(3/2)

n = round(n*R); %   变换后的宽
m = round(m*R); %   变换后的高

%%  变换
transim = zeros(n,m,class(grayim));

for i = 1:1:n
    for j = 1:1:m
        x = round(i/R); %   映射到原图像的位置
        y = round(j/R); %   映射到原图像的位置
        if x == 0 
            x = x+1;    end
        if y == 0
            y = y +1;   end
        %-----------------求得偏移量
        u = i/R - floor(i/R);   %   水平
        v = j/R - floor(j/R);   %   垂直
        %    对于在边缘位置的图像用最近邻插值法
        if i >= n - R || j >= m - R;
            transim(i,j) = grayim(x,y);
        else transim(i,j) = u*v*grayim(x,y) + (1-u)*v*grayim(x+1,y) + u*(1-v)*grayim(x,y+1)+(1-u)*(1-v)*grayim(x+1,y+1);
        end
    end
end
%%  输出结果
figure;
imshow(transim);
imwrite(transim,'BI.png');


原文地址:https://www.cnblogs.com/hoppz/p/14813576.html