影象縮放的雙線性內插值演算法的原理解析
轉自:http://blog.csdn.net/qiqi5521/article/details/2207562
影象的縮放很好理解,就是影象的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小影象了,把這個工作交給程式來完成就可以了。下面就來講講計算機怎麼來放大縮小圖象;在本文中,我們所說的影象都是指點陣圖,也就是用一個畫素矩陣來描述影象的方法,對於另一種影象:用函式來描述影象的向量圖,不在本文討論之列。
越是簡單的模型越適合用來舉例子,我們就舉個簡單的影象: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)v f(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也體現出了這一特點;
後記:近日在論壇上看到有人提問,說寫的影象縮放演算法放大圖片的時候出現了空缺。分析了一下程式碼,發現是犯了這樣的錯誤:縮放圖片的時候,遍歷源圖的畫素,然後推出目標圖中的對應座標,進行逐點的畫素拷貝,這樣當然放大圖片的時候會出現空缺。縮小圖片的時候結果是對的,但是會出現多餘的計算量。
影象縮放演算法一定要反推:遍歷目標圖的畫素,反推得到源圖中的對應座標,然後進行畫素拷貝。這樣才保證了放大圖片沒有空缺,縮小圖片也不會引入冗餘計算。
最鄰近插值和雙向性內插值縮放圖片的效果對比:
原始圖片
最鄰近插值放大圖片
雙線型內插值放大圖片
相關文章
- [work] 影象縮放——雙線性插值演算法演算法
- 影象縮放--插值法(opencv,原理)OpenCV
- 圖形影象處理-之-高質量的快速的影象縮放 中篇 二次線性插值和三次卷積插值卷積
- opencv中自定義的雙線性二次插值的影像旋轉及縮放OpenCV
- 【影像縮放】雙立方(三次)卷積插值卷積
- 影像重取樣演算法之雙線性插值演算法演算法
- 圖形影象處理-之-高質量的快速的影象縮放 上篇 近鄰取樣插值和其速度優化優化
- 在不使用cv2等庫的情況下利用numpy實現雙線性插值縮放影像
- C++影象縮放C++
- 【影象演算法】高斯模糊+徑向縮放模糊演算法
- 有符號浮點運算的基本步驟:以雙線性插值為例符號
- OpenCV(iOS)影象尺寸縮放(14)OpenCViOS
- 演算法-查詢(線性、二分、插值、斐波那契)演算法
- NOISEDIFFUSION: 改進基於擴散模型的球面線性插值模型
- [Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移Python
- HOG演算法中用到三線性插值(Trilinear Interpolation)的作用及其用法HOG演算法
- 常用演算法 插值演算法演算法
- 插值查詢演算法演算法
- 插值演算法總結演算法
- 介紹一種二維線性插值計算方法
- 十三種基於直方圖的影象全域性二值化演算法原理、實現、程式碼及效果。直方圖演算法
- 使用StretchBlt函式進行影象縮放函式
- 影象放大並進行BiCubic插值 Matlab/C++程式碼MatlabC++
- 查詢演算法__插值查詢演算法
- JPEG影象的解壓縮操作
- 一文讀懂影象壓縮演算法演算法
- SCSS #{} 插值CSS
- C#影象顯示實現拖拽、錨點縮放功能【轉】C#
- 基於模糊集理論的一種影象二值化演算法的原理、實現效果及程式碼演算法
- flutter實現可縮放可拖拽雙擊放大的圖片功能Flutter
- 深度學習影象視訊壓縮演算法——TNG深度學習演算法
- angularjs中的雙向繫結原理解析AngularJS
- 【數字影象處理】五.MFC影象點運算之灰度線性變化、灰度非線性變化、閾值化和均衡化處理詳解
- 自定義圖片裁剪之雙指縮放思路
- 插值查詢的簡單理解
- MemoryCache 的原生插值方式淺談
- 自控原理中的線性系統和非線性系統
- 影像重取樣演算法之最鄰近插值演算法演算法