【问题标题】:FFT-based 2D convolution and correlation in PythonPython中基于FFT的二维卷积和相关性
【发布时间】:2010-11-09 03:55:18
【问题描述】:

scipy(或其他流行库)中是否内置了基于 FFT 的 2D 互相关或卷积函数?

有这样的功能:

  • scipy.signal.correlate2d - "convolveND 实现的直接方法将是 大数据速度慢”
  • scipy.ndimage.correlate - “数组与给定的内核相关,使用 精确计算(即不是 FFT)。”
  • scipy.fftpack.convolve.convolve,虽然不是很懂,但是好像错了

numarray 有一个correlate2d() function with an fft=True switch,但我猜 numarray 被折叠了 进入numpy,找不到是否包含这个函数。

【问题讨论】:

  • 请注意,使用精确计算(无 FFT)与说它很慢是完全一样的 :) 更准确地说,如果您有一个信号和一个大约为大小相同(如果内核比输入小得多,那么 FFT 实际上可能比直接计算慢)。
  • 理想情况下,FFT 算法会自动处理零填充以达到最佳速度。
  • 哦,您不是在谈论零填充,而是在谈论将 5x5 图像与 2000x2000 图像匹配。为什么算法不能仅仅猜测 FFT 是否会更有效,而选择哪种方式更快呢?
  • scipy 有一个 fftconvolve 函数docs.scipy.org/doc/scipy/reference/generated/…

标签: python image numpy signal-processing fft


【解决方案1】:

请注意,自 Scipy 1.4 以来就有 scipy.signal.oaconvolve,它使用 Overlap-add method

【讨论】:

    【解决方案2】:

    我找到了scipy.signal.fftconvolveas also pointed out by magnus,但当时并没有意识到它是 n 维的。由于它是内置的并产生正确的值,因此它似乎是理想的解决方案。

    来自Example of 2D Convolution

    In [1]: a = asarray([[ 1, 2, 3],
       ...:              [ 4, 5, 6],
       ...:              [ 7, 8, 9]])
    
    In [2]: b = asarray([[-1,-2,-1],
       ...:              [ 0, 0, 0],
       ...:              [ 1, 2, 1]])
    
    In [3]: scipy.signal.fftconvolve(a, b, mode = 'same')
    Out[3]: 
    array([[-13., -20., -17.],
           [-18., -24., -18.],
           [ 13.,  20.,  17.]])
    

    正确!另一方面,STSCI 版本需要一些额外的工作才能使边界正确?

    In [4]: stsci.convolve2d(a, b, fft = True)
    Out[4]: 
    array([[-12., -12., -12.],
           [-24., -24., -24.],
           [-12., -12., -12.]])
    

    (STSCI 方法还需要编译,我没有成功(我只是注释掉了非 python 部分),有一些错误,如this 并修改输入([1, 2] 变为 [[1, 2]]) 等。所以我将接受的答案更改为内置的fftconvolve() 函数。)

    当然,相关性与卷积是一回事,只是将一个输入反转:

    In [5]: a
    Out[5]: 
    array([[3, 0, 0],
           [2, 0, 0],
           [1, 0, 0]])
    
    In [6]: b
    Out[6]: 
    array([[3, 2, 1],
           [0, 0, 0],
           [0, 0, 0]])
    
    In [7]: scipy.signal.fftconvolve(a, b[::-1, ::-1])
    Out[7]: 
    array([[ 0., -0.,  0.,  0.,  0.],
           [ 0., -0.,  0.,  0.,  0.],
           [ 3.,  6.,  9.,  0.,  0.],
           [ 2.,  4.,  6.,  0.,  0.],
           [ 1.,  2.,  3.,  0.,  0.]])
    
    In [8]: scipy.signal.correlate2d(a, b)
    Out[8]: 
    array([[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [3, 6, 9, 0, 0],
           [2, 4, 6, 0, 0],
           [1, 2, 3, 0, 0]])
    

    并且the latest revision 已通过在内部使用二的幂来加速(然后我通过using real FFT for real inputusing 5-smooth lengths instead of powers of 2 加快了速度:D)。

    【讨论】:

      【解决方案3】:

      我编写了一个互相关/卷积包装器,它负责填充和 nan,并包含一个简单的平滑包装器 here。它不是一个流行的包,但除了 numpy(或 fftw 用于更快的 ffts)之外,它也没有依赖项。

      我还实现了 FFT 速度测试代码here,以防万一有人感兴趣。它显示 - 令人惊讶的是 - numpy 的 fft 比 scipy 的快,至少在我的机器上是这样。

      编辑:将代码移至 N 维版本here

      【讨论】:

        【解决方案4】:

        查看 scipy.signal.fftconvolve、signal.convolve 和 signal.correlate(有一个 signal.correlate2d 但它似乎返回一个移位数组,而不是居中)。

        【讨论】:

        • 我将我接受的答案更改为这个,如下所述stackoverflow.com/questions/1100100/…
        • 您好,只是一个不相关的查询。 correlate2d 运行 2048x2048 形状的二维数组需要多长时间?
        【解决方案5】:

        我在 scipy 中忘记了这个包的状态,但我知道我们将 ndimage 包含在 stsci_python 发布包中是为了方便我们的用户:

        http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python/current/download

        或者如果您愿意,您应该可以从存储库中提取它:

        https://www.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/ndimage/

        【讨论】:

        • 根据 SciPy 文档,它不是基于 FFT 的,正如我在问题中提到的那样。 scipy.org/SciPyPackages/Ndimage
        • convolve 包也可以从 stsci_python 存储库中获得。它包括您还提到的具有 fft=True 开关的 correlate2d 函数。 stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/convolve/lib/…
        • 哦!如果我删除对 _correlate 的引用,我可以直接导入该 python 文件。 FFT 相关性全部在 Python 中。现在我已经开始工作了。 :) 谢谢!
        • 原来 stsci 正在从 SciPy 中删除(这就是它不起作用的原因),而 stsci_python 版本现在是权威版本,所以我将其作为公认的答案。跨度>
        • 此外,一维卷积/相关不是 FFT 加速的。 :(
        【解决方案6】:

        我想你想要 scipy.stsci 包:

        http://docs.scipy.org/doc/scipy/reference/stsci.html

        In [30]: scipy.__version__
        Out[30]: '0.7.0'
        
        In [31]: from scipy.stsci.convolve import convolve2d, correlate2d
        

        【讨论】:

        • 我也看到了,但它似乎不再包含在 SciPy 中了? >>> import scipy.stsci.convolve Traceback(最近一次调用最后):文件“”,第 1 行,在 ImportError: No module named convolve
        • 嗨 - 我粘贴了上面提示的输出。你的版本是什么?
        • 显然出了点问题:pastebin.com/mdd2bc6d 不过很高兴知道它存在。
        • 奇怪。从您的 ipython 提示符中,我看到您使用的是 python 2.6。我有 python 2.5.2。我不知道为什么 scipy 每个版本会有不同的版本。也许重新安装 scipy 并查看问题是否仍然存在会更容易?
        • 它可以在我的 2.6 的 Windows 机器上运行,但不能在其他 Ubuntu 机器上运行,所以它一定是 Ubuntu 的打包问题。 bugs.launchpad.net/bugs/397217
        猜你喜欢
        • 1970-01-01
        • 2012-12-10
        • 1970-01-01
        • 2013-10-09
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多