【发布时间】:2015-11-04 07:34:24
【问题描述】:
我有一个带有正弦背景的成像伪影的数据图像,我想将其移除。由于它是单频正弦波,因此傅里叶变换和带通滤波器或“陷波滤波器”(我认为我会在 +-omega 处使用高斯滤波器)似乎很自然。
在尝试这样做时,我注意到两件事:
1) 只需执行 fft 和 back,我就减少了正弦波分量,如下所示。似乎只是通过往返来对数据进行一些高通过滤?
import numpy as np
f = np.fft.fft2(img) #do the fourier transform
fshift1 = np.fft.fftshift(f) #shift the zero to the center
f_ishift = np.fft.ifftshift(fshift1) #inverse shift
img_back = np.fft.ifft2(f_ishift) #inverse fourier transform
img_back = np.abs(img_back)
这是 img_back 的图片:
也许这里的过滤对我来说已经足够了,但我对它没有那么自信,因为我对背景抑制没有很好的了解。
2) 为了更确定抑制不需要的频率,我制作了一个布尔“带通”掩码并将其应用于数据,但傅立叶变换忽略了掩码。
a = shape(fshift1)[0]
b = shape(fshift1)[1]
ro = 8
ri = 5
y,x = np.ogrid[-a/2:a/2, -b/2:b/2]
m1 = x*x + y*y >= ro*ro
m2 = x*x + y*y <= ri*ri
m3=np.dstack((m1,m2))
maskcomb =[]
for r in m3:
maskcomb.append([any(c) for c in r]) #probably not pythonic, sorry
newma = np.invert(maskcomb)
filtdat = ma.array(fshift1,mask=newma)
imshow(abs(filtdat))
f_ishift = np.fft.ifftshift(filtdat)
img_back2 = np.fft.ifft2(f_ishift)
img_back2 = np.abs(img_back2)
这里的结果和之前一样,因为 np.fft 忽略了掩码。解决方法很简单:
filtdat2 = filtdat.filled(filtdat.mean())
不幸的是,(但经过反思也不足为奇)结果如下所示:
左图是 FFT 的幅度,应用了带通滤波器。它是中心 (DC) 组件周围的暗环。相位未显示。
显然,“砖墙”过滤器不是正确的解决方案。用这个过滤器制作戒指的现象在这里得到了很好的解释:What happens when you apply a brick-wall filter to a 1D dataset.
所以现在我被困住了。也许使用一种内置的 scipy 方法会更好,但它们似乎适用于一维数据,如in this implementation of a butterworth filter。可能正确的做法是使用 fftconvolve(),就像 here to blur an image. 所做的那样我关于 fftconvolve 的问题是:它是否需要两个“图像”(图像和过滤器)都在真实空间中?我认为是的,但在示例中他们使用高斯,所以它是模棱两可的(fft(高斯)=高斯)。如果是这样,那么尝试制作真正的空间带通滤波器似乎是错误的。也许正确的策略使用 convolve2d() 与傅立叶空间图像和自制滤波器。如果是这样,你知道如何制作一个好的二维过滤器吗?
【问题讨论】:
-
试试这个:
filtdat2 = filtdat.filled(0),然后对filtdat2做 ifft。 -
是的,我可以做到这一点,它确实过滤掉了不需要的正弦波,但对数据的代价很大。这种过滤器称为“砖墙”过滤器。我创建的环中的硬边,当我做 ifft 时,会产生看起来像通风圆盘的东西。这里解释得很好:why not to apply brick-wall filters
标签: python numpy image-processing filter convolution