numpy - 是否有相当于 scipy.signal.deconvolve 的二维数组?

标签 numpy scipy convolution

我想用点扩散函数 (PSF) 对 2D 图像进行去卷积。我看到有一个 scipy.signal.deconvolve适用于一维数组的函数,以及 scipy.signal.fftconvolve对多维数组进行卷积。 scipy 中是否有特定的函数来解卷积 2D 数组?

我定义了一个 fftdeconvolve 函数,用除法替换 fftconvolve 中的乘积:

def fftdeconvolve(in1, in2, mode="full"):
    """Deconvolve two N-dimensional arrays using FFT. See convolve.

    """
    s1 = np.array(in1.shape)
    s2 = np.array(in2.shape)
    complex_result = (np.issubdtype(in1.dtype, np.complex) or
                      np.issubdtype(in2.dtype, np.complex))
    size = s1+s2-1

    # Always use 2**n-sized FFT
    fsize = 2**np.ceil(np.log2(size))
    IN1 = fftpack.fftn(in1,fsize)
    IN1 /= fftpack.fftn(in2,fsize)
    fslice = tuple([slice(0, int(sz)) for sz in size])
    ret = fftpack.ifftn(IN1)[fslice].copy()
    del IN1
    if not complex_result:
        ret = ret.real
    if mode == "full":
        return ret
    elif mode == "same":
        if np.product(s1,axis=0) > np.product(s2,axis=0):
            osize = s1
        else:
            osize = s2
        return _centered(ret,osize)
    elif mode == "valid":
        return _centered(ret,abs(s2-s1)+1)

但是,下面的代码在卷积和反卷积后并没有恢复原始信号:
sx, sy = 100, 100
X, Y = np.ogrid[0:sx, 0:sy]
star = stats.norm.pdf(np.sqrt((X - sx/2)**2 + (Y - sy/2)**2), 0, 4)
psf = stats.norm.pdf(np.sqrt((X - sx/2)**2 + (Y - sy/2)**2), 0, 10)

star_conv = fftconvolve(star, psf, mode="same")
star_deconv = fftdeconvolve(star_conv, psf, mode="same")

f, axes = plt.subplots(2,2)
axes[0,0].imshow(star)
axes[0,1].imshow(psf)
axes[1,0].imshow(star_conv)
axes[1,1].imshow(star_deconv)
plt.show()

生成的二维数组显示在下图中的下一行。如何使用 FFT 解卷积恢复原始信号?

enter image description here

最佳答案

这些使用 SciPy 的 fftpack 包中的 fftn、ifftn、fftshift 和 ifftshift 的函数似乎可以工作:

from scipy import fftpack

def convolve(star, psf):
    star_fft = fftpack.fftshift(fftpack.fftn(star))
    psf_fft = fftpack.fftshift(fftpack.fftn(psf))
    return fftpack.fftshift(fftpack.ifftn(fftpack.ifftshift(star_fft*psf_fft)))

def deconvolve(star, psf):
    star_fft = fftpack.fftshift(fftpack.fftn(star))
    psf_fft = fftpack.fftshift(fftpack.fftn(psf))
    return fftpack.fftshift(fftpack.ifftn(fftpack.ifftshift(star_fft/psf_fft)))

star_conv = convolve(star, psf)
star_deconv = deconvolve(star_conv, psf)

f, axes = plt.subplots(2,2)
axes[0,0].imshow(star)
axes[0,1].imshow(psf)
axes[1,0].imshow(np.real(star_conv))
axes[1,1].imshow(np.real(star_deconv))
plt.show()

左下角的图像显示了上排两个高斯函数的卷积,右下角显示了卷积效果的反向。

enter image description here

关于numpy - 是否有相当于 scipy.signal.deconvolve 的二维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17473917/

相关文章:

matlab - 非等距数据的一维高斯滤波器

python - 在 python 中导入我的 cythonized 包

python - 当我们使用列表理解时如何保持原始列表的形状?

python - 找到两条三次曲线之间的公共(public)切线

python - Python Quad 积分乘以 float

python - 加速 Python 中的列表处理

python - 在 Pandas 中折叠列和索引

python - 如何更改 numpy 文件列表的名称?

r - R中正支持函数的卷积

python - scipy.signal.convolve 给出的结果与手动计算卷积积分不同