相位相关
如何通过两张图片的相位相关性(使用快速傅里叶变换,简称fft)来确定旋转角度?在这个链接中提到的算法返回的是线性位移,而不是角度位移。它还提到需要将图片转换为对数极坐标才能计算旋转。那么在Python中如何进行这种转换呢?转换后,算法的步骤是否还是一样的?
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()
来轻松适配。
编辑:现在,做相关性计算的代码很简单。在你的脚本中导入了两张图片,分别命名为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
应该包含一个峰值,其坐标代表大小差异和角度差异。此外,除了使用快速傅里叶变换(FFT),你也可以直接使用numpy的np.correlate()
函数:
# Conversion to log-polar coordinates
lpimage = logpolar(image)
lptarget = logpolar(target)
# Correlation
correlation = np.correlate(lpimage,lptarget)
对数极坐标变换其实是对旋转和缩放不敏感的。旋转对应于在y轴上的移动,而缩放则对应于在x轴上的移动。
要在图像y中找到图像x,简单步骤如下:
在图像y中找到图像x(可以使用相位相关法在笛卡尔坐标系中进行)。
计算x和y的对数极坐标变换(这又是一个复杂的问题,具体可以参考下面的资料),确保在两个图像中都以相同的特征为中心。
找到x和y的快速傅里叶变换,分别记为F(X)和F(y)。
计算F(x)和F(y)的相位相关,称之为R。
找到R的逆快速傅里叶变换(IFFT)。R的峰值对应于原始图像在Y轴上的旋转偏差和在X轴上的缩放偏差。
参考资料: