我有一个图像投影问题,在最后一步中,我需要在源图像上使用双线性插值法,以到达目标点的间距不均匀。 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])
正如您可能期望的那样,循环需要很长时间(strongstrong)。我相信一定有更好的方法。我找到的最接近的东西是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。它仍然插值到这些值。然后,这需要找到凸包,并手动消除该包之外的值,这很慢。
答案 0 :(得分:1)
问题是您正在使用的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中并查看其性能。