在网格上快速插入图像

问题描述

我正在寻找一种在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,y)

用int强制替换map_coordinates(查找像素)的速度相当快。

def int_map(img,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,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,ch]),order=order)

interp_img(test_img,row_in,col_in,ch)