[英]Python: Efficiently interpolate from an irregular grid to a regular grid in 2D
我在不規則間隔的2d網格中有一些數據點,我想將這些數據點插入到常規網格中。 例如,假設源數據來自魚眼鏡頭:
不規則源網格的示例。 注意...這些僅是示例-通常,源數據也可能以不同的方式失真-但仍來自網格。
# Source Data
x_src # A (n_src_rows, n_src_cols) array of x-coordinates of points
y_src # A (n_src_rows, n_src_cols) array of y-coordinates of points
# (x_src, y_src) form an irregular grid. i.e. if you were to plot the lines connecting neighbouring points, no lines would ever cross.
f_src # A (n_src_rows, n_src_cols) array of values.
# Interpolation Points:
x_dst # An (n_dest_cols) sorted array of x-coordinates of columns in a regular grid
y_dst # An (n_dest_rows) sorted array of y-coordinates of rows in a regular grid.
# Want to calculate:
f_dst # An (n_dest_rows, n_dest_cols) array of interpolated data on the regular grid defined by x_dst, y_dst
到目前為止,我一直在使用scipy.interpolate.griddata ,並將源點展平到一維數組中,但這有點慢,因為它沒有利用源數據點的網格結構(僅目標數據點) )。 它還在不在相鄰源網格點內部的區域內插(如果源網格的邊界是凹形的,則會發生這種情況(如左圖所示)。
在SciPy / opencv或某些類似的庫中,當源數據位於不規則間隔的網格中時,是否可以有效地進行插值?
好吧,它仍然不是最佳的,因為它沒有利用已知的源數據沿網格放置的事實,但是到目前為止,我發現的最佳方法是使用SciPy的NearestNDInterpolator,該方法基於KDTree:
import scipy.interpolate
def fast_interp_irregular_grid_to_regular(
x_dst, # type: ndarray(dst_size_x) # x-values of columns in the destination image.
y_dst, # type: ndarray(dst_size_y) # y-values of rows in the destination image
x_src, # type: ndarray(src_size_y, src_sixe_x) # x-values of data points
y_src, # type: ndarray(src_size_y, src_size_x) # y-values of data points
f_src, # type: ndarray(src_size_y, src_size_x, n_dim) # values of data points.
fill_value = 0, # Value to fill in regions outside pixel hull
zero_edges = True, # Zero the edges (ensures that regions outside source grid are zero)
): # type: (...) -> array(dst_size_y, dst_size_x, n_dim) # Interpolated image
"""
Do a fast interpolation from an irregular grid to a regular grid. (When source data is on a grid we can interpolate
faster than when it consists of arbitrary points).
NOTE: Currently we do not exploit the fact that the source data is on a grid. If we were to do that, this function
could be much faster.
"""
assert zero_edges in (False, True, 'inplace')
univariate = f_src.ndim==1
if univariate:
f_src = f_src[:, None]
else:
assert f_src.ndim==3
if zero_edges:
if zero_edges is True:
f_src = f_src.copy()
f_src[[0, -1], :] = fill_value
f_src[:, [0, -1]] = fill_value
interp = scipy.interpolate.NearestNDInterpolator(
x = np.hstack([x_src.reshape(-1, 1), y_src.reshape(-1, 1)]),
y = f_src.reshape(-1, f_src.shape[-1]),
)
grid_x, grid_y = np.meshgrid(x_dst, y_dst)
z = interp((grid_x, grid_y)).reshape((len(y_dst), len(x_dst), f_src.shape[-1]))
return z
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.