![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiETPwJWZ3ZCMwcTP39zZuBnLENTJENTJ3pVdC5GTykkeNd3aU1EeJR1T4BTaOl3YE5EerpWT3lkaOlXVE10dJRUT5BzQONzYU9ENRRVT2VFRNdXSE1Ue4MkTzMGVPRTUU1kdjJjYzpkMMRXOykVdNNjW2hXbZVnTtx0dJRUT5N2ViBXO5xkNNh0YwIFSh9CXt92YuM3YltWas5iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
圖像的雙線性插值過程推導,利用Matlab進行驗證。實驗證明,利用雙線性插值法,可以對圖檔做任意尺寸的縮放操作。
在圖像進行中,如果需要對圖像進行縮放,一般可以采取插值法,最常用的就是雙線性插值法。本文首先從數學角度推導了一維線性插值和二維線性插值的計算過程,并總結了規律。随後将其應用到圖像的雙線性插值上,利用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
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiETPwJWZ3ZCMwcTP39zZuBnLENTJENTJ3pVdC5GTykkeNd3aU1EeJR1T4BTaOl3YE5EerpWT3lkaOlXVE10dJRUT5BzQONzYU9ENRRVT2VFRNdXSE1Ue4MkTzMGVPRTUU1kdjJjYzpkMMRXOykVdNNjW2hXbZVnTtx0dJRUT5N2ViBXO5xkNNh0YwIFSh9CXt92YuM3YltWas5iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
放大圖檔
利用代碼 可以對圖像進行縮放 200×200 → 600×600
參考資料
- 【圖像處理】利用雙線性插值算法進行圖像的縮放
- 圖像縮放--雙線性插值