如何估计非均匀图像之间的亚像素偏移 translation/rotation
How to estimate a sub-pixel shift between images with non uniform translation/rotation
我有几张完全重叠同一场景的图像。但是所有图像之间都有一个小的偏移,大约 1 像素或更小,所以是亚像素偏移。假设这是问题 (1):我如何估计 2 个图像之间的亚像素偏移(实际上,我知道如何并且我在下面编写了有关此的代码)。我这里用的是python
除了问题(1)之外,还有问题(2)是关于全图的非均匀偏移。让我们给出图像 A 和图像 B,在左上角,图像 A 在 x 和 y 轴上从图像 B 移动了大约 1px,但是在中心,图像 A 在 x 和 y 轴上也从图像 B 移动了 0.5px。图像 A 和 B 之间的偏移在图像的整个表面上并不均匀。问题是我如何估计这个非均匀偏移,让我们将它命名为偏移表面,对于所有图像的所有像素(以一个作为参考)(我也有这个问题的解决方案,我将在下面解释)。
最后,问题(3)是要用估计的偏移面(在(2)中计算)来偏移图像。例如,我知道如何将图像移动到 X 轴上的 0.5 像素和 Y 轴上的 1.2 像素。但我不知道如何为每个像素移动具有特定移位的数组。
我的解决方案:
问题(1):这个问题可以用傅里叶的互相关来解决space。 scipy 库中已经存在一个函数:register_translation
reference here,我只需要提供两个图像作为参数和我想要的浮点精度。
问题(2):请记住,图像所有表面的偏移不均匀。我所做的基本上是在 500x500 像素的 window 上,偏移是均匀的,可以很容易地从问题 (1) 中估计出来。因此,我计算了图像所有表面之间的偏移,window 为 500x500px,步长为 100px。因此,我现在估计的非均匀偏移如下所示 . I can then, interpolate a surface from this ponctual estimated shift, which will give me an estimated shift for each pixel of the image. To do that, I have to interpolate a surface with the same resolution of the image. I did it, using numpy.griddata
. Here is the result for both components (x and 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 spicy
# ... (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)
我有几张完全重叠同一场景的图像。但是所有图像之间都有一个小的偏移,大约 1 像素或更小,所以是亚像素偏移。假设这是问题 (1):我如何估计 2 个图像之间的亚像素偏移(实际上,我知道如何并且我在下面编写了有关此的代码)。我这里用的是python
除了问题(1)之外,还有问题(2)是关于全图的非均匀偏移。让我们给出图像 A 和图像 B,在左上角,图像 A 在 x 和 y 轴上从图像 B 移动了大约 1px,但是在中心,图像 A 在 x 和 y 轴上也从图像 B 移动了 0.5px。图像 A 和 B 之间的偏移在图像的整个表面上并不均匀。问题是我如何估计这个非均匀偏移,让我们将它命名为偏移表面,对于所有图像的所有像素(以一个作为参考)(我也有这个问题的解决方案,我将在下面解释)。
最后,问题(3)是要用估计的偏移面(在(2)中计算)来偏移图像。例如,我知道如何将图像移动到 X 轴上的 0.5 像素和 Y 轴上的 1.2 像素。但我不知道如何为每个像素移动具有特定移位的数组。
我的解决方案:
问题(1):这个问题可以用傅里叶的互相关来解决space。 scipy 库中已经存在一个函数:register_translation
reference here,我只需要提供两个图像作为参数和我想要的浮点精度。
问题(2):请记住,图像所有表面的偏移不均匀。我所做的基本上是在 500x500 像素的 window 上,偏移是均匀的,可以很容易地从问题 (1) 中估计出来。因此,我计算了图像所有表面之间的偏移,window 为 500x500px,步长为 100px。因此,我现在估计的非均匀偏移如下所示 numpy.griddata
. Here is the result for both components (x and 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 spicy
# ... (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)