1. 程式人生 > >Image Resize 雙線性和雙立方插值法

Image Resize 雙線性和雙立方插值法


I.影象處理-雙線性插值(轉載

影象的縮放很好理解,就是影象的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小影象了,把這個工作交給程式來完成就可以了。下面就來講講計算機怎麼來放大縮小圖象;在本文中,我們所說的影象都是指點陣圖,也就是用一個畫素矩陣來描述影象的方法,對於另一種影象:用函式來描述影象的向量圖,不在本文討論之列。
越是簡單的模型越適合用來舉例子,我們就舉個簡單的影象:3X3 的256級灰度圖,也就是高為3個象素,寬也是3個象素的影象,每個象素的取值可以是 0-255,代表該畫素的亮度,255代表最亮,也就是白色,0代表最暗,即黑色。假如影象的象素矩陣如下圖所示(這個原始圖把它叫做源圖,Source):
234   38    22
67     44    12
89     65    63

這個矩陣中,元素座標(x,y)是這樣確定的,x從左到右,從0開始,y從上到下,也是從零開始,這是圖象處理中最常用的座標系,就是這樣一個座標:

  ---------------------->X
  |
  |
  |
  |
  |
∨Y

如果想把這副圖放大為 4X4大小的影象,那麼該怎麼做呢?那麼第一步肯定想到的是先把4X4的矩陣先畫出來再說,好了矩陣畫出來了,如下所示,當然,矩陣的每個畫素都是未知數,等待著我們去填充(這個將要被填充的圖的叫做目標圖,Destination):
       ?        ?       ?
       ?        ?       ?
       ?        ?       ?
       ?        ?       ? 
               
        然後要往這個空的矩陣裡面填值是從源圖中來,先填寫目標圖最左上角的象素,座標為(0,0),那麼該座標對應源圖中的座標可以由如下公式得出:                                      
srcX=dstX* (srcWidth/dstWidth) , srcY = dstY * (srcHeight/dstHeight)
套用公式,就可以找到對應的原圖的座標(0*(3/4),0*(3/4))=>(0*0.75,0*0.75)=>(0,0)
,找到了源圖的對應座標,就可以把源圖中座標為(0,0)處的234象素值填進去目標圖的(0,0)這個位置了。

接下來,如法炮製,尋找目標圖中座標為(1,0)的象素對應源圖中的座標,套用公式:
(1*0.75,0*0.75)=>(0.75,0)
結果發現,得到的座標裡面竟然有小數,這可怎麼辦?計算機裡的影象可是數字影象,象素就是最小單位了,象素的座標都是整數,從來沒有小數座標。這時候採用的一種策略就是採用四捨五入的方法(也可以採用直接舍掉小數位的方法),把非整數座標轉換成整數,好,那麼按照四捨五入的方法就得到座標(1,0),完整的運算過程就是這樣的:
(1*0.75,0*0.75)=>(0.75,0)=>(1,0)
那麼就可以再填一個象素到目標矩陣中了,同樣是把源圖中座標為(1,0)處的畫素值38填入目標圖中的座標。
         
依次填完每個象素,一幅放大後的影象就誕生了,畫素矩陣如下所示:
234    38     22     22  
67      44     12     12  
89      65     63     63  
89      65     63     63 

這種放大影象的方法叫做最臨近插值演算法,這是一種最基本、最簡單的影象縮放演算法,效果也是最不好的,放大後的影象有很嚴重的馬賽克,縮小後的影象有很嚴重的失真;效果不好的根源就是其簡單的最臨近插值方法引入了嚴重的影象失真,比如,當由目標圖的座標反推得到的源圖的的座標是一個浮點數的時候,採用了四捨五入的方法,直接採用了和這個浮點數最接近的象素的值,這種方法是很不科學的,當推得座標值為 0.75的時候,不應該就簡單的取為1,既然是0.75,比1要小0.25 ,比0要大0.75 ,那麼目標象素值其實應該根據這個源圖中虛擬的點四周的四個真實的點來按照一定的規律計算出來的,這樣才能達到更好的縮放效果。雙線型內插值演算法就是一種比較好的影象縮放演算法,它充分的利用了源圖中虛擬點四周的四個真實存在的畫素值來共同決定目標圖中的一個畫素值,因此縮放效果比簡單的最鄰近插值要好很多。

雙線性內插值演算法描述如下:
  對於一個目的畫素,設定座標通過反向變換得到的浮點座標為(i+u,j+v) (其中i、j均為浮點座標的整數部分,u、v為浮點座標的小數部分,是取值[0,1)區間的浮點數),則這個畫素得值 f(i+u,j+v) 可由原影象中座標為 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所對應的周圍四個畫素的值決定,即:

f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j)+ uvf(i+1,j+1)                          公式1

其中f(i,j)表示源影象(i,j)處的的畫素值,以此類推。


比如,象剛才的例子,現在假如目標圖的象素座標為(1,1),那麼反推得到的對應於源圖的座標是(0.75 , 0.75), 這其實只是一個概念上的虛擬象素,實際在源圖中並不存在這樣一個象素,那麼目標圖的象素(1,1)的取值不能夠由這個虛擬象素來決定,而只能由源圖的這四個象素共同決定:(0,0)(0,1)(1,0)(1,1),而由於(0.75,0.75)離(1,1)要更近一些,那麼(1,1)所起的決定作用更大一些,這從公式1中的係數uv=0.75×0.75就可以體現出來,而(0.75,0.75)離(0,0)最遠,所以(0,0)所起的決定作用就要小一些,公式中係數為(1-u)(1-v)=0.25×0.25也體現出了這一特點;

最鄰近插值和雙向性內插值縮放圖片的效果對比:


 

 原始圖片

     

最鄰近插值放大圖片

      

雙線型內插值放大圖片

常用的插值方法有:最近鄰插值、雙線性插值、三次卷積法。

在做數字影象處理時,經常會碰到小數象素座標的取值問題,這時就需要依據鄰近象素的值來對該座標進行插值。比如:做地圖投影轉換,對目標影象的一個象素進行座標變換到源影象上對應的點時,變換出來的對應的座標是一個小數,再比如做影象的幾何校正,也會碰到同樣的問題。以下是對常用的三種數字影象插值方法進行介紹。

1、最鄰近元法

  這是最簡單的一種插值方法,不需要計算,在待求象素的四鄰象素中,將距離待求象素最近的鄰象素灰度賦給待求象素。設i+u, j+v(i, j為正整數, u, v為大於零小於1的小數,下同)為待求象素座標,則待求象素灰度的值 f(i+u, j+v) 如下圖所示:


如果(i+u, j+v)落在A區,即u<0.5, v<0.5,則將左上角象素的灰度值賦給待求象素,同理,落在B區則賦予右上角的象素灰度值,落在C區則賦予左下角象素的灰度值,落在D區則賦予右下角象素的灰度值。

最鄰近元法計算量較小,但可能會造成插值生成的影象灰度上的不連續,在灰度變化的地方可能出現明顯的鋸齒狀。

2、雙線性內插法

雙線性內插法是利用待求象素四個鄰象素的灰度在兩個方向上作線性內插,如下圖所示:



對於 (i, j+v)f(i, j)  f(i, j+1) 的灰度變化為線性關係,則有:

f(i, j+v) = [f(i, j+1)- f(i, j)] * v + f(i, j)

同理對於 (i+1, j+v) 則有:

                  f(i+1,j+v) = [f(i+1, j+1) - f(i+1, j)] * v + f(i+1, j)

f(i, j+v)  f(i+1, j+v) 的灰度變化也為線性關係,由此可推匯出待求象素灰度的計算式如下:

                  f(i+u,j+v) = (1-u) * (1-v) * f(i, j) + (1-u) * v * f(i, j+1) + u * (1-v) * f(i+1, j)+ u * v * f(i+1, j+1)

雙線性內插法的計算比最鄰近點法複雜,計算量較大,但沒有灰度不連續的缺點,結果基本令人滿意。它具有低通濾波性質,使高頻分量受損,影象輪廓可能會有一點模糊。

3、三次內插法

該方法利用三次多項式S(x)求逼近理論上最佳插值函式sin(x)/x, 其數學表示式為:

待求畫素(x, y)的灰度值由其周圍16個灰度值加權內插得到,如下圖:

 

待求畫素的灰度計算式如下:

f(x, y) = f(i+u, j+v) = ABC

其中

三次曲線插值方法計算量較大,但插值後的影象效果最好。

II.影象處理-雙立方插值(轉載

雙立方插值計算涉及到16個畫素點,其中(i’, j’)表示待計算畫素點在源影象中的包含

小數部分的畫素座標,dx表示X方向的小數座標,dy表示Y方向的小數座標。具體

可以看下圖:


根據上述圖示與雙立方插值的數學表示式可以看出,雙立方插值本質上影象16個畫素點

權重卷積之和作為新的畫素值。

其中R(x)表示插值表示式,可以根據需要選擇的表示式不同。常見有基於三角取值、Bell

分佈表達、B樣條曲線表示式。

1. 基於三角形取樣數學公式為


最簡單的線性分佈,程式碼實現如下:

  1. privatedouble triangleInterpolation( double f )  
  2. {  
  3.     f = f / 2.0;  
  4.     if( f < 0.0 )  
  5.     {  
  6.         return ( f + 1.0 );  
  7.     }  
  8.     else
  9.     {  
  10.         return ( 1.0 - f );  
  11.     }  
  12. }  
2.基於Bell分佈取樣的數學公式如下:


Bell分佈取樣數學公式基於三次卷積計算實現。程式碼實現如下:

  1. privatedouble bellInterpolation( double x )  
  2. {  
  3.     double f = ( x / 2.0 ) * 1.5;  
  4.     if( f > -1.5 && f < -0.5 )  
  5.     {  
  6.         return0.5 * Math.pow(f + 1.52.0));  
  7.     }  
  8.     elseif( f > -0.5 && f < 0.5 )  
  9.     {  
  10.         return3.0 / 4.0 - ( f * f );  
  11.     }  
  12.     elseif( ( f > 0.5 && f < 1.5 ) )  
  13.     {  
  14.         return0.5 * Math.pow(f - 1.52.0));  
  15.     }  
  16.     return0.0;  
  17. }  
3.基於B樣條曲線取樣的數學公式如下:


是一種基於多項式的四次卷積的取樣計算,程式碼如下:

  1. privatedouble bspLineInterpolation( double f )  
  2. {  
  3.     if( f < 0.0 )  
  4.     {  
  5.         f = -f;  
  6.     }  
  7.     if( f >= 0.0 && f <= 1.0 )  
  8.     {  
  9.         return ( 2.0 / 3.0 ) + ( 0.5 ) * ( f* f * f ) - (f*f);  
  10.     }  
  11.     elseif( f > 1.0 && f <= 2.0 )  
  12.     {  
  13.         return1.0 / 6.0 * Math.pow( ( 2.0 - f  ), 3.0 );  
  14.     }  
  15.     return1.0;  
  16. }  
實現影象雙立方插值的完整原始碼如下:
  1. package com.gloomyfish.zoom.study;  
  2. import java.awt.image.BufferedImage;  
  3. import java.awt.image.ColorModel;  
  4. import com.gloomyfish.filter.study.AbstractBufferedImageOp;  
  5. publicclass BicubicInterpolationFilter extends AbstractBufferedImageOp  {  
  6.     publicfinalstaticint TRIANGLE__INTERPOLATION = 1;  
  7.     publicfinalstaticint BELL__INTERPOLATION = 2;  
  8.     publicfinalstaticint BSPLINE__INTERPOLATION = 4;  
  9.     publicfinalstaticint CATMULLROOM__INTERPOLATION = 8;  
  10.     publicfinalstaticdouble B = 0.0;  
  11.     publicfinalstaticdouble C = 0.5// constant
  12.     privateint destH; // zoom height
  13. 相關推薦

    Image Resize 線性立方

    I.影象處理-雙線性插值(轉載) 影象的縮放很好理解,就是影象的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小影象了,把這個工作交給程式來完成就可以了。下面就來講講計算機怎麼來放大縮小圖象;在本文中,我們所說

    影象處理中兩種基本的演算法(最鄰近線性)

    在影象的基本仿射變換中,經常會碰到經過旋轉、縮放後灰度值如何賦值的問題。因為變換之後,影象的座標位置有可能是小數,所以就需要插值演算法來確定到底將該畫素賦予哪個位置。 1、最鄰近插值法(Nearest Interpolation) 這是最簡單的一種插值方法,不需要計算。在待

    使用Matlab進行影象的讀寫、顯示縮放(最近臨線性

    上次我們開始進行數字影象處理這門課程的實驗,直到現在才抽空出來寫寫文章,記錄一下知識點。介紹一下,使用Matlab對數字影象的簡單處理。 1、 讀取與顯示輸入影象: %輸入影象和顯示影象 funct

    圖像處理之三種常見立方

    log views 實現 ack oar 過程 線表 const filter http://blog.csdn.net/jia20003/article/details/40020775 圖像處理之三種常見雙立方插值算法 雙立方插值計算涉及到16個像素點,其中(i’, j

    Matlab 演算法(最鄰近、線性三次

    1、最鄰近元法 這是最簡單的一種插值方法,不需要計算,在待求象素的四鄰象素中,將距離待求象素最近的鄰象素灰度賦給待求象素。設i+u, j+v(i, j為正整數, u, v為大於零小於1的小數,下同)為待求象素座標,則待求象素灰度的值 f(i+u, j+v) 如下圖所示:

    線性,最鄰近 處理圖片的旋轉,放大

    對於一張圖片旋轉某個角度,其實就是把每個畫素計算好它的位置,再對對應的位置設定畫素值即可,以順時針為例,如下圖,由P點旋轉到P', x=rcos(a) y=rsin(a) x'=rcos(a+b)=rcos(a)cos(b)-rsin(a)sin(b) y'=rsi

    線性影象放縮示例

    演算法原理簡介 雙線性插值是一階插值,常用於影象的旋轉、縮放處理。 它利用原圖中對應的四個點的畫素值來確定目標影象中的畫素值。 為了便於理解,我們來看兩張尺寸不一樣的圖片: 原圖 變換圖 假設原圖圖片的寬度為yw,高度為xh 變換圖的寬

    影象的放大與縮小(3)——立方演算法

    -----------------------------轉載自jia20003的部落格" ----------------------------------- 一:數學原理 如果已知一個函式f(x)以及它在x=0,x=1處的導數,那麼

    在基於debian的deepin或者Ubuntu上等號“==”中括號“[[]]”不能使用的真相

    logs deep test [] 發現 不能 腳本 使用 mar 使用的deepin-linux,今天寫shell腳本的時候,忽然發現 sh test.sh 會報錯[[: not found ,雙等號和雙中括號都不能使用了,很郁悶,後來探索發現,sh其實是dash的別名,

    什麼是單工、半工通訊(最詳細)

    單工、半雙工、全雙工、單工資料傳輸只支援資料在一個方向上傳輸;      半雙工資料傳輸允許資料在兩個方向上傳輸,但是,在某一時刻,只允許資料在一個方向上傳輸,它實際上是一種切換方向的單工通訊;     &nb

    影象縮放之三次

    今天學習了第三種影象縮放的方法,雙三次插值法。由於理解能力比較差,看了好久的公式,還是雲裡霧裡,但是為了督促自己學習,還是把已知的部分記錄下來。 數學原理 假設源影象A大小為m*n,縮放後的目標影象B的大小為M*N。那麼根據比例我們可以得到B(X,Y)在

    Codeforces 622F The Sum of the k-th Powers ( 自然數冪、拉格朗日 )

    n-1 power HERE sig class text name while pow 題目鏈接 題意 : 就是讓你求個自然數冪和、最高次可達 1e6 、求和上限是 1e9 分析 : 題目給出了最高次 k = 1、2、3 時候的自然數冪和求和公式 可以發現求和公式的

    一維(interp1)二維(interp2)

    一、一維插值 1.定義 插值:已知f(x)的N個數據點,f(x)不知道。根據N個數據點估計任意點的函式值f(x)。 2. interp1函式 呼叫格式: yi = interp1(x,y,xi,method)    其中x,y為已知的資料點,通常xi為比x更加密集的資料點,

    【拉格朗日求自然數冪

    求自然數冪和: 1<=n<=10^5,1<=k<=10^5 用快速冪; 1<=n<=10^9,1<=k<=10^6 用拉格朗日插值法; 1.什麼是拉格

    51nod 1258 序列求和 V4 拉格朗日求自然數冪

    題意 T(n) = n^k,S(n) = T(1) + T(2) + …… T(n)。給出n和k,求S(n)。 例如k = 2,n = 5,S(n) = 1^2 + 2^2 + 3^2 + 4^2

    拉格朗日及應用

    oci cin app .com dmg npe info sina gin 3man6h1yg巫http://shufang.docin.com/sina_6355780928 7DMg布62夏aq撂儼8秤http://www.docin.com/app/user/use

    拉格朗日

    說明 -1 需要 插值 是什麽 col pre rac div   給定 $n$ 個點 $(x_1, y_1), (x_2, y_2), ..., (x_n, y_n)$ , 其中 $x_1, x_2, ..., x_n$ 互不相等, 構造一個最高次不超過 $n-1$ 的多

    圖像

    值方法 方向 信息 基於 lan 介紹 XML 模型 技術分享 第一部分: 在做數字圖像處理時,經常會碰到小數象素坐標的取值問題,這時就需要依據鄰近象素的值來對該坐標進行插值。比如:做地圖投影轉換,對目標圖像的一個象素進行坐標變換到源圖像上對應的點時,變換出來

    4559[JLoi2016]成績比較 容斥+拉格朗日

    mem otto spa ack input mes mod 只需要 rip 4559: [JLoi2016]成績比較Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 261 Solved: 165[Submit][Statu

    樣條(Java)

    Coding trace 算法 top writer 檢查 block 技術分享 iter 該程序包含:樣條插值法、讀取文件,寫入文件,字符型轉double型方法等; 適合初學Java的人學習; 在cmd中執行, 在Linux中執行 完整代碼如下: 樣條插值法: