我正在编写一些代码,使用相位相关法a la Reddy & Chatterji 1996来恢复测试图像相对于模板的旋转、缩放和平移。我对原始测试图像进行FFT以找到比例因子和旋转角度,但我需要对旋转和缩放后的测试图像进行FFT才能获得平移信息。
现在我可以在空间域中应用旋转和缩放,然后进行FFT,但这似乎有点低效 - 是否可能直接在频率域中获得旋转/缩放后的图像的傅里叶系数?
现在我可以在空间域中应用旋转和缩放,然后进行FFT,但这似乎有点低效 - 是否可能直接在频率域中获得旋转/缩放后的图像的傅里叶系数?
编辑1: 好的,我按照user1816548的建议尝试了一下。对于90度的倍数角度,我可以得到看起来比较合理的旋转结果,但是图像的极性会发生奇怪的变化。对于不是90度的倍数角度,我的结果非常离谱。
编辑2: 我对图像进行了零填充,并在旋转时将FFT的边缘包装起来。我非常确定我正在围绕FFT的DC分量进行旋转,但是对于不是90度的倍数角度,我仍然得到奇怪的结果。
示例输出:
可执行的Numpy/Scipy代码:
import numpy as np
from scipy.misc import lena
from scipy.ndimage.interpolation import rotate,zoom
from scipy.fftpack import fft2,ifft2,fftshift,ifftshift
from matplotlib.pyplot import subplots,cm
def testFourierRotation(angle):
M = lena()
newshape = [2*dim for dim in M.shape]
M = procrustes(M,newshape)
# rotate, then take the FFT
rM = rotate(M,angle,reshape=False)
FrM = fftshift(fft2(rM))
# take the FFT, then rotate
FM = fftshift(fft2(M))
rFM = rotatecomplex(FM,angle,reshape=False)
IrFM = ifft2(ifftshift(rFM))
fig,[[ax1,ax2,ax3],[ax4,ax5,ax6]] = subplots(2,3)
ax1.imshow(M,interpolation='nearest',cmap=cm.gray)
ax1.set_title('Original')
ax2.imshow(rM,interpolation='nearest',cmap=cm.gray)
ax2.set_title('Rotated in spatial domain')
ax3.imshow(abs(IrFM),interpolation='nearest',cmap=cm.gray)
ax3.set_title('Rotated in Fourier domain')
ax4.imshow(np.log(abs(FM)),interpolation='nearest',cmap=cm.gray)
ax4.set_title('FFT')
ax5.imshow(np.log(abs(FrM)),interpolation='nearest',cmap=cm.gray)
ax5.set_title('FFT of spatially rotated image')
ax6.imshow(np.log(abs(rFM)),interpolation='nearest',cmap=cm.gray)
ax6.set_title('Rotated FFT')
fig.tight_layout()
pass
def rotatecomplex(a,angle,reshape=True):
r = rotate(a.real,angle,reshape=reshape,mode='wrap')
i = rotate(a.imag,angle,reshape=reshape,mode='wrap')
return r+1j*i
def procrustes(a,target,padval=0):
b = np.ones(target,a.dtype)*padval
aind = [slice(None,None)]*a.ndim
bind = [slice(None,None)]*a.ndim
for dd in xrange(a.ndim):
if a.shape[dd] > target[dd]:
diff = (a.shape[dd]-target[dd])/2.
aind[dd] = slice(np.floor(diff),a.shape[dd]-np.ceil(diff))
elif a.shape[dd] < target[dd]:
diff = (target[dd]-a.shape[dd])/2.
bind[dd] = slice(np.floor(diff),target[dd]-np.ceil(diff))
b[bind] = a[aind]
return b