圖像插值技術——雙線性插值法


在圖像處理中,如果需要對圖像進行縮放,一般可以采取插值法,最常用的就是雙線性插值法。本文首先從數學角度推導了一維線性插值和二維線性插值的計算過程,並總結了規律。隨后將其應用到圖像的雙線性插值上,利用Matlab編程進行圖像的縮放驗證,實驗證明,二維線性插值能夠對圖像做出較好的縮放效果。

數學角度的線性插值

一維線性插值

假設有一個一元函數 \(y = f(x)\) , 已知曲線上的兩點,\(A\)\(B\) 的坐標分別為 \((x_0 , y_0)\)\((x_1, y_1)\) 。現在要在\(A\)\(B\) 之間通過插值計算出一個點 \(P\) ,若已知 \(P\)點的橫坐標 \(x\),如何求出 \(P\)點的縱坐標 \(y\) ?

這里我們的插值之所以叫做線性插值,就是因為我們假定了 \(P\) 點落在 \(A\) 點和 \(B\) 點的連線上,使得他們的坐標之間滿足線性關系。所以,根據初中的知識,可以得到下面的等式:

\[{{y - {y_0}} \over {{y_1} - {y_0}}} = {{x - {x_0}} \over {{x_1} - {x_0}}} \]

這里我們令:

\[\alpha = {{x - {x_0}} \over {{x_1} - {x_0}}} \]

於是,我們可以得到\(P\)點的縱坐標 \(y\) 的表達式:

\[y = \left( {1 - \alpha } \right){f(x_0)} + \alpha {f(x_1)} \]

二維線性插值

一維線性插值可以擴展到二維的情況。

假設有一個二元函數 \(z = f(x,y)\) , 已知曲面上的四點,\(A\)\(B\)\(C\)\(D\)的坐標分別為 \((x_0 , y_0)\)\((x_1, y_0)\)\((x_1, y_1)\)\((x_0, y_1)\) 。現在要在\(A\)\(B\)\(C\)\(D\)之間通過插值計算出一個點 \(P\) ,若已知 \(P\)點的坐標 \((x,y)\),如何求出 \(P\)點的函數值坐標 \(z\) ?

這里我們依舊可以仿照一維線性插值,進行計算。

假設先計算 \(y\) 軸方向的插值點 \(P_0\)\(P_1\) ,則根據上面的推導過程,且令

\[\alpha = {{y - {y_0}} \over {{y_1} - {y_0}}} \]

則, \(P_0\) 的取值 \(z_0\)為:

\[z_0 = \left( {1 - \alpha } \right){f(x_0,y_0)} + \alpha {f(x_0,y_1)} \]

\(P_1\) 的取值 \(z_1\)為:

\[z_1 = \left( {1 - \alpha } \right){f(x_1,y_0)} + \alpha {f(x_1,y_1)} \]

再計算 \(x\) 軸方向的插值點 \(P\),令

\[\beta = {{x - {x_0}} \over {{x_1} - {x_0}}} \]

\(P\) 的取值 \(z\)為:

\[z = \left( {1 - \beta } \right){z_0} + \beta {z_1} \]

整理得到下面的式子:

\[\eqalign{ & z = \left( {1 - \beta } \right)\left[ {\left( {1 - \alpha } \right)f\left( {{x_0},{y_0}} \right) + \alpha f\left( {{x_0},{y_1}} \right)} \right] + \beta \left[ {\left( {1 - \alpha } \right)f\left( {{x_1},{y_0}} \right) + \alpha f\left( {{x_1},{y_1}} \right)} \right] \cr & \;\;{\kern 1pt} = \left( {1 - \beta } \right)\left( {1 - \alpha } \right)f\left( {{x_0},{y_0}} \right) + \left( {1 - \beta } \right)\alpha f\left( {{x_0},{y_1}} \right) + \beta \left( {1 - \alpha } \right)f\left( {{x_1},{y_0}} \right) + \beta \alpha f\left( {{x_1},{y_1}} \right) \cr} \]

小結

由一維線性插值過渡到二維線性插值,我們發現,二者在表達式上有相似的規律:

一維線性插值:

\[\left\{ {\matrix{ {y = f\left( x \right)} \hfill \cr {\alpha = {{x_p - {x_0}} \over {{x_1} - {x_0}}}} \hfill \cr {{y_p} = \left( {1 - \alpha } \right)f\left( {{x_0}} \right) + \alpha f\left( {{x_1}} \right)} \hfill \cr } } \right. \]

二維線性插值:

\[\left\{ {\matrix{ {z = f\left( {x,y} \right)} \hfill \cr {\alpha = {{{x_p} - {x_0}} \over {{x_1} - {x_0}}},\beta = {{{y_p} - {y_0}} \over {{y_1} - {y_0}}}} \hfill \cr {{z_p} = \left( {1 - \beta } \right)\left( {1 - \alpha } \right)f\left( {{x_0},{y_0}} \right) + \left( {1 - \beta } \right)\alpha f\left( {{x_0},{y_1}} \right) + \beta \left( {1 - \alpha } \right)f\left( {{x_1},{y_0}} \right) + \beta \alpha f\left( {{x_1},{y_1}} \right)} \hfill \cr } } \right. \]


圖像中的雙線性插值

我們可以用函數來表示一幅圖像(假設為單通道)。如下圖所示,假設有一幅圖,其尺寸為3×3大小,每個像素點對應一個灰度值(0~255),以圖像的左上角為坐標原點,橫向為 \(x\) 軸,縱向為 \(y\) 軸,則圖像的表達式可以表達為:

\[f(x,y) \]

每個像素點的灰度值 \(z\) 由橫縱坐標唯一確定,即 \(z=f(x,y)\)

假設需要將圖片進行尺寸縮放,則可以利用前面所提到的雙線性插值法進行變換。

這里我們定義原始的圖片為 src ,其寬度為 src_width, 高度為 src_height,通道數為 channel

縮放的目標圖片為 dst,其寬度為 dst_width, 高度為 dst_height, 通道數與原始圖片一樣,為channel

利用雙線性插值來進行圖像的縮放步驟如下:

  • 計算目標圖片與原始圖片之間的縮放因子(寬度、高度方向)
  • 利用縮放因子,由目標圖片像素位置反推回原始圖片中的虛擬像素位置
  • 由虛擬像素位置找到寬度和高度方向相鄰的四個像素點
  • 由四個像素點進行雙線性插值計算,得出目標圖像中的像素值

由於圖片像素的位置一格表示一個像素,因此,在前面的公式中,相鄰的點之間坐標在相同方向的差值為1。

基於Matlab的圖片雙線性插值

close all
clc
clear

% 讀取原始圖像,並轉換為 double 類型
src = imread('lena.jpg');
src = im2double(src);

% 讀取圖像尺寸信息
[src_width, src_height,channel] = size(src);

% 目標圖像尺寸
dst_width = 50;
dst_height = 50;


% 計算縮放因子
horFactor = src_width / dst_width;
verFactor = src_height / dst_height;

% 初始化矩陣
dst = zeros(dst_width,dst_height,channel);

for i = 1:channel
    for j = 1:dst_width
        
        x0 = j*horFactor;           % 計算虛擬像素值位置
        x1 = ceil(x0);              % 取其左側臨近的位置
        x2 = min([x1+1,src_width]); % 取其右側側臨近的位置,用 min 防止超出原始圖片邊界
        
        beta = x0 - x1;             % 公式中的 beta
        
        
        for k = 1:dst_height
            
            y0 = k*verFactor;           % 計算虛擬像素值位置
            y1 = ceil(y0);              % 取其左側臨近的位置
            y2 = min([y1+1,src_height]);% 取其右側側臨近的位置,用 min 防止超出原始圖片邊界
            
            alpha = y0 - y1;             % 公式中的 alpha
            
            % 雙線性插值求出該位置的像素值
            dst(j,k,i) = (1-beta)*(1-alpha)*src(x1,y1,i) + ...
                         (1-beta)*alpha*src(x1,y2,i) + ...
                         beta*(1-alpha)*src(x2,y1,i) + ...
                         beta*alpha*src(x2,y2,i);
            
        end
    end
end


% 處理前后圖片對比
subplot(1,2,1)
imshow(src)
subplot(1,2,2)
imshow(dst)

縮小圖片

利用代碼 可以對圖像進行縮放 200×200 → 50×50

放大圖片

利用代碼 可以對圖像進行縮放 200×200 → 600×600

參考資料


免責聲明!

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



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