python - 为什么 MATLAB interp2 在非均匀间隔样本上比 SciPy 快得多?

标签 python matlab image-processing scipy interpolation

我有一个图像投影问题,在最后一步中,我需要在源图像上使用双线性插值到间隔不均匀的目标点。 MATLAB 可以很好地处理这个问题,并使用 interp2 非常快速地计算答案。 MATLAB 示例:

img = imread('ngc6543a.jpg');
img = double(rgb2gray(img)) / 256;
[img_col, img_row] = meshgrid(1:size(img, 2), 1:size(img, 1));
interp_rows = 325+200*randn(1, 100000);
interp_cols = 300*200*randn(1, 100000);

tic
img_interp = interp2(img_col, img_row, omg, interp_rows, interp_cols)
toc
>Elapsed time is 0.011680 seconds.

据我所知,在 Python 中,没有办法以几乎同样快的速度插值到非均匀采样点。所有典型的 SciPy 方法似乎都希望目标是等距点的二维网格,而不是随机散布的点。 (例如scipy.interpolate.interp2d)。在 SciPy 中执行相同的操作需要 for 循环:

from scipy.interpolate import interp2d
import numpy as np


% Does NOT interpolate to points outside the convex hull (which is good)
interpolator = interp2d(img_col, img_row, img)
interp_rows = 325+200*np.random.randn(1, 100000);
interp_cols = 300*200*np.random.randn(1, 100000);

result = np.empty((100000,), dtype=np.float)
for i in range(100000):
    result[i] = interpolator(interp_cols[i], interp_rows[i])

正如人们所期望的那样,这需要一个非常长的时间的循环。我确信一定有更好的方法。我发现的最接近的是 scipy.interpolate.RectBivariateSpline 。有了这个,我几乎可以以与 MATLAB 几乎相同的速度完成我想要的事情:

from scipy.interpolate import RectBivariateSpline

% DOES interpolate to points outside the convex hull (which is bad)
interpolator = RectBivariateSpline(img_col, img_row, img)
img_interp = interpolator(interp_cols, interp_rows, grid=False)

此方法的问题在于,它不会将源凸包之外的值设置为 NaN。它仍然插入到这些值。然后,这需要手动找到凸包并消除凸包之外的值,这很慢。

最佳答案

问题是您正在使用的 for 循环:

for i in range(100000):
    result[i] = interpolator(interp_cols[i], interp_rows[i])

在 MATLAB 代码中,您使用的是矢量化方法:

img_interp = interp2(img_col, img_row, omg, interp_rows, interp_cols)

使用 scipy 也可以实现同样的效果:

result = interpolator(interp_cols, interp_rows)

这应该会给你带来相当好的加速。

避免在 Python 中使用 for 循环。通常 Numpy/Scipy 中有一种向量化方法。

MATLAB 可能仍然稍快一些,但是当您发现计算时间可能慢 2 到 100 倍时,您在 Python 中做错了什么。

为了进行比较,您可以尝试将 for 循环添加到 MATLAB 中并查看其执行情况。

参见herehere对于想法和概念,

关于python - 为什么 MATLAB interp2 在非均匀间隔样本上比 SciPy 快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56435870/

相关文章:

arrays - 在向量存在之前用 'end' 创建索引数组

Python:如何从视差图中获得真实深度

c++ - 尝试计算 2 个图像的 FFT(快速傅立叶变换)时发生访问冲突

matlab - 通过 MatLab 计算 Blob 数量

python - 更新数据存储应用引擎中的实体

python - 属性错误 : 'CombinedExpression' object has no attribute 'default_alias'

python - Numpy fft 卡住更长的样本

c++ - 从 C++ : fail to initialize the library 调用 matlab dll

python - 当我在 python 中发送 post 请求时...我该怎么做

matlab - bwmorph 分支点如何工作?