使用傅里叶变换从图像中去除周期性噪声

信息处理 图像处理 傅里叶变换 频谱 Python
2022-02-17 13:57:23

我试图通过对记录的图像进行后处理来消除一些周期性的闪烁噪声。这些伪影的原因是相机的电子卷帘快门顺序读取每一行,当在荧光灯下(由于 50 或 60 Hz 交流电源频率)拍摄照片时,这种机制会导致图像的亮度变化。

我尝试计算图像的傅里叶变换并抑制可能导致闪烁的分量。我检查了幅度谱(如下图所示),并将直流分量周围的垂直分量设置为一个非常小的值(我保留了直流分量)。最后,我设法消除了闪烁,因为我抑制了闪烁频率,但图像也有点变形,因为我可能还抑制了一些有助于信号能量的其他频率。

原始图像及其幅度谱和滤波后的幅度谱

我想知道检测闪烁频率并仅消除/抑制该频率的更好方法是什么?在我当前的实现中,我可能会做一些根本错误的事情,所以我将不胜感激任何指导和提示。下面,我展示了我为上面解释的那种过滤得到的结果图像。您还可以在下面找到我的 Python 代码。

输入和输出图像

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('images/flicker2.jpg',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
# calculate amplitude spectrum
mag_spec = 20*np.log(np.abs(fshift))

r = f.shape[0]/2        # number of rows/2
c = f.shape[1]/2        # number of columns/2   
p = 3                         
n = 1                   # to suppress all except for the DC component       
fshift2 = np.copy(fshift)

# suppress upper part
fshift2[0:r-n , c-p:c+p] = 0.001
# suppress lower part
fshift2[r+n:r+r, c-p:c+p] = 0.001
# calculate new amplitude spectrum
mag_spec2 = 20*np.log(np.abs(fshift2))
inv_fshift = np.fft.ifftshift(fshift2)
# reconstruct image
img_recon = np.real(np.fft.ifft2(inv_fshift))

plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(mag_spec, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(mag_spec2, cmap = 'gray')
plt.title('Magnitude Spectrum after suppression'), plt.xticks([]), plt.yticks([])
plt.show()

plt.figure()
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_recon, cmap = 'gray')
plt.title('Output Image'), plt.xticks([]), plt.yticks([])
plt.show()
1个回答

只看第一张图片就告诉我你有一个非常简单的带状图案。它们实际上大部分是水平的(在空间域中)。您会在傅立叶域中看到一个明显的十字。那是因为您在该走廊中的大部分空间特征都是水平和垂直定向的。您的水平带同样显示为原点上方和下方的一对点。条带略微向右旋转,这对点也将向右旋转。

您需要擦除这些点周围的一小块区域但是如何找到它们呢?最简单的解决方案可能是获取您录制的图像,在 Paint 或类似程序中打开它,然后在实际条带上绘制纯黑色和白色条。现在对该条形模式进行 FFT,您将获得您正在寻找的两个点的确切位置。它通常不会完全是单个 FFT bin,因此您可以将高斯曲线拟合到这两个点的邻域,并使用相反的值1-gauss(x-xc,y-yc)作为频域滤波器。