我有几张图像完全重叠同一场景。但所有图像之间都有一个小的偏移,大约 1 像素或更小,因此是子像素偏移。假设这是问题 (1):如何估计两个图像之间的子像素偏移(实际上,我知道如何进行,并且在下面编写了有关此问题的代码)。我这里用的是python。
除了问题(1)之外,还有问题(2),即整个图像上的非均匀偏移。让我们给出图像 A 和图像 B,在左上角,图像 A 在 x 和 y 轴上从图像 B 移动了大约 1 像素,但在中心,图像 A 在 x 和 y 轴上也从图像 B 移动了 0.5 像素。图像 A 和 B 之间的偏移在图像的整个表面中并不均匀。问题是我如何估计这种非均匀偏移,让我们将其命名为偏移表面,对于所有图像的所有像素(以一个作为参考)(我也有一个针对这个问题的解决方案,我将在下面解释)。
最后,问题(3)是用估计的平移面(在(2)上计算)来平移图像。例如,我知道如何将图像在 X 轴上移动到 0.5 px,在 Y 轴上移动到 1.2 px。但我不知道如何对每个像素进行特定移位的数组。
我的解决方案:
问题(1):该问题可以使用傅里叶空间中的互相关来解决。 scipy库中已经存在一个函数:
register_translation
参考这里,我只需要给出两个图像作为参数和我想要的浮点精度。
问题(2):请记住,图像的所有表面之间的移位并不均匀。我所做的基本上是,在 500x500 像素的窗口上,移位是均匀的,可以从问题 (1) 轻松估计。因此,我计算了窗口为 500x500px、步长为 100px 的图像所有表面之间的位移。因此,我现在估计的非均匀偏移如下所示。然后,我可以从这个实时估计的偏移中插入一个表面,这将为我提供图像每个像素的估计偏移。为此,我必须以与图像相同的分辨率对表面进行插值。我做到了,使用
numpy.griddata
。这是两个分量(x 和 y)的结果。因此,我估计了图像所有表面之间的非均匀偏移。
问题(3):我现在想将这种转变应用于所有图像。我不知道该怎么做。要以子像素移动图像,您可以使用
scipy.ndimage
中名为 fourier_shift
的函数,您可以在 here 找到该函数,但您只能对所有图像进行一次移动。在这里,我想对图像的每个像素进行偏移。
你们有什么想法来解决这个问题(3)吗?另外,如果您认为有一个最简单的方法来解决问题 1 和 3,它仍然很有用!作为信息,我有 7 张 16000x26000px 的图像,所以像我一样需要一些时间来解决问题(2)。
您现在需要在位置
(x + x_shift(x,y), y + y_shift(x,y))
处插入原始图像。可能 scipy.interpolate.interpn 是最有效的方法。
我认为你的代码看起来像这样(未经测试):
import numpy as np
import scipy
# ... (load data, find shifts, etc.)
input_coords = (np.arange(x_size), np.arange(y_size))
output_coords = np.column_stack((
( x_shift + input_coords[0] ).ravel(),
( y_shift + input_coords[1][None,:] ).ravel(),
))
output_image = scipy.interpolate.interpn(
input_coords,
original_image,
output_coords,
method='linear',
bounds_error=False
)