In che modo l'angolo di rotazione può essere determinato dalla correlazione di fase (utilizzando fft) di 2 immagini? L'algoritmo indicato in http://en.wikipedia.org/wiki/Phase_correlation restituisce lo spostamento lineare, non angolare. Indica anche che le immagini devono essere convertite in coordinate log-polari per calcolare la rotazione. Come viene realizzata questa conversione in python? E la conversione post esegue gli stessi passaggi dell'algoritmo?Correlazione di fase
risposta
Log trasformazione polare è in realtà la rotazione e scala invariante .. rotazione corrisponde a spostamento dell'asse y e incrostazione è pari a spostare lungo l'asse x in log trasformazione polare
passaggi Così semplici sono i seguenti per trovare un x image immagine y:
Ricerca immagine nell'immagine x y (correlazione di fase uso in coordinate cartesiane)
Calcola log trasformate polari di xey (questo è tutto un altro problema, vedi riferimento s sotto), assicurati di centrare la stessa funzione in entrambe le immagini.
Find FFT di x ed y, dire (y) fase correlazione
Find F (X) F e F (x) e F (y), chiamano R
Trova l'IFFT (FFT inversa) di R. Il valore di picco di R corrisponde alla deviazione di rotazione nell'asse Y e alla deviazione di scala nell'asse X dall'immagine originale.
Riferimenti:
ho lavorato sullo stesso problema per un po '. Ho preso il week-end per scrivere questo. Non è il codice più pulito che ci sia, ma io sono solo un fisico, non un programmatore ...
La correlazione di fase è semplice: usa il tuo algoritmo di convoluzione preferito per convogliare due immagini. La posizione di picco ti dà la differenza di rotazione/ridimensionamento. È ben spiegato su Wikipedia (nel link citato nella domanda).
Il mio problema era che non riuscivo a trovare un buon convertitore log-polar, quindi ne ho scritto uno. Non è infallibile, ma fa il lavoro. Chiunque voglia riscriverlo per renderlo più chiaro, per favore fallo!
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
Avviso: questo codice è progettato per immagini in scala di grigi. Può essere facilmente adattato per lavorare sulle immagini a colori eseguendo il looping della linea con map_coordinates()
su ciascuna cornice a colori separata.
EDIT: Ora, il codice per eseguire la correlazione è semplice. Dopo che lo script ha importato entrambe le immagini come image
e target
, effettuare le seguenti operazioni:
# 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)
La matrice correlation
dovrebbe contenere un picco che coordinate sono la differenza di dimensioni e la differenza angolare.Inoltre, invece di usare FFT, si può semplicemente utilizzare la funzione di np.correlate()
NumPy:
# Conversion to log-polar coordinates
lpimage = logpolar(image)
lptarget = logpolar(target)
# Correlation
correlation = np.correlate(lpimage,lptarget)
Ecco un'implementazione: http://www.lfd.uci.edu/~gohlke/code/imreg.py.html. Ho trovato che ci vogliono 0,035 secondi per trovare la somiglianza tra due immagini 128x128.
puoi pubblicare il codice sorgente completo (non solo logpolar)? – mrgloom
Ci scusiamo per la risposta tardiva, ero afk per un po '... Sto correggendo la mia risposta in questo momento. – PhilMacKay
Hey Phil, ho provato a eseguire la tua funzione ma sto ricevendo un errore di runtime. Ti dispiace aiutarmi? http://stackoverflow.com/questions/16654083/ –