屏蔽归一化互相关

在这个例子中,我们使用屏蔽归一化互相关来识别包含无效数据的两个相似图像之间的相对移位。

在这种情况下,不能在计算互相关之前简单地对图像进行掩码,因为掩码会影响计算。必须从互相关中去除掩码的影响,如中所述 1.

在本例中,我们注册了两个图像之间的转换。然而,其中一张图像有大约25%的像素被破坏。

1

D.Padfield,“傅里叶域中的蒙版物体配准”,IEEE图像处理论文集(2012年)。 DOI:10.1109/TIP.2011.2181402

import numpy as np
import matplotlib.pyplot as plt

from skimage import data, draw
from skimage.registration import phase_cross_correlation
from scipy import ndimage as ndi

定义图像中无效的区域。无效像素的概率为25%。这可能是由于检测器有故障,或者边缘不受平移的影响(例如,在窗口中移动对象)。有关更多示例,请参阅参考文献

image = data.camera()
shift = (-22, 13)

corrupted_pixels = np.random.choice([False, True], size=image.shape,
                                    p=[0.25, 0.75])

# The shift corresponds to the pixel offset relative to the reference image
offset_image = ndi.shift(image, shift)
offset_image *= corrupted_pixels
print(f"Known offset (row, col): {shift}")

# Determine what the mask is based on which pixels are invalid
# In this case, we know what the mask should be since we corrupted
# the pixels ourselves
mask = corrupted_pixels

detected_shift = phase_cross_correlation(image, offset_image,
                                         reference_mask=mask)

print(f"Detected pixel offset (row, col): {-detected_shift}")

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex=True, sharey=True,
                                    figsize=(8, 3))

ax1.imshow(image, cmap='gray')
ax1.set_axis_off()
ax1.set_title('Reference image')

ax2.imshow(offset_image.real, cmap='gray')
ax2.set_axis_off()
ax2.set_title('Corrupted, offset image')

ax3.imshow(mask, cmap='gray')
ax3.set_axis_off()
ax3.set_title('Masked pixels')


plt.show()
Reference image, Corrupted, offset image, Masked pixels

输出:

Known offset (row, col): (-22, 13)
Detected pixel offset (row, col): [-22.  13.]

实心面具是另一个例证。在这种情况下,我们只能看到有限的图像和偏移图像。这些图像的面具不需要相同。这个 phase_cross_correlation 函数将正确地识别应该比较图像的哪一部分。

image = data.camera()
shift = (-22, 13)

rr1, cc1 = draw.ellipse(259, 248, r_radius=125, c_radius=100,
                        shape=image.shape)

rr2, cc2 = draw.ellipse(300, 200, r_radius=110, c_radius=180,
                        shape=image.shape)

mask1 = np.zeros_like(image, dtype=bool)
mask2 = np.zeros_like(image, dtype=bool)
mask1[rr1, cc1] = True
mask2[rr2, cc2] = True

offset_image = ndi.shift(image, shift)
image *= mask1
offset_image *= mask2

print(f"Known offset (row, col): {shift}")

detected_shift = phase_cross_correlation(image, offset_image,
                                         reference_mask=mask1,
                                         moving_mask=mask2)

print(f"Detected pixel offset (row, col): {-detected_shift}")

fig = plt.figure(figsize=(8,3))
ax1 = plt.subplot(1, 2, 1)
ax2 = plt.subplot(1, 2, 2, sharex=ax1, sharey=ax1)

ax1.imshow(image, cmap='gray')
ax1.set_axis_off()
ax1.set_title('Reference image')

ax2.imshow(offset_image.real, cmap='gray')
ax2.set_axis_off()
ax2.set_title('Masked, offset image')

plt.show()
Reference image, Masked, offset image

输出:

Known offset (row, col): (-22, 13)
Detected pixel offset (row, col): [-22.  13.]

脚本的总运行时间: (0分0.886秒)

Gallery generated by Sphinx-Gallery