From: http://blog.csdn.net/swimmingfish2004/article/details/7312361
Lanczos Algorithm Analyse
在公司時候研究過的Lanczos映像縮減演算法,今天整理出來給大家分享,分析的是imagemagic裡面的lanczos resize的源碼。
1 映像縮放原理簡介
映像縮放的基本原理就是根據原映像的像素值通過一定的規則計算得到靶心圖表像的像素值。在映像縮放的過程中,最重要的就是確定下面兩個問題:一是計算目的映像中的每一個像素值時,應該選取原映像中哪些像素值;二是這些選取出的像素值在計算目的像素時權重如何確定。
2 lanczos演算法介紹
通常根據確定參與計算的像素權重的方式來分類各種映像interpolation algorithm。Lanczos演算法用到的數學公式如下:
我們可以畫出a=2,a=3時的L(x)映像
假定我們的一維函數用f(x)來表示,I(x)來表示由n個f(x)的值通過lanczos filter來得到其值,則I(x)的計算如下:
二維、三維的表示類似。 下面只給出一個二維的計算公式:
簡言之,我們使用lanczos演算法的主要作用就是由其確定各個參與計算的像素值的權重。
3 現即時需要考量的點3.1計算目的像素時需要選取哪些像素點
在lanczos演算法中是選取一個矩形地區來計算新的像素點
3.2選取像素計算點時從哪裡開始
在lanczos algorithm中應該映像中間的像素比映像兩邊的像素重要,因此在選取使用的像素時是由中間開始來選取的。
4 MagicImage中Lanczos演算法實現的分析4.0最重要的檔案
Magic/resize.c
4.1 主要流程調用4.1.1 ZoomImage
MagickExport Image *ZoomImage(const Image *image, const unsigned long columns, const unsigned long rows, ExceptionInfo *exception)
這個函數中,輸入:image指向原始的映像,columns和rows表示縮放後的像素大小,輸出:縮放後的映像
ZoomImage中調用ResizeImage函數
4.1.2 ResizeImage
MagickExport Image *ResizeImage(const Image *image, const unsigned long columns, const unsigned long rows, const FilterTypes filter,const double blur, ExceptionInfo *exception)
這個函數中,輸入:filter是指縮放函數使用的類型,blur是指模糊化的系統
輸出:縮放後的映像
在這個函數中完成縮放功能:主要分為四個步驟:
第一步:先產生一個縮放後映像的像素空矩陣和一個過渡映像的像素空矩陣,連同原始圖片的像素矩陣這裡一共有三個像素矩陣,比如,將一幅10*10像素的映像縮放成6*6像素的圖象:在這裡產生了三個像素矩陣:10*10的原像素矩陣,6*6的目的像素矩陣(資料不正確),6*10或10*6的過渡像素矩陣(資料不正確)
第二步:擷取過濾演算法的參數,比如使用什麼樣的interpolation演算法、模糊化參加是多少等等。這樣具體就是調用AcquireResizeFilter函數來填充一個resize_filter結構。
第三步:就是調用:HorizontalFilter函數和VerticalFilter函數,分別計算行的縮放和列的縮放
第四步:返回縮放好的像素矩陣並釋放相應的記憶體結構
4.1.3 AcquireResizeFilter
MagickExport ResizeFilter *AcquireResizeFilter(const Image *image, const FilterTypes filter,const MagickRealType blur, const MagickBooleanType cylindrical,ExceptionInfo *exception)
這個函數中輸出:一個填充好的resize_filter結構
主要的資料結構有:mapping二維數組,用來指定使用的interpolation algorithm和filter type
Filters二維數組,用來指定過濾器所用的函數和初始值,如我們選用Lanczos algorithm,由表可知,所使用的函數為sinc,初始值為1.0,使用的sinc函數為3的sinc函數,即:
L(x) = sinc(x)*sinc(x/3) = sin(x) * sin(x/3)/3 當-3<x<3時,x取其它值時L(x)= 0
| 12345 |
resize_filter->blur//設定模糊度resize_filter->support = 3.0resize_filter->scale = 1.0resize_filter->filter = sincresize_filter->window = sinc |
4.1.4 HorizontalFilter
計算x_factor,y_factor,公式如下:
x_factor = 縮放後的水平像素值/原圖片的水平像素值
y_factor = 縮放後的垂直像素值/原圖片的垂直像素值
在本例中,x_factor = 0.6,y_factor = 0.6
static MagickBooleanType HorizontalFilter(const ResizeFilter *resize_filter, const Image *image,Image *resize_image,const MagickRealType x_factor, const MagickSizeType span,MagickOffsetType *quantum,ExceptionInfo *exception)
這個函數的輸入:quantum = 0,span = 6+6
image_view與resize_view,這兩個值與CMYK色彩空間有關
Contributions數組:這個數組負責filter器的裝入,即這個數組的值由GetResizeFilterWeight函數調用sinc函數,添入相應的計算值
其計算過程如下:
計算的順序,先水平計算完所有紅色框的內容,向右移一列,再水平計算綠色框的資料,即先水平再垂直。
所以為迴圈的
| 123456 |
for (columns){ for(rows) { }} |
4.1.5 VerticalFilter
詳見HorizontalFilter
另外的資料
2. 3. 4 縮放模組
視頻縮放包括放大( up scaling ) 和縮小( downsca ling )兩個方面,而進行縮放的基本方法為空白間插值。下式為對映像進行插值的一般數學運算式,其中g ( i,j)為縮放映像中待插值點的像素值,f ( k,l)為原始映像中座標( k,l)處的像素值,h( i- k,j - l)為插值基函數。
插值基函數的選擇可以有很多種,通常有二維的矩形函數、線性函數、三次函數及S inc 函數等,它們分別對應於最近鄰插值、線性插值、三次插值以及理想插值(實際中利用S inc函數截斷後插值) ,其插值效果為從差到好排列,但實現難度也依次提高。在實際處理中是利用濾波器來實現插值基函數,而且由於這些插值的對稱性,可以將其分解為橫向和縱向插值兩部分分開進行,如二維線性插值函數對應雙線性插值( Bilinear Interpo lation),三次函數對應雙立方插值( B icub ic Interpo lation) ,對於Sinc 插值函數實際中為多相位插值( Po lyphase Interpo lation)。本文使用多相位插值法實現映像縮放,實際上在4 ? 4領域大小內進行多相位插值和三次插值幾乎是一樣的,只是對應插值函數值略微不同。多相位插值法是通過對輸出點對應原圖中的領域進行Lanczos2 函數移相插值來產生輸出點的。11所示。
圖11 Lanczos2 函數
假設g ( u,v )為經縮放後輸出映像中一點,其還原到原映像的最近點為f ( i,j) 且兩者在原圖中相差( x,y )的座標,則輸出點g ( u,v)的數學表達如下,從其可以看出實際上分為兩步實現分別進行垂直濾波和水平濾波。
其中有關係式: i = ( u ×W in ) /W out,j = ( v ×H in) /H out; x = ( u × W in)% W out,y = ( v ×H in)%H out。W in 和Wout分別為縮放前後的映像寬度,H in和H out分別為縮放前後的映像高度。圖12為4 ×4領域水平垂直相位,其中的水平相位值分別為PH 0,PH 1,PH 2,PH 3,垂直相位值分別為PV0,PV1,PV2,PV3。只要根據上述關係式求得x,y 值就能獲得8 個相位值,就能實現多相位濾波。
圖12 4×4 領域水平垂直相位
圖13為本文設計的映像縮放器中濾波器部分框圖,其中的垂直水平尋找表裡分別存放著4個不同相位的Lanczos2 函數值。
圖13 映像縮放器中的濾波器
(本文轉自電子工程世界:http://www.eeworld.com.cn/FPGA/2011/0330/article_1947_2.html)