给定索引的插值图像 python
Interpolate Image for given indices python
我有一张大约 8000x9000 大小的图像作为 numpy 矩阵。我还有一个 numpy 2xn 矩阵中的索引列表。这些索引是小数的,并且可能超出图像大小。我需要对图像进行插值并找到给定索引的值。如果指数落在外面,我需要为它们 return numpy.nan
。目前我在 for 循环中做如下
def interpolate_image(image: numpy.ndarray, indices: numpy.ndarray) -> numpy.ndarray:
"""
:param image:
:param indices: 2xN matrix. 1st row is dim1 (rows) indices, 2nd row is dim2 (cols) indices
:return:
"""
# Todo: Vectorize this
M, N = image.shape
num_indices = indices.shape[1]
interpolated_image = numpy.zeros((1, num_indices))
for i in range(num_indices):
x, y = indices[:, i]
if (x < 0 or x > M - 1) or (y < 0 or y > N - 1):
interpolated_image[0, i] = numpy.nan
else:
# Todo: Do Bilinear Interpolation. For now nearest neighbor is implemented
interpolated_image[0, i] = image[int(round(x)), int(round(y))]
return interpolated_image
但是 for 循环占用了大量时间(正如预期的那样)。我怎样才能矢量化这个?我找到了 scipy.interpolate.interp2d, but I'm not able to use it. Can someone explain how to use this or any other method is also fine. I also found ,但它又不符合我的要求。给定 x 和 y 索引,这些生成插值矩阵。我不想要那个。对于给定的索引,我只想要插值,即我需要一个矢量输出。不是矩阵。
我这样试过,但是如上所述,它给出了一个矩阵输出
f = interpolate.interp2d(numpy.arange(image.shape[0]), numpy.arange(image.shape[1]), image, kind='linear')
interp_image_vect = f(indices[:,0], indices[:,1])
RuntimeError: Cannot produce output of size 73156608x73156608 (size too large)
目前,我已经实现了最近邻插值。 scipy interp2d 没有最近邻。如果图书馆作为最近的邻居(这样我就可以比较),那就太好了。如果没有,那也没关系。
看起来 scipy.interpolate.RectBivariateSpline
可以解决问题:
from scipy.interpolate import RectBivariateSpline
image = # as given
indices = # as given
spline = RectBivariateSpline(numpy.arange(M), numpy.arange(N), image)
interpolated = spline(indices[0], indices[1], grid=False)
这会为您提供内插值,但不会在您需要的地方提供 nan
。你可以用 where
:
nans = numpy.zeros(interpolated.shape) + numpy.nan
x_in_bounds = (0 <= indices[0]) & (indices[0] < M)
y_in_bounds = (0 <= indices[1]) & (indices[1] < N)
bounded = numpy.where(x_in_bounds & y_in_bounds, interpolated, nans)
我用一张 2624x2624 的图像和 100,000 个点在 indices
中进行了测试,所有人都说它用了不到一秒钟。
我有一张大约 8000x9000 大小的图像作为 numpy 矩阵。我还有一个 numpy 2xn 矩阵中的索引列表。这些索引是小数的,并且可能超出图像大小。我需要对图像进行插值并找到给定索引的值。如果指数落在外面,我需要为它们 return numpy.nan
。目前我在 for 循环中做如下
def interpolate_image(image: numpy.ndarray, indices: numpy.ndarray) -> numpy.ndarray:
"""
:param image:
:param indices: 2xN matrix. 1st row is dim1 (rows) indices, 2nd row is dim2 (cols) indices
:return:
"""
# Todo: Vectorize this
M, N = image.shape
num_indices = indices.shape[1]
interpolated_image = numpy.zeros((1, num_indices))
for i in range(num_indices):
x, y = indices[:, i]
if (x < 0 or x > M - 1) or (y < 0 or y > N - 1):
interpolated_image[0, i] = numpy.nan
else:
# Todo: Do Bilinear Interpolation. For now nearest neighbor is implemented
interpolated_image[0, i] = image[int(round(x)), int(round(y))]
return interpolated_image
但是 for 循环占用了大量时间(正如预期的那样)。我怎样才能矢量化这个?我找到了 scipy.interpolate.interp2d, but I'm not able to use it. Can someone explain how to use this or any other method is also fine. I also found
我这样试过,但是如上所述,它给出了一个矩阵输出
f = interpolate.interp2d(numpy.arange(image.shape[0]), numpy.arange(image.shape[1]), image, kind='linear')
interp_image_vect = f(indices[:,0], indices[:,1])
RuntimeError: Cannot produce output of size 73156608x73156608 (size too large)
目前,我已经实现了最近邻插值。 scipy interp2d 没有最近邻。如果图书馆作为最近的邻居(这样我就可以比较),那就太好了。如果没有,那也没关系。
看起来 scipy.interpolate.RectBivariateSpline
可以解决问题:
from scipy.interpolate import RectBivariateSpline
image = # as given
indices = # as given
spline = RectBivariateSpline(numpy.arange(M), numpy.arange(N), image)
interpolated = spline(indices[0], indices[1], grid=False)
这会为您提供内插值,但不会在您需要的地方提供 nan
。你可以用 where
:
nans = numpy.zeros(interpolated.shape) + numpy.nan
x_in_bounds = (0 <= indices[0]) & (indices[0] < M)
y_in_bounds = (0 <= indices[1]) & (indices[1] < N)
bounded = numpy.where(x_in_bounds & y_in_bounds, interpolated, nans)
我用一张 2624x2624 的图像和 100,000 个点在 indices
中进行了测试,所有人都说它用了不到一秒钟。