gpt4 book ai didi

python - 如何使用 FFT 从图像中删除重复模式

转载 作者:行者123 更新时间:2023-12-03 23:41:30 25 4
gpt4 key购买 nike

  • 我有使用一行传感器感知照片的扫描仪生成的具有重复图案(水平白线)的肤色图像。
    raw image
    raw image2
  • 我的问题 是如何使用 FFT 对图像进行有效去噪而不会对图像质量产生太大影响,有人告诉我必须手动抑制幅度谱中出现的线条,但我不知道该怎么做那个,你能告诉我怎么做吗?
  • 我的方法 是使用 快速傅立叶变换 (FFT) 逐 channel 去噪图像。
  • 我在傅立叶域中尝试过 HPF 和 LPF,但结果并不好,如您所见:

  • result
    我的代码:
    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()

    最佳答案

    这里有一个简单有效的线性过滤策略来去除水平线伪影:
    大纲:

  • 通过在垂直维度上寻找图像功率谱中的峰值来估计失真的频率。函数 scipy.signal.welch 对此很有用。
  • 设计两个滤波器:一个截止频率刚好低于失真频率的高通滤波器和一个截止频率接近 DC 的低通滤波器。我们将垂直应用高通滤波器并水平应用低通滤波器以尝试隔离失真。我们将使用 scipy.signal.firwin 来设计这些过滤器,尽管有很多方法可以做到这一点。
  • 将恢复的图像计算为“image − (hpf ⊗ lpf) ∗ image”。

  • 代码:
    # Copyright 2021 Google LLC.
    # SPDX-License-Identifier: Apache-2.0

    import numpy as np
    from scipy.ndimage import convolve1d
    from scipy.signal import firwin, welch

    def remove_lines(image, distortion_freq=None, num_taps=65, eps=0.025):
    """Removes horizontal line artifacts from scanned image.
    Args:
    image: 2D or 3D array.
    distortion_freq: Float, distortion frequency in cycles/pixel, or
    `None` to estimate from spectrum.
    num_taps: Integer, number of filter taps to use in each dimension.
    eps: Small positive param to adjust filters cutoffs (cycles/pixel).
    Returns:
    Denoised image.
    """
    image = np.asarray(image, float)
    if distortion_freq is None:
    distortion_freq = estimate_distortion_freq(image)

    hpf = firwin(num_taps, distortion_freq - eps,
    pass_zero='highpass', fs=1)
    lpf = firwin(num_taps, eps, pass_zero='lowpass', fs=1)
    return image - convolve1d(convolve1d(image, hpf, axis=0), lpf, axis=1)

    def estimate_distortion_freq(image, min_frequency=1/25):
    """Estimates distortion frequency as spectral peak in vertical dim."""
    f, pxx = welch(np.reshape(image, (len(image), -1), 'C').sum(axis=1))
    pxx[f < min_frequency] = 0.0
    return f[pxx.argmax()]
    例子:
    在人像图像上, estimate_distortion_freq 估计失真的频率为 0.1094 个周期/像素(周期为 9.14 个像素)。过滤“image − (hpf ⊗ lpf) ∗ image”的传递函数如下所示:
    Filter transfer function
    这是 remove_lines 的过滤输出:
    Filtered output on the portrait image
    在皮肤图像上, estimate_distortion_freq 估计失真的频率为 0.08333 个周期/像素(周期为 12.0 个像素)。来自 remove_lines 的过滤输出:
    Filtered output on the skin image
    在这两个示例中,大部分失真都被消除了。它并不完美:在肖像图像上,在顶部和底部边界附近仍然可以看到一些波纹,这是使用大滤波器或傅立叶方法时的典型缺陷。尽管如此,它还是对原始图像的一个很好的改进。

    关于python - 如何使用 FFT 从图像中删除重复模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65480162/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com