我有
[[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8]]
,我想将其插入到旋转的网格中,该网格的左边缘有一个角。类似于:
[[2, ~2, 2],
[~4, ~4, ~4],
[6, ~6, 6]]
(我用~
表示近似值。)
(当然,我的实际数据更复杂。这种情况是我想按像素将DEM数据映射到旋转的图像上。)
这是设置:
import numpy
from scipy import interpolate as interp
grid = numpy.ndarray((5, 5))
for I in range(grid.shape[0]):
for j in range(grid.shape[1]):
grid[I, j] = I + j
grid = ndimage.interpolation.shift(
ndimage.interpolation.rotate(grid, -45, reshape=False),
-1)
source_x, source_y = numpy.meshgrid(
numpy.arange(0, 5), numpy.arange(0, 5))
target_x, target_y = numpy.meshgrid(
numpy.arange(0, 2), numpy.arange(0, 2))
print(interp.griddata(
numpy.array([source_x.ravel(), source_y.ravel()]).T,
grid.ravel(),
target_x, target_y))
这给了我
[[2.4467 2.6868 2.4467]
[4. 4. 4. ]
[5.5553 5.3132 5.5553]]
这是有希望的。但是,旋转和移位值是硬编码的,我至少应该能够精确地获得左上角。
我确实知道我想插入的网格角的索引。也就是说,我有
upper_left = 2, 0
upper_right = 0, 2
lower_right = 4, 2
lower_left = 2, 4
答案 0 :(得分:1)
内置的功能可能不足以满足您的口味,但这是一种更直接使用起点(网格角)并应用样条插值(默认为三次)的方法。
Row starttime endtime
1 06:45:00 06:50:00
2 14:45:00 14:50:00
打印:
import numpy as np
from scipy.interpolate import RectBivariateSpline
# input data
data = np.array([[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8]])
upper_left = 2, 0
upper_right = 0, 2
lower_right = 2, 4 # note that I swapped this
lower_left = 4, 2 # and this
n_steps = 3, 3
# build interpolator
m, n = data.shape
x, y = np.arange(m), np.arange(n)
interpolator = RectBivariateSpline(x, y, data)
# build grid
ul,ur,ll,lr = map(np.array, (upper_left,upper_right,lower_left,lower_right))
assert np.allclose(ul + lr, ur + ll) # make sure edges are parallel
x, y = ul[:, None, None] \
+ np.outer(ll-ul, np.linspace(0.0, 1.0, n_steps[0]))[:, :, None] \
+ np.outer(ur-ul, np.linspace(0.0, 1.0, n_steps[1]))[:, None, :]
# intepolate on grid
print(interpolator.ev(x, y))
答案 1 :(得分:0)
虽然这确实回答了我的问题,但我希望有一种更内置的处理方式。我仍在寻找更好的方法。
这实际上是两个问题:旋转原始网格,然后进行插值。旋转网格然后将其平移到正确的左上角可以使用Affine Transformation。
skimage
为此提供了easy function。
from skimage.transform import AffineTransform, warp
# Set up grid as in question
transform = AffineTransform(rotation=-math.pi / 4,
scale=(math.sqrt(2)/2, math.sqrt(2)/2),
translations=(0,2))
grid = warp(grid, transform)
结果是
[[2. 2. 2. 2. 2.]
[3. 3. 3. 3. 3.]
[4. 4. 4. 4. 4.]
[5. 5. 5. 5. 5.]
[6. 6. 6. 6. 6.]]
然后可以根据需要简单地重新采样。
通常,如果我们有一个尺寸为x和y的网格,并且坐标为p1,p2,p3,p4(从左上角开始,顺时针旋转),我们要旋转到该位置,
rotation = math.atan2(p4.x - p1.x, p4.y - p1.y)
scale = (math.sqrt((p2.y - p1.y) ** 2 + (p2.x - p1.x) ** 2) / x,
math.sqrt((p4.y - p1.y) ** 2 + (p4.x - p1.x) ** 2) / y)
translation = (0, p1.y)