def show_digits(): digits=load_digits() fig=plt.figure() for i in range(25): ax=fig.add_subplot(5,5,i+1) ax.imshow(digits.images[i],cmap=plt.cm.gray_r,interpolation='bilinear') plt.show() show_detail()
python的sklearn中對圖像插值的實現方式,如下
對interpolation的說明:
interpolation : string, optional, default: None
Acceptable values are 'none', 'nearest', 'bilinear', 'bicubic',
'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser',
'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc',
'lanczos'
If `interpolation` is None, default to rc `image.interpolation`.
See also the `filternorm` and `filterrad` parameters.
If `interpolation` is 'none', then no interpolation is performed
on the Agg, ps and pdf backends. Other backends will fall back to
'nearest'.
插值:字符串,可選,默認:無
可接受的值是“無”,“最接近”,“雙線性”,“雙三次”,
“spline16”,“spline36”,“hanning”,“hamming”,“hermite”,“kaiser”
'quadric','catrom','gaussian','bessel','mitchell','sinc',
“蘭克澤斯”
如果`interpolation`為None,則默認為rc`image.interpolation`。
另見`filternorm`和`filterrad`參數。
如果“插值”為“無”,則不執行插值
在Agg,ps和pdf后端。 其他后端將回落到
“最近”。
圖像的縮放很好理解,就是圖像的放大和縮小。傳統的繪畫工具中,有一種叫做“放大尺”的繪畫工具,畫家常用它來放大圖畫。當然,在計算機上,我們不再需要用放大尺去放大或縮小圖像了,把這個工作交給程序來完成就可以了。下面就來講講計算機怎么來放大縮小圖象;在本文中,我們所說的圖像都是指點陣圖,也就是用一個像素矩陣來描述圖像的方法,對於另一種圖像:用函數來描述圖像的矢量圖,不在本文討論之列。
越是簡單的模型越適合用來舉例子,我們就舉個簡單的圖像: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):
? ? ? ?
? ? ? ?
? ? ? ?
? ? ? ?
現在從最簡單的情況說起
1.最近鄰插值
該算法是最簡單的插值算法,就只是把放大后缺失的點的像素值用最靠近的原圖的像素值直接填進去就可以了,比如坐標為(0,0),那么該坐標對應源圖中的坐標可以由如下公式得出:
放大系數t=dstWidth/srcWidth=4/3
srcX=dstX/t, srcY = dstY/t
好了,套用公式,就可以找到對應的原圖的坐標了(0/(4/3),0/(4/3))=>(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 ,那么目標象素值其實應該根據這個源圖中虛擬的點四周的四個真實的點來按照一定的規律計算出來的,這樣才能達到更好的縮放效果。
2 雙線性插值
雙線型內插值算法就是一種比較好的圖像縮放算法,它充分的利用了源圖中虛擬點四周的四個真實存在的像素值來共同決定目標圖中的一個像素值,因此縮放效果比簡單的最鄰近插值要好很多。在雙線性插值方法中源圖片與目標圖片的坐標轉換關系和最近鄰一樣
雙線性內插值算法描述如下:
對於一個目的像素,設置坐標通過反向變換得到的浮點坐標為(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)
其中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也體現出了這一特點。
雙三次插值 用4*4個點賦予權重來構造 (未完待續。。。)
繼續寫
雙三次插值(也稱協調板元),二元雙三次插值公式共有(3+1)2=16個系數,其一般形式可寫成[9]:
a00 + a10x + a01y + a20x2 + a11xy + a02y2 + a21x2y + a12xy2 + a22x2y2 + a30x3 + a03y3+ a31x3y + a13xy3 + a32x3y2 + a23x2y3 + a33x3y3
或者更簡單的形式 
雙三次插值方法能夠克服雙線性插值和最鄰近插值算法的缺點。計算精度比較高,插值效果較最近鄰插值法和雙線性插值法好,但是計算量大。在圖像領域中,該方法考慮一個浮點坐標(i+u,j+v)周圍的16個鄰點,目標像素值f(i+u,j+v)可由如下插值公式得到:
f(i+u,j+v)=[A]×[B]×[C]
[A]=[S(u+1) S(u+0) S(u-1) S(u-2)]

