由于这些(几乎)是二维数组,因此您需要scipy.signal.correlate2d()
功能。
首先,读取图像并转换为数组:
import numpy as np
from PIL import Image
import requests
import io
image1 = "https://i.stack.imgur.com/lf2lc.png"
image2 = "https://i.stack.imgur.com/MMSdM.png"
img1 = np.asarray(Image.open(io.BytesIO(requests.get(image1).content)))
img2 = np.asarray(Image.open(io.BytesIO(requests.get(image2).content)))
# img2 is greyscale; make it 2D by taking mean of channel values.
img2 = np.mean(img2, axis=-1)
现在我们有了两个图像,我们可以调整示例the scipy.signal.correlate2d()文档 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.correlate2d.html:
from scipy import signal
corr = signal.correlate2d(img1, img2, mode='same')
如果你想避免使用scipy
由于某种原因,那么这应该是等效的:
pad = np.max(img1.shape) // 2
fft1 = np.fft.fft2(np.pad(img1, pad))
fft2 = np.fft.fft2(np.pad(img2, pad))
prod = fft1 * fft2.conj()
result_full = np.fft.fftshift(np.fft.ifft2(prod))
corr = result_full.real[1+pad:-pad+1, 1+pad:-pad+1]
现在我们可以计算最大相关性的位置:
y, x = np.unravel_index(np.argmax(corr), corr.shape)
现在我们可以可视化结果,再次调整文档示例:
import matplotlib.pyplot as plt
y2, x2 = np.array(img2.shape) // 2
fig, (ax_img1, ax_img2, ax_corr) = plt.subplots(1, 3, figsize=(15, 5))
im = ax_img1.imshow(img1, cmap='gray')
ax_img1.set_title('img1')
ax_img2.imshow(img2, cmap='gray')
ax_img2.set_title('img2')
im = ax_corr.imshow(corr, cmap='viridis')
ax_corr.set_title('Cross-correlation')
ax_img1.plot(x, y, 'ro')
ax_img2.plot(x2, y2, 'go')
ax_corr.plot(x, y, 'ro')
fig.show()
绿点是中心img2
。红点是放置绿点给出最大相关性的位置。