繁体   English   中英

Python中使用fft2的“有效”和“完整”卷积

[英]“valid” and “full” convolution using fft2 in Python

这是一个不完整的Python与FFT卷积的片段。

我想修改它以使其支持,1)有效卷积2)和完全卷积

import numpy as np
from numpy.fft import fft2, ifft2

image = np.array([[3,2,5,6,7,8],
                  [5,4,2,10,8,1]])

kernel = np.array([[4,5],
                   [1,2]])

fft_size =  # what size should I put here for,
            # 1) valid convolution
            # 2) full convolution

convolution = ifft2(fft2(image, fft_size) * fft2(kernel, fft_size))

先感谢您。

在具有长度LM一维阵列xy的情况下,你需要将FFT填充到大小为L + M - 1mode="full" 对于2维情况,将该规则应用于每个轴。

使用numpy,你可以计算二维情况下的大小

np.array(x.shape) + np.array(y.shape) - 1

要实现“有效”模式,您必须计算“完整”结果,然后切出有效部分。 对于1-d,假设L > M ,则有效数据是完整数据中心的L - M + 1元素。 同样,在2-d情况下对每个轴应用相同的规则。

例如,

import numpy as np
from numpy.fft import fft2, ifft2


def fftconvolve2d(x, y, mode="full"):
    """
    x and y must be real 2-d numpy arrays.

    mode must be "full" or "valid".
    """
    x_shape = np.array(x.shape)
    y_shape = np.array(y.shape)
    z_shape = x_shape + y_shape - 1
    z = ifft2(fft2(x, z_shape) * fft2(y, z_shape)).real

    if mode == "valid":
        # To compute a valid shape, either np.all(x_shape >= y_shape) or
        # np.all(y_shape >= x_shape).
        valid_shape = x_shape - y_shape + 1
        if np.any(valid_shape < 1):
            valid_shape = y_shape - x_shape + 1
            if np.any(valid_shape < 1):
                raise ValueError("empty result for valid shape")
        start = (z_shape - valid_shape) // 2
        end = start + valid_shape
        z = z[start[0]:end[0], start[1]:end[1]]

    return z

这是应用于示例数据的函数:

In [146]: image
Out[146]: 
array([[ 3,  2,  5,  6,  7,  8],
       [ 5,  4,  2, 10,  8,  1]])

In [147]: kernel
Out[147]: 
array([[4, 5],
       [1, 2]])

In [148]: fftconvolve2d(image, kernel, mode="full")
Out[148]: 
array([[  12.,   23.,   30.,   49.,   58.,   67.,   40.],
       [  23.,   49.,   37.,   66.,  101.,   66.,   21.],
       [   5.,   14.,   10.,   14.,   28.,   17.,    2.]])

In [149]: fftconvolve2d(image, kernel, mode="valid")
Out[149]: array([[  49.,   37.,   66.,  101.,   66.]])

可以添加更多错误检查,并且可以修改它以处理复杂数组和n维数组。 如果选择额外的填充以使FFT计算更有效,那将是很好的。 如果您完成了所有这些增强功能,最终可能会出现类似scipy.signal.fftconvolvehttps://github.com/scipy/scipy/blob/master/scipy/signal/signaltools.py#L210 )的内容:

In [152]: from scipy.signal import fftconvolve

In [153]: fftconvolve(image, kernel, mode="full")
Out[153]: 
array([[  12.,   23.,   30.,   49.,   58.,   67.,   40.],
       [  23.,   49.,   37.,   66.,  101.,   66.,   21.],
       [   5.,   14.,   10.,   14.,   28.,   17.,    2.]])

In [154]: fftconvolve(image, kernel, mode="valid")
Out[154]: array([[  49.,   37.,   66.,  101.,   66.]])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM