Bil*_*lal 8 python filtering fft image-processing
我有由扫描仪生成的带有重复图案(水平白线)的肤色图像,该扫描仪使用一排传感器来感知照片。
我的问题是如何使用 FFT 有效地对图像进行去噪,而不会对图像质量产生太大影响,有人告诉我,我必须手动抑制幅度谱中出现的线,但我不知道该怎么做,可以请告诉我该怎么做?
我的方法是使用快速傅立叶变换(FFT)逐通道对图像进行去噪。
我尝试过傅里叶域中的 HPF 和 LPF,但结果并不好,如您所见:
我的代码:
from skimage.io import imread, imsave
from matplotlib import pyplot as plt
import numpy as np
img = imread('skin.jpg')
R = img[...,2]
G = img[...,1]
B = img[...,0]
f1 = np.fft.fft2(R)
fshift1 = np.fft.fftshift(f1)
phase_spectrumR = np.angle(fshift1)
magnitude_spectrumR = 20*np.log(np.abs(fshift1))
f2 = np.fft.fft2(G)
fshift2 = np.fft.fftshift(f2)
phase_spectrumG = np.angle(fshift2)
magnitude_spectrumG = 20*np.log(np.abs(fshift2))
f3 = np.fft.fft2(B)
fshift3 = np.fft.fftshift(f3)
phase_spectrumB = np.angle(fshift3)
magnitude_spectrumB = 20*np.log(np.abs(fshift2))
#===============================
# LPF # HPF
magR = np.zeros_like(R) # = fshift1 #
magR[magR.shape[0]//4:3*magR.shape[0]//4,
magR.shape[1]//4:3*magR.shape[1]//4] = np.abs(fshift1[magR.shape[0]//4:3*magR.shape[0]//4,
magR.shape[1]//4:3*magR.shape[1]//4]) # =0 #
resR = np.abs(np.fft.ifft2(np.fft.ifftshift(magR)))
resR = R - resR
#===============================
magnitude_spectrumR
plt.subplot(221)
plt.imshow(R, cmap='gray')
plt.title('Original')
plt.subplot(222)
plt.imshow(magnitude_spectrumR, cmap='gray')
plt.title('Magnitude Spectrum')
plt.subplot(223)
plt.imshow(phase_spectrumR, cmap='gray')
plt.title('Phase Spectrum')
plt.subplot(224)
plt.imshow(resR, cmap='gray')
plt.title('Processed')
plt.show()
Run Code Online (Sandbox Code Playgroud)
这是一个简单有效的线性滤波策略,用于消除水平线伪影:
\n大纲:
\n通过寻找图像垂直方向功率谱中的峰值来估计失真的频率。函数scipy.signal.welch对此很有用。
\n设计两个滤波器:截止频率略低于失真频率的高通滤波器和截止频率接近直流的低通滤波器。我们将垂直应用高通滤波器,水平应用低通滤波器,以尝试隔离失真。我们将使用scipy.signal.firwin来设计这些过滤器,尽管有很多方法可以做到这一点。
\n将恢复的图像计算为“image \xe2\x88\x92 (hpf \xe2\x8a\x97 lpf) \xe2\x88\x97 image”。
\n代码:
\n# Copyright 2021 Google LLC.\n# SPDX-License-Identifier: Apache-2.0\n\nimport numpy as np\nfrom scipy.ndimage import convolve1d\nfrom scipy.signal import firwin, welch\n\ndef remove_lines(image, distortion_freq=None, num_taps=65, eps=0.025):\n """Removes horizontal line artifacts from scanned image.\n Args:\n image: 2D or 3D array.\n distortion_freq: Float, distortion frequency in cycles/pixel, or\n `None` to estimate from spectrum.\n num_taps: Integer, number of filter taps to use in each dimension.\n eps: Small positive param to adjust filters cutoffs (cycles/pixel).\n Returns:\n Denoised image.\n """\n image = np.asarray(image, float)\n if distortion_freq is None:\n distortion_freq = estimate_distortion_freq(image)\n\n hpf = firwin(num_taps, distortion_freq - eps,\n pass_zero=\'highpass\', fs=1)\n lpf = firwin(num_taps, eps, pass_zero=\'lowpass\', fs=1)\n return image - convolve1d(convolve1d(image, hpf, axis=0), lpf, axis=1)\n\ndef estimate_distortion_freq(image, min_frequency=1/25):\n """Estimates distortion frequency as spectral peak in vertical dim."""\n f, pxx = welch(np.reshape(image, (len(image), -1), \'C\').sum(axis=1))\n pxx[f < min_frequency] = 0.0\n return f[pxx.argmax()]\nRun Code Online (Sandbox Code Playgroud)\n例子:
\n在肖像图像上,estimate_distortion_freq估计失真频率为 0.1094 周期/像素(9.14 像素的周期)。过滤“image \xe2\x88\x92 (hpf \xe2\x8a\x97 lpf) \xe2\x88\x97 image”的传递函数如下所示:
这是过滤后的输出remove_lines:
在皮肤图像上,estimate_distortion_freq估计失真频率为 0.08333 周期/像素(12.0 像素的周期)。过滤后的输出remove_lines:
两个例子中的失真大部分都被消除了。它并不完美:在肖像图像上,在顶部和底部边界附近仍然可以看到一些波纹,这是使用大型滤波器或傅立叶方法时的典型缺陷。尽管如此,它仍然比原始图像有了很大的改进。
\n