用scipy.ndimage频域滤波器模糊图像

426 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情

前言

scipy.ndimage 模块提供了一系列可以在频域中对图像应用低通滤波器的函数。本节中,我们通过几个示例学习其中一些滤波器的用法。

使用 fourier_gaussian() 函数

使用 scipy.ndimage 库中的 fourier_gaussian() 函数在频域中使用高斯核执行卷积操作。

(1) 首先,读取输入图像,并将其转换为灰度图像,并通过使用 FFT 获取其频域表示:

import numpy as np
import numpy.fft as fp
from skimage.io import imread
import matplotlib.pyplot as plt
from scipy import ndimage

im = imread('1.png', as_gray=True)
freq = fp.fft2(im)

(2) 接下来,使用 fourier_gaussian() 函数对图像执行模糊操作,使用两个具有不同标准差的高斯核,绘制输入、输出图像以及功率谱:

fig, axes = plt.subplots(2, 3, figsize=(20,15))
plt.subplots_adjust(0,0,1,0.95,0.05,0.05)
plt.gray() # show the filtered result in grayscale
axes[0, 0].imshow(im), axes[0, 0].set_title('Original Image', size=10)
axes[1, 0].imshow((20*np.log10( 0.1 + fp.fftshift(freq))).real.astype(int)), axes[1, 0].set_title('Original Image Spectrum', size=10)
i = 1
for sigma in [3,5]:
    convolved_freq = ndimage.fourier_gaussian(freq, sigma=sigma)
    convolved = fp.ifft2(convolved_freq).real # the imaginary part is an artifact
    axes[0, i].imshow(convolved)
    axes[0, i].set_title(r'Output with FFT Gaussian Blur, $\sigma$={}'.format(sigma), size=10)
    axes[1, i].imshow((20*np.log10( 0.1 + fp.fftshift(convolved_freq))).real.astype(int))
    axes[1, i].set_title(r'Spectrum with FFT Gaussian Blur, $\sigma$={}'.format(sigma), size=10)
    i += 1
for a in axes.ravel():
    a.axis('off')    
plt.show()

Figure_13.png

从上图中可以看出,高斯核的标准差 σσ 值越大,输出图像就会越模糊。

使用 fourier_uniform() 函数

scipy.ndimage 模块的函数 fourier_uniform() 实现了多维均匀傅立叶滤波器。频率阵列与给定尺寸的方形核的傅立叶变换相乘。接下来,我们学习如何使用 LPF (均值滤波器)模糊输入灰度图像。

(1) 首先,读取输入图像并使用 DFT 获取其频域表示:

im = imread('1.png', as_gray=True)
freq = fp.fft2(im)

(2) 然后,使用函数 fourier_uniform() 应用 10x10 方形核(由功率谱上的参数指定),以获取平滑输出:

freq_uniform = ndimage.fourier_uniform(freq, size=10)

(3) 绘制原始输入图像和模糊后的图像:

fig, (axes1, axes2) = plt.subplots(1, 2, figsize=(20,10))
plt.gray() # show the result in grayscale
im1 = fp.ifft2(freq_uniform)
axes1.imshow(im), axes1.axis('off')
axes1.set_title('Original Image', size=10)
axes2.imshow(im1.real) # the imaginary part is an artifact
axes2.axis('off')
axes2.set_title('Blurred Image with Fourier Uniform', size=10)
plt.tight_layout()
plt.show()

Figure_14.png

(4) 最后,绘制显示方形核的功率谱:

plt.figure(figsize=(10,10))
plt.imshow( (20*np.log10( 0.1 + fp.fftshift(freq_uniform))).real.astype(int))
plt.title('Frequency Spectrum with fourier uniform', size=10)
plt.show()

Figure_15.png

使用 fourier_ellipsoid() 函数

与上一小节类似,通过将方形核修改为椭圆形核,我们可以使用椭圆形核生成模糊的输出图像。

(1) 类似的,我们首先在图像的功率谱上应用函数 fourier_ellipsoid(),并使用 IDFT 在空间域中获得模糊后的输出图像:

freq_ellipsoid = ndimage.fourier_ellipsoid(freq, size=10)
im1 = fp.ifft2(freq_ellipsoid)

(2) 接下来,绘制原始输入图像和模糊后的图像:

fig, (axes1, axes2) = plt.subplots(1, 2, figsize=(20,10))
axes1.imshow(im), axes1.axis('off')
axes1.set_title('Original Image', size=10)
axes2.imshow(im1.real) # the imaginary part is an artifact
axes2.axis('off')
axes2.set_title('Blurred Image with Fourier Ellipsoid', size=10)
plt.tight_layout()
plt.show()

Figure_16.png

(3) 最后,显示应用椭圆形核后图像的频谱:

plt.figure(figsize=(10,10))
plt.imshow( (20*np.log10( 0.1 + fp.fftshift(freq_ellipsoid))).real.astype(int))
plt.title('Frequency Spectrum with Fourier ellipsoid', size=10)
plt.show()

Figure_17.png