Я работал над той же проблемой некоторое время. Я взял уик-энд, чтобы написать это. Это не самый чистый код, но я всего лишь физик, а не программист ...
Сама фазовая корреляция проста: используйте свой любимый алгоритм свертки для свертки двух изображений. Пиковое положение дает вам разницу вращения / масштабирования. Это хорошо объяснено в Википедии (по ссылке, указанной в вопросе).
Моя проблема была в том, что я не смог найти хороший логарифмический преобразователь, поэтому я написал один. Это не защищает от дурака, но это делает работу. Любой, кто захочет переписать его, чтобы сделать его более понятным, сделайте это!
import scipy as sp
from scipy import ndimage
from math import *
def logpolar(input,silent=False):
# This takes a numpy array and returns it in Log-Polar coordinates.
if not silent: print("Creating log-polar coordinates...")
# Create a cartesian array which will be used to compute log-polar coordinates.
coordinates = sp.mgrid[0:max(input.shape)*2,0:360]
# Compute a normalized logarithmic gradient
log_r = 10**(coordinates[0,:]/(input.shape[0]*2.)*log10(input.shape[1]))
# Create a linear gradient going from 0 to 2*Pi
angle = 2.*pi*(coordinates[1,:]/360.)
# Using scipy's map_coordinates(), we map the input array on the log-polar
# coordinate. Do not forget to center the coordinates!
if not silent: print("Interpolation...")
lpinput = ndimage.interpolation.map_coordinates(input,
(log_r*sp.cos(angle)+input.shape[0]/2.,
log_r*sp.sin(angle)+input.shape[1]/2.),
order=3,mode='constant')
# Returning log-normal...
return lpinput
Предупреждение. Этот код предназначен для изображений в оттенках серого. Его можно легко адаптировать для работы с цветными изображениями, обведя линию с map_coordinates()
на каждой отдельной цветовой рамке.
РЕДАКТИРОВАТЬ: Теперь код для корреляции прост. После того, как ваш скрипт импортирует оба изображения как image
и target
, сделайте следующее:
# Conversion to log-polar coordinates
lpimage = logpolar(image)
lptarget = logpolar(target)
# Correlation through FFTs
Fcorr = np.fft.fft2(lpimage)*np.conj(np.fft.fft2(lptarget))
correlation = np.fft.ifft2(Fcorr)
Массив correlation
должен содержать пик, координатами которого являются разность размеров и разность углов. Кроме того, вместо использования БПФ, вы можете просто использовать функцию np.correlate()
numpy:
# Conversion to log-polar coordinates
lpimage = logpolar(image)
lptarget = logpolar(target)
# Correlation
correlation = np.correlate(lpimage,lptarget)