[數字圖像處理](六)插值運算


參考文章

(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');



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM