代码之家  ›  专栏  ›  技术社区  ›  endolith

Python中基于FFT的二维卷积与相关

  •  21
  • endolith  · 技术社区  · 15 年前

    是否有一个基于FFT的二维互相关或卷积函数内置到scipy(或另一个流行的库)?

    有如下功能:

    • scipy.signal.correlate2d -“直接方法由 convolveND 将 大数据处理速度慢”
    • scipy.ndimage.correlate -“数组与给定的内核相关,使用 精确计算(即不是FFT)。
    • scipy.fftpack.convolve.convolve 我不太明白,但似乎错了

    数字阵列 correlate2d() function with an fft=True switch 但是我想numarray被折叠了 到numpy中,我找不到是否包含此函数。

    5 回复  |  直到 10 年前
        1
  •  19
  •   Community Nick Dandoulakis    7 年前

    我发现 scipy.signal.fftconvolve , as 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部分),它有一些bug,比如 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 input using 5-smooth lengths instead of powers of 2 D)。

        2
  •  6
  •   magnus    15 年前

    查看scipy.signal.fftconvolve、signal.covolve和signal.correlate(存在signal.correlate2d,但似乎返回移位数组,而不是居中)。

        3
  •  4
  •   ars    15 年前

    我想你想要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
    
        4
  •  2
  •   Vicki Laidler    15 年前

    我已经在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/

        5
  •  2
  •   keflavich    12 年前

    我编写了一个交叉相关/卷积包装器,它负责填充和命名,并包含一个简单的平滑包装器。 here . 它不是一个流行的软件包,但除了numpy(或快速fft的fftw)之外,它也没有依赖性。

    我还实现了一个FFT速度测试代码 here 以防有人感兴趣。令人惊讶的是,在我的机器上,numpy的fft比scipy快。

    编辑:将代码移动到n维版本 在这里