首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >图像旋转和频域缩放?

图像旋转和频域缩放?
EN

Stack Overflow用户
提问于 2012-12-06 05:02:08
回答 3查看 11K关注 0票数 7

我正在编写一些代码来恢复相对于使用相位相关( A la Reddy & Chatterji 1996 )的模板的测试图像的旋转、缩放和平移。为了找到标度因子和旋转角度,我采用了原始测试图像的FFT,但是为了得到平移,我需要旋转和缩放测试图像的FFT。

现在我可以在空域应用旋转和缩放,然后采取FFT,但这似乎有点低效-它有可能直接获得频域旋转/缩放图像的傅里叶系数吗?

编辑1: OK,我按照用户1816548的建议做了一个游戏。我可以得到模糊的感觉-旋转角度是90度倍数,尽管在图像的极性发生了奇怪的变化。不是90度倍数的角度给了我相当有趣的结果。

编辑2:,我在图像上加了零填充,当我旋转它的时候,我正在包装FFT的边缘。我很确定我在旋转FFT的直流电分量,但是对于不是90度倍数的角度,我仍然得到了奇怪的结果。

示例输出:

可执行的Numpy/Scipy代码:

代码语言:javascript
运行
AI代码解释
复制
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
EN

回答 3

Stack Overflow用户

发布于 2014-09-29 14:41:57

我不知道这件事是否已经解决,但我相信我有办法解决你在第三个数字中观察到的影响的问题:

你观察到的这个奇怪的效果是由于你实际计算FFT的起源。从本质上说,快速傅立叶变换从M[0][0]阵列的第一个像素开始。然而,您定义了围绕M[size/2+1,size/2+1]的旋转,这是正确的方法,但却是错误的。傅里叶域已经从M[0][0]计算出来了!如果你现在在傅里叶域中旋转,你是围绕M[0][0]旋转,而不是围绕M[size/2+1,size/2+1]旋转。我不能完全解释这里到底发生了什么,但你得到的效果和我以前一样。为了在傅里叶域中旋转原始图像,首先必须将二维fftShift应用于原始图像M,然后计算FFT、旋转、IFFT,然后应用ifftShift。这样,图像的旋转中心和傅里叶域的中心就同步了。

AFAI记得,我们还在两个独立的数组中旋转实和虚分量,然后将它们合并。我们还对复数上的各种插值算法进行了测试,但效果不大:)。它在我们的包裹化脓性里。

然而,这可能是超级los较少,但与两个额外的移动并不是真正的快速,除非您指定一些时髦的数组索引算法。

票数 5
EN

Stack Overflow用户

发布于 2012-12-06 05:26:11

嗯,旋转和缩放图像的结果是旋转和缩放(用逆尺度)傅里叶变换。

还请注意,旋转和缩放都是线性的像素数,而FFT是O(w*logw*h*logh),所以它实际上并不昂贵。

票数 2
EN

Stack Overflow用户

发布于 2014-09-18 22:08:52

我意识到这太晚了,但我只是想在这里回答这个问题,因为我复习了我关于移位不变的基本知识。问题是,在旋转之前,您是在扩展傅里叶空间(如考虑混叠)。看看旋转图像的FT :轴向尖峰(别名)出现在没有在傅里叶旋转的IFT中的边缘。

你应该旋转,然后处理混叠。因为您正在考虑混叠(在周期=像素数处循环您的傅里叶空间),然后通过旋转丢弃这种努力,所以您将导致混叠出现在您的最终图像中。本质上,你是在展开傅立叶别名,因此把图像空间别名拉到一起.

旋转为90度旋转平稳,因为没有混叠;k空间的角点完全匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13744171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档