在 meshgrid 上快速插值图像

fast interpolate image on meshgrid

我正在寻找一种在 x-y 点网格上插入 3 通道图像的快速方法。我有一个使用 map_coordinates 的功能代码。如您所见,我正在做同样的事情 3 次,我想要一种至少可以同时做 3 个通道的更快的方法。

import numpy as np
from scipy.ndimage import map_coordinates

test_img = np.random.random((128, 160, 3))
x, y = np.meshgrid(np.arange(128), np.arange(160))

# here f is a 2d -> 2d map that will return floats. In my case
# it is a function to un-fisheye a picture.
x, y = f(x,y)

def interp_img(img, x, y, order=1):
    "interpolates img on (x,y) grid"
    return np.stack([map_coordinates(img[:,:,i], np.stack([y, x]), order=order) for i in range(3)], axis=-1)

interp_img(test_img, x, y)

map_coordinates 替换为 int 类型转换(以查找像素)会更快。

def int_map(img, x, y):
    "int round reindexing of image"
    return img[y.astype(int), x.astype(int), :]

%time out_img = interp_img(aimg, xc, yc)
>> CPU times: user 398 ms, sys: 72.4 ms, total: 470 ms
   Wall time: 472 ms

%time out_img_int = int_map(aimg, xc, yc)
>> CPU times: user 54.8 ms, sys: 43.9 ms, total: 98.7 ms
   Wall time: 98.5 ms

我认为以下应该可行。 (我已将 x/y 更改为 row/col 以避免在交换轴顺序时产生混淆...)

import numpy as np
from scipy.ndimage import map_coordinates

test_img = np.random.random((128, 160, 3))
row, col, ch = np.meshgrid(
    np.arange(128), np.arange(160), np.arange(3),
    indexing='ij',
)

# here f is a 2d -> 2d map that will return floats. In my case
# it is a function to un-fisheye a picture.
row_in, col_in = f(row, col)

def interp_img(img, r, c, ch, order=1):
    "interpolates color (3-channel) img on grid"
    return map_coordinates(img, np.stack([r, c, ch]), order=order)

interp_img(test_img, row_in, col_in, ch)