我正在编写一些代码来使用相位相关性来恢复测试图像相对于模板的旋转、缩放和平移,。我对原始测试图像进行 FFT,以便找到比例因子和旋转角度,但随后我需要对原始测试图像进行 FFT旋转和缩放测试图像以获得翻译。
现在我可以在空间域中应用旋转和缩放,然后进行 FFT,但这似乎有点低效 - 是否可以获得旋转/缩放图像的傅里叶系数directly在频域?
Edit 1:好的,我按照 user1816548 的建议进行了尝试。对于 90o 的倍数角度,我可以获得看起来模糊的合理旋转,尽管图像的极性有奇怪的变化。不是 90o 倍数的角度给我带来了相当滑稽的结果。
Edit 2:我对图像应用了零填充,并且在旋转图像时包裹了 FFT 的边缘。我非常确定我正在围绕 FFT 的 DC 分量旋转,但对于不是 90o 倍数的角度,我仍然得到奇怪的结果。
输出示例:
可执行的 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