Как обнаружить перевод изображения только с NumPy и PIL - PullRequest
0 голосов
/ 30 сентября 2019

Учитывая два изображения, мне нужно определить, есть ли сдвиг перевода между ними. Я могу использовать только numpy и PIL.

В этом посте показано, как применить перевод (x, y) с PIL, но я не нашел ничего похожего в том, как обнаружитьперевод.

Из того, что я прочитал, взаимная корреляция, кажется, является частью решения, и есть функция numpy.correlate . Однако я не знаю, как использовать выходные данные этой функции для определения горизонтальных и вертикальных координат перемещения.

первое изображение

второе изображение

1 Ответ

2 голосов
/ 01 октября 2019

Поскольку это (почти) двумерные массивы, вам нужна функция 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)

Теперь у нас есть дваизображения, мы можем адаптировать пример в документации scipy.signal.correlate2d() :

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

x2, y2 = 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. Красная точка - это позиция, в которой размещение зеленой точки дает максимальную корреляцию.

img1, img2 and correlation

...