圖像常見插值算法——超分辨率(四) 常見插值算法

常見插值算法

在現實生活中,我們經常會遇到把圖像進行放大、幾何空間變換的情況等等,這些操作都需要在源圖像和目標圖像之間建立一個映射規則\left(x^{\prime}, y^{\prime}\right)=T(x, y),使得兩圖像像素座標之間建立起一種對應關係,從而爲目標圖像的每一個像素賦值。

從源圖像到目標圖像的映射叫前向映射,但是這種映射方法可能會出現這樣的兩個問題:源圖像的好幾個像素點映射到目標圖像中的位置是相同的;目標圖像某些位置沒有要賦值的像素。這樣就要考慮如何把多個輸出值轉換成一個輸出值和對目標圖像中沒有映射到的像素該如何賦值的問題。而我們經常採用的是後向映射,這種方法比前向映射更加有效,它是從目標圖像到源圖像的映射,即(x, y)=T^{-1}\left(x^{\prime}, y^{\prime}\right),這樣就避免了前向映射中存在的問題,但也不可避免地存在着部分像素映射回源圖像時座標爲浮點數的問題,而圖像的像素值僅在整數座標處有定義,這時候就要利用圖像插值方法來給這個待求像素點賦值。

常用的插值算法有:最近鄰插值,雙線性插值,雙三次插值方法等等。其中最近鄰插值方法(零階插值)最簡單,運算量最小,但是效果很差,塊效應非常明顯。

一、最鄰插值算法

是最簡單的一種插值算法,當圖片放大時,缺少的像素通過直接使用與之最近原有顏色生成,也就是說照搬旁邊的像素。這樣做結果產生了明顯可見的鋸齒。

在待求象素的四鄰象素中,將距離待求象素最近的鄰灰度賦給待求象素。


如果 i+u, j+v(i落在 A區,即 u<0.5,v<0.5,則將左上角象素的灰度值賦給待求象素,同理落在B區則賦予右上角的象素灰度值,落在C區則賦予左下角象素的灰度值,落在D區則賦予右下角象素的灰度值。
最近鄰插值法計算量較小,但可能會造成生的圖像灰度上的不連續,在變化地方可能出現明顯鋸齒狀

二、線性插值

線性插值是一種針對一維數據的插值方法,它根據一維數據序列中需要插值的點的左右鄰近兩個數據點來進行數值的估計。當然了它不是求這兩個點數據大小的平均值(當然也有求平均值的情況),而是根據到這兩個點的距離來分配它們的比重的。


它很好地顯示了線性插值的原理。根據圖中的假設:已知點(x0,y0)、(x1,y1),試問在x處插值,y的值是多少?用我們初中學過的知識,已知兩個點的座標可以得到一條線,又已知線上一點的一個座標可以求得這個點的另一個座標值。這就是線性插值的原理。

這樣就求得了y值。

三、雙線性插值

雙線性插值

假設源圖像大小爲mxn,目標圖像爲axb。那麼兩幅圖像的邊長比分別爲:m/a和n/b。注意,通常這個比例不是整數,編程存儲的時候要用浮點型。目標圖像的第(i,j)個像素點(i行j列)可以通過邊長比對應回源圖像。其對應座標爲(im/a,jn/b)。顯然,這個對應座標一般來說不是整數,而非整數的座標是無法在圖像這種離散數據上使用的。雙線性插值通過尋找距離這個對應座標最近的四個像素點,來計算該點的值(灰度值或者RGB值)。

若圖像爲灰度圖像,那麼(i,j)點的灰度值的數學計算模型是:

f(x,y)=b1+b2x+b3y+b4xy

其中b1,b2,b3,b4是相關的係數。關於其的計算過程如下如下:

如圖,已知Q12,Q22,Q11,Q21,但是要插值的點爲P點,這就要用雙線性插值了,首先在x軸方向上,對R1和R2兩個點進行插值,這個很簡單,然後根據R1和R2對P點進行插值,這就是所謂的雙線性插值。


定義:雙線性插值,又稱爲雙線性內插。在數學上,雙線性插值是有兩個變量的插值函數的線性插值擴展,其核心思想是在兩個方向分別進行一次線性插值。

假如我們想得到未知函數f在點P=(x, y)的值,假設我們已知函數fQ_{11}=\left(x_{1}, y_{1}\right), Q_{12}=\left(x_{1}, y_{2}\right), Q_{21}=\left(x_{2}, y_{1}\right)Q_{22}=\left(x_{2}, y_{2}\right) 四個點的值。
首先在 x 方向進行線性插值,得到
\begin{aligned} f\left(R_{1}\right) & \approx \frac{x_{2}-x}{x_{2}-x_{1}} f\left(Q_{11}\right)+\frac{x-x_{1}}{x_{2}-x_{1}} f\left(Q_{21}\right) \quad \text { Where } \quad R_{1}=\left(x, y_{1}\right) \\ f\left(R_{2}\right) & \approx \frac{x_{2}-x}{x_{2}-x_{1}} f\left(Q_{12}\right)+\frac{x-x_{1}}{x_{2}-x_{1}} f\left(Q_{22}\right) \quad \text { Where } \quad R_{2}=\left(x, y_{2}\right) \end{aligned}
然後在 y 方向進行線性插值,得到
f(P) \approx \frac{y_{2}-y}{y_{2}-y_{1}} f\left(R_{1}\right)+\frac{y-y_{1}}{y_{2}-y_{1}} f\left(R_{2}\right)
這樣就得到所要的結果f(x, y),
\begin{array}{c}{f(x, y) \approx \frac{f\left(Q_{11}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x_{2}-x\right)\left(y_{2}-y\right)+\frac{f\left(Q_{21}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x-x_{1}\right)\left(y_{2}-y\right)} \\ {+\frac{f\left(Q_{12}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x_{2}-x\right)\left(y-y_{1}\right)+\frac{f\left(Q_{22}\right)}{\left(x_{2}-x_{1}\right)\left(y_{2}-y_{1}\right)}\left(x-x_{1}\right)\left(y-y_{1}\right)}\end{array}
如果選擇一個座標系統使得 f 的四個已知點座標分別爲 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那麼插值公式就可以化簡爲
f(x, y) \approx f(0,0)(1-x)(1-y)+f(1,0) x(1-y)+f(0,1)(1-x) y+f(1,1) x y
或者用矩陣運算表示爲:
f(x, y) \approx\left[\begin{array}{cc}{1-x} & {x}\end{array}\right]\left[\begin{array}{cc}{f(0,0)} & {f(0,1)} \\ {f(1,0)} & {f(1,1)}\end{array}\right]\left[\begin{array}{c}{1-y} \\ {y}\end{array}\right]
線性插值的結果與插值的順序無關。首先進行 y 方向的插值,然後進行 x 方向的插值,所得到的結果是一樣的。

注意: 源圖像和目標圖像的原點(0,0)均選擇左上角,然後根據插值公式計算目標圖像每點像素,假設你需要將一幅5x5的圖像縮小成3x3,那麼源圖像和目標圖像各個像素之間的對應關係如下:


只畫了一行,用做示意,從圖中可以很明顯的看到,如果選擇右上角爲原點(0,0),那麼最右邊和最下邊的像素實際上並沒有參與計算,而且目標圖像的每個像素點計算出的灰度值也相對於源圖像偏左偏上。

那麼,讓座標加1或者選擇右下角爲原點怎麼樣呢?很不幸,還是一樣的效果,不過這次得到的圖像將偏右偏下。

最好的方法就是,兩個圖像的幾何中心重合,並且目標圖像的每個像素之間都是等間隔的,並且都和兩邊有一定的邊距,這也是matlab和openCV的做法。如下圖:


計算對應座標的時候改爲以下公式即可:

代替

四、雙三次(bicubic)插值

雙三次插值又稱立方卷積插值。三次卷積插值是一種更加複雜的插值方式。該算法利用待採樣點周圍16個點的灰度值作三次插值,不僅考慮到4 個直接相鄰點的灰度影響,而且考慮到各鄰點間灰度值變化率的影響。三次運算可以得到更接近高分辨率圖像的放大效果,但也導致了運算量的急劇增加。這種算法需要選取插值基函數來擬合數據,其最常用的插值基函數如下所示:
構造BiCubic函數:
W(x)=\left\{\begin{array}{ll}{(a+2)|x|^{3}-(a+3)|x|^{2}+1} & {\text { for }|x| \leq 1} \\ {a|x|^{3}-5 a|x|^{2}+8 a|x|-4 a} & {\text { for } 1<|x|<2} \\ {0} & {\text { otherwise }}\end{array}\right.
其中,a取-0.5.

BiCubic函數具有如下形狀:


假設源圖像A大小爲mn,縮放後的目標圖像B的大小爲MN。那麼根據比例我們可以得到B(X,Y)在A上的的 對應座標爲A(x,y)=A(X(m/M),Y(n/N))。在雙線性插值法中,我們選取A(x,y)的最近四個點。而在雙立方 插值法中,我們選取的是最近的16個像素點作爲計算目標圖像B(X,Y)處像素值的參數。如圖所示:


每個像素值的權重由該點到待求像素點的距離確定,這個距離包括水平和豎直兩個方向上的距離。以像素點爲例,該點在豎直和水平方向上與待求像素點的距離分別是和則該像素點的權重爲。則待求點像素值的計算方法如下式所示。

其中:


插值核w(x)爲:
w(x)=\left\{\begin{array}{cc}{1-2|x|^{2}+|x|^{3}} & {,|x|<1} \\ {4-8|x|+5|x|^{2}-|x|^{3},} & {1 \leq|x|<2} \\ {0} & {, \quad|x| \geq 2}\end{array}\right.

參考文章:
圖像處理: 五種 插值法
圖像放大並進行BiCubic插值 Matlab/C++代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章