对齐数组值

时间:2014-07-02 10:00:11

标签: python arrays numpy matplotlib

假设我有两个数组,两个数组的值都代表太阳的亮度。第一个阵列具有在早晨测量的值,第二个阵列具有在晚上测量的值。在实际情况下,我有大约80个阵列。我将使用matplotlib绘制图片。绘制的圆圈(在两种情况下)都是相同的大小。然而,由于地球的运动,图像的位置会有所改变,应该避免这种情况。

>>> array1
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 1, 3, 1, 0]
[0, 0, 1, 1, 2, 0]
[0, 0, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0]

>>> array2
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 1, 2, 1, 0]
[0, 0, 1, 1, 4, 0]
[0, 0, 1, 1, 1, 0]

在上面的示例中,较大的值表示较亮的点,而零值表示为黑色空间。数组总是大小相同。如何将array2中的重要值(非零)与array1中的重要值对齐?所以结果应该是这样的。

>>> array2(aligned)
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 1, 2, 1, 0]
[0, 0, 1, 1, 4, 0]
[0, 0, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0]

必须这样做才能以有意义的方式对数组进行后处理。计算平均值或总和等等。注意!找到质量中心点并相应地对齐不会起作用,因为在一天中可能会发生变化的高值。

1 个答案:

答案 0 :(得分:3)

可能导致此类数据出现问题的一个原因是图像与像素不能很好地对齐。我尝试用两个带有正方形的数组来说明我的观点:

array1:
0 0 0 0 0
0 2 2 2 0
0 2 2 2 0
0 2 2 2 0
0 0 0 0 0

array2:
0 0 0 0 0
0 1 2 2 1
0 1 2 2 1
0 1 2 2 1
0 0 0 0 0

如您所见,有限的分辨率是一个挑战,因为图像移动了0.5像素。

当然,很容易计算出这两者的COG,并且看到第一个数组是(行,列= 2,2),第二个数组是(2,2.5)。但是如果我们将第二个数组向左移动.5,我们得到:

array2_shifted:
  0   0   0   0   0
0.5 1.5 2.0 1.5 0.5
0.5 1.5 2.0 1.5 0.5
0.5 1.5 2.0 1.5 0.5
  0   0   0   0   0

所以事情开始蔓延。

当然,可能是你的阵列足够大,以便你可以在不担心子像素的情况下工作,但如果你在每个方向上只有几个或几十个像素,这可能会变得很麻烦。

其中一种方法是首先通过适当的外推法增加图像大小(例如使用图像处理程序完成; cv2模块充满了这种可能性)。然后,图像可以用单像素精度进行拟合,然后进行下采样。<​​/ p>


在任何情况下,您都需要一种方法来找出图像之间最佳匹配的位置。有很多选择。需要注意的一件重要事情是,您可能不希望将图像与第一张图像对齐,您可能希望使用参考对齐所有图像。在这种情况下,参考可以是图像中心的完美圆。然后,您只需移动所有图像以匹配此参考。

选择参考后,您需要选择一种方法,为您提供有关图像对齐的指标。有几种可能性,但您可以从这些开始:

  1. 计算图像的重心。

  2. 计算图像与参考之间的相关性。结果相关数组的最高点为您提供最佳匹配。

  3. 执行上述任一操作,但仅在对图像进行一些处理后(通常限制每端或两端的动态范围)。

  4. 我会从这样的事情开始:

    • 可能对图像进行上采样(如果分辨率较低)
    • 限制动态范围的高端(例如clipped=np.clip(image,0,max_intensity)
    • 计算重心(例如scipy.ndimage.measurements.center_of_mass(clipped)
    • 将图像转换为重心偏移

    2D阵列的翻译需要一些代码,但不应过分困难。如果您确定周围有黑色,可以使用:

    translated = np.roll(np.roll(original, deltar, axis=0), deltac, axis=1)
    

    这将最左边的像素向右滚动(反之亦然)。如果这很糟糕,那么你需要将它们归零。 (或者看看:python numpy roll with padding)。

    关于对齐程序的警告:如果图像上有强度梯度,则简单(COG,相关)会失败。因此,您可能需要查找边缘然后关联。如果您的背景非常黑,那么强度限制也会有所帮助。