2011-04-07 35 views
10

編輯:保羅已經解決了這一個下面。謝謝!Scipy插值如何調整大小/重新取樣3x3矩陣到5x5?

我想重新取樣(高檔)3x3矩陣到5x5,用interpolate.interp2d或interpolate.RectBivariateSpline(或任何工程)填充中間點。

如果有一個簡單的,現有的功能來做到這一點,我想使用它,但我還沒有找到它。例如,一個功能,將工作,如:

# upscale 2x2 to 4x4 
matrixSmall = ([[-1,8],[3,5]]) 
matrixBig = matrixSmall.resample(4,4,cubic) 

所以,如果我開始一個3×3矩陣/數組:

0,-2,0 
-2,11,-2 
0,-2,0 

我要計算一個新的5x5矩陣(「我」的意思插值值):

0, I[1,0], -2, I[3,0], 0 
I[0,1], I[1,1], I[2,1], I[3,1], I[4,1] 
-2, I[1,2], 11, I[3,2], -2 
I[0,3], I[1,3], I[2,3], I[3,3], I[4,3] 
0, I[1,4], -2, I[3,4], 0 

我一直在尋找和閱讀並嘗試各種不同的測試代碼,但我還沒有完全想通了什麼,我試圖做正確的語法。我也不確定是否需要在某些行中使用meshgrid,mgrid或linspace。

編輯:固定和工作感謝保羅

import numpy, scipy 
from scipy import interpolate 

kernelIn = numpy.array([[0,-2,0], 
      [-2,11,-2], 
      [0,-2,0]]) 

inKSize = len(kernelIn) 
outKSize = 5 

kernelOut = numpy.zeros((outKSize,outKSize),numpy.uint8) 

x = numpy.array([0,1,2]) 
y = numpy.array([0,1,2]) 

z = kernelIn 

xx = numpy.linspace(x.min(),x.max(),outKSize) 
yy = numpy.linspace(y.min(),y.max(),outKSize) 

newKernel = interpolate.RectBivariateSpline(x,y,z, kx=2,ky=2) 

kernelOut = newKernel(xx,yy) 

print kernelOut 

回答

9

只有兩個小問題:

1)你的XX,YY是x的範圍之外,Y(你可以外推,但我猜你不想)

2)您的樣本量對於kx和ky爲3(默認值)太小。將其降至2並獲得二次擬合而非立方。

import numpy, scipy 
from scipy import interpolate 

kernelIn = numpy.array([ 
    [0,-2,0], 
    [-2,11,-2], 
    [0,-2,0]]) 

inKSize = len(kernelIn) 
outKSize = 5 

kernelOut = numpy.zeros((outKSize),numpy.uint8) 

x = numpy.array([0,1,2]) 
y = numpy.array([0,1,2]) 

z = kernelIn 

xx = numpy.linspace(x.min(),x.max(),outKSize) 
yy = numpy.linspace(y.min(),y.max(),outKSize) 

newKernel = interpolate.RectBivariateSpline(x,y,z, kx=2,ky=2) 

kernelOut = newKernel(xx,yy) 

print kernelOut 
##[[ 0.  -1.5  -2.  -1.5  0. ] 
## [ -1.5  5.4375 7.75  5.4375 -1.5 ] 
## [ -2.  7.75 11.  7.75 -2. ] 
## [ -1.5  5.4375 7.75  5.4375 -1.5 ] 
## [ 0.  -1.5  -2.  -1.5  0. ]] 
+0

非常感謝您的快速解決方案!這正是我所期待的。我曾嘗試過linspace,但格式錯誤,我完全錯過了kx,ky。 – moski 2011-04-07 20:08:55

9

如果使用SciPy的了,我覺得scipy.ndimage.interpolate.zoom可以做你需要的東西:

import numpy 
import scipy.ndimage 

a = numpy.array([[0.,-2.,0.], [-2.,11.,-2.], [0.,-2.,0.]]) 
out = numpy.round(scipy.ndimage.interpolation.zoom(input=a, zoom=(5./3), order = 2),1) 

print out 
#[[ 0. -1. -2. -1. 0. ] 
# [ -1. 1.8 4.5 1.8 -1. ] 
# [ -2. 4.5 11. 4.5 -2. ] 
# [ -1. 1.8 4.5 1.8 -1. ] 
# [ 0. -1. -2. -1. 0. ]] 

這裏的「放大倍數」是5./3,因爲我們是從一個3x3的陣列將一個5x5的陣列。如果您閱讀文檔,它說您也可以爲兩個軸獨立指定縮放比例,這意味着您可以放大非矩形矩陣。默認情況下,它使用三階樣條插值,我不確定是最好的。

我在一些圖片上試了一下,效果很好。

+0

謝謝你指出。我沒有找到這個功能。我也會試試。我想知道是什麼導致了這個nd.image.interpolate.zoom和interpolate.RectBivariateSpline之間插值輸出值的顯着差異。 – moski 2011-04-07 20:55:01