Фазовая корреляция - PullRequest
5 голосов
/ 14 мая 2010

Как можно определить угол поворота с помощью фазовой корреляции (с использованием fft) двух изображений? Алгоритм, приведенный в http://en.wikipedia.org/wiki/Phase_correlation, возвращает линейное смещение, а не угловое. В нем также упоминается, что изображения должны быть преобразованы в лог-полярные координаты для вычисления вращения. Как это преобразование достигается в Python? И после конвертации сделать те же шаги алгоритма держать?

Ответы [ 3 ]

4 голосов
/ 24 мая 2010

Логарифмическое преобразование поля фактически является вращением и масштабным инвариантом.

Итак, простые шаги для нахождения изображения x в изображении y следующие:

  1. Найти изображение x на изображении y (использовать фазовую корреляцию в декартовых координатах)

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

  3. Найти БПФ x и y, скажем, F (X) и F (y)

  4. Найдите фазовую корреляцию F (x) и F (y), назовите ее R

  5. Найти IFFT (обратное БПФ) для R. Пиковое значение R соответствует отклонению вращения по оси Y и отклонению масштабирования по оси X от исходного изображения.

Ссылки:

  1. http://etd.lsu.edu/docs/available/etd-07072005-113808/unrestricted/Thunuguntla_thesis.pdf
2 голосов
/ 04 сентября 2012

Я работал над той же проблемой некоторое время. Я взял уик-энд, чтобы написать это. Это не самый чистый код, но я всего лишь физик, а не программист ...

Сама фазовая корреляция проста: используйте свой любимый алгоритм свертки для свертки двух изображений. Пиковое положение дает вам разницу вращения / масштабирования. Это хорошо объяснено в Википедии (по ссылке, указанной в вопросе).

Моя проблема была в том, что я не смог найти хороший логарифмический преобразователь, поэтому я написал один. Это не защищает от дурака, но это делает работу. Любой, кто захочет переписать его, чтобы сделать его более понятным, сделайте это!

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)
1 голос
/ 01 августа 2014

Вот реализация: http://www.lfd.uci.edu/~gohlke/code/imreg.py.html. Я обнаружил, что требуется 0,035 секунды, чтобы найти сходство между двумя изображениями 128x128.

...