【发布时间】:2019-10-19 12:15:45
【问题描述】:
我有一个图像投影问题,在最后一步中,我需要对源图像使用双线性插值到非均匀间隔的目标点。 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 方法似乎都希望目标也是等距点的 2D 网格,而不是点的随机分散。 (例如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。它仍然插值到这些值。然后,这需要找到凸包并手动消除凸包之外的值,这很慢。
【问题讨论】:
-
这里有很多关于 Python 比 MATLAB 慢的问题。 Python 是免费的,MATLAB 不是。您可以选择便宜或快速。
-
这根本不是真的。通常人们只是不知道如何用 Python 编写快速代码 :)
-
“这个方法的问题是它不会将源凸包之外的值设置为 NaN。它仍然会插值到这些值。”源(图像)的凸包是一个矩形(或者我错过了什么)?
-
@CrisLuengo,主要问题是我觉得我一定错过了一些东西。看来 Python 必须有一个同样快速的方法。
-
@Trilarion,在这个组成的例子中,源图像的凸包是一个矩形。不一定总是如此。此外,目标点可能在该形状之外。
标签: python matlab image-processing scipy interpolation