给定具有以下形状的多光谱图像:
a = np.random.random([240, 320, 30])
其中尾轴表示以下部分波长处的值:
array([395.13, 408.62, 421.63, 434.71, 435.64, 453.39, 456.88, 471.48,
484.23, 488.89, 497.88, 513.35, 521.38, 528.19, 539.76, 548.39,
557.78, 568.06, 577.64, 590.22, 598.63, 613.13, 618.87, 632.75,
637.5 , 647.47, 655.6 , 672.66, 681.88, 690.1 ])
如下所示,重新网格化整数波长处的数据的最有效方式是什么,即,不对每个单个波长进行迭代:
array([400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520,
530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 650,
660, 670, 680, 690])
2条答案
按热度按时间yrwegjxp1#
这取决于您认为合适的插值方法和物理特性。
从你所写的内容来看,我倾向于假设与波长误差相比,空间维度沿着误差可以忽略不计。如果是这样的话,N维插值可能是错误的,因为像素信息应该是独立的。相反,你需要做的是对所有像素进行一维插值。
最简单(也是最快)的插值形式是最近邻插值。现在,如果新的波长可以用
np.round(decimals=-1)
计算,则数据已经插值,您只需要更新波长值。如果新波长不是旧波长的四舍五入值,或者如果不需要或不想要最近邻插值,则需要使用不同的方法,在某些点上,这将涉及循环通过像素。
SciPy提供了
scipy.interpolate.interp1d()
,它以一种矢量化的方式(即,通过像素的循环被推到Python帧之外)完成了这一任务,并提供了各种插值方法。例如,如果
samples
是测量的波长,new_samples
包含新的波长,arr
包含最后一个轴穿过波长的堆叠图像:至少对于线性插值,可以使用更快的
np.interp()
函数,通过显式循环手动计算类似的结果:该函数不支持多维输入,但可以使用Numba:
虽然它们都得到了类似的结果(它们处理外推的方式略有不同),但时间可能不同:
r6vfmomb2#
编辑了解决方案,使其完全矢量化,没有循环。可能更多的内存密集型虽然。
注意,矢量化的版本比仅仅循环通过波长要慢。