相位相关

发布于 2024-09-01 20:52:53 字数 248 浏览 3 评论 0原文

如何通过两幅图像的相位相关(使用 fft)确定旋转角度? http://en.wikipedia.org/wiki/Phase_correlation 中给出的算法返回线性偏移,不是有棱角的。它还提到图像必须转换为对数极坐标才能计算旋转。这个转换在python中是如何实现的呢?转换后算法的相同步骤是否成立?

How can rotation angle be determined by phase correlation(using fft) of 2 images? The algorithm given in http://en.wikipedia.org/wiki/Phase_correlation returns linear shift, not angular. It also mentions images have to be converted to log-polar coordinates to compute rotation. How is this conversion achieved in python? And post conversion do the same steps of the algorithm hold?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡忘如思 2024-09-08 20:52:53

对数极坐标变换实际上是旋转和尺度不变的。在对数极坐标变换中,旋转对应于 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 轴上的缩放偏差。

参考文献:

  1. http://etd.lsu.edu/文档/可用/etd-07072005-113808/unrestricted/Thunuguntla_thesis.pdf

Log polar transformation is actually rotation and scale invariant.. Rotation corresponds to shift in y axis and scaling corresponds to shift in x axis in log polar transformation

So simple steps are as follows for finding an image x in image y:

  1. Find image x in image y (use phase correlation in cartesian coordinates)

  2. Compute log polar transforms of both x and y (this is a whole other problem, see references below), make sure to center on the same feature in both images.

  3. Find FFT of x and y, say F(X) and F(y)

  4. Find phase correlation of F(x) and F(y), call it R

  5. Find the IFFT (inverse FFT) of R. The peak value of R corresponds to the rotation deviation in the Y Axis and to the Scaling deviation in the X Axis from the original Image.

References:

  1. http://etd.lsu.edu/docs/available/etd-07072005-113808/unrestricted/Thunuguntla_thesis.pdf
爱她像谁 2024-09-08 20:52:53

我已经研究同样的问题有一段时间了。我花了周末的时间来写这篇文章。这不是最干净的代码,但我只是一个物理学家,而不是程序员......

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

我的问题是我找不到好的对数极坐标转换器,所以我写了一个。这并不是万无一失的,但它可以完成工作。任何愿意重写它以使其更清晰的人,请这样做!

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)

I have been working on the same problem for a while. I took the week-end to write this. It's not the cleanest code there is, but I'm only a physicist, not a programmer...

The phase correlation itself is simple: use your favorite convolution algorithm to convolve two images. The peak position gives you the rotation/scaling difference. It's well explained on Wikipedia (in the link mentioned in the question).

My problem was I couldn't find a good log-polar converter, so I wrote one. It's not fool-proof, but it gets the job done. Anyone willing to rewrite it to make it clearer, please do so!

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

Warning: This code is designed for grayscale images. It can easily be adapter to work on color images by looping the line with map_coordinates() on each separate color frame.

EDIT: Now, the code to do the correlation is simple. After your script has imported both images as image and target, do the following:

# 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)

The array correlation should contain a peak which coordinates are the size difference and the angle difference. Also, instead of using FFTs, you could simply use numpy's np.correlate() function:

# Conversion to log-polar coordinates
lpimage = logpolar(image)
lptarget = logpolar(target)

# Correlation
correlation = np.correlate(lpimage,lptarget)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文