相位相关

时间:2010-05-14 02:34:51

标签: python correlation fft

如何通过2幅图像的相位相关(使用fft)确定旋转角度? http://en.wikipedia.org/wiki/Phase_correlation中给出的算法返回线性移位,而不是角度移位。它还提到必须将图像转换为对数极坐标以计算旋转。如何在python中实现这种转换?并且后转换执行与算法相同的步骤吗?

3 个答案:

答案 0 :(得分:4)

对数极坐标变换实际上是旋转和尺度不变。旋转对应于y轴的偏移,缩放对应于对数极坐标变换中的x轴偏移

在图像y中找到图像x的步骤如下:

  1. 在图像y中查找图像x(在笛卡尔坐标中使用相位相关)

  2. 计算x和y的对数极坐标变换(这是另一个问题,请参阅下面的参考资料),确保以两个图像中的相同特征为中心。

  3. 查找x和y的FFT,比如说F(X)和F(y)

  4. 找到F(x)和F(y)的相位相关,称之为R

  5. 找到R的IFFT(逆FFT).R的峰值对应于Y轴的旋转偏差和X轴与原始图像的缩放偏差。

  6. 参考文献:

    1. http://etd.lsu.edu/docs/available/etd-07072005-113808/unrestricted/Thunuguntla_thesis.pdf

答案 1 :(得分:2)

我一直在研究同样的问题。我在周末写了这篇文章。它不是最干净的代码,但我只是一个物理学家而不是程序员......

相位相关本身很简单:使用您最喜欢的卷积算法来卷积两个图像。峰值位置为您提供旋转/缩放差异。它在维基百科上得到了很好的解释(在问题中提到的链接中)。

我的问题是我找不到一个好的对数极化转换器,所以我写了一个。这不是万无一失的,但它完成了工作。有人愿意改写它以使其更清楚,请这样做!

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()循环行,可以轻松地对彩色图像进行处理。

编辑:现在,进行关联的代码很简单。在您的脚本导入了imagetarget两个图像后,请执行以下操作:

# 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应包含一个峰值,其坐标是大小差异和角度差异。此外,您可以简单地使用numpy的np.correlate()函数:

,而不是使用FFT
# Conversion to log-polar coordinates
lpimage = logpolar(image)
lptarget = logpolar(target)

# Correlation
correlation = np.correlate(lpimage,lptarget)

答案 2 :(得分:1)

以下是一项实施:http://www.lfd.uci.edu/~gohlke/code/imreg.py.html。我发现找到两张128x128图像之间的相似度需要0.035秒。