如何利用傅立叶变换删除图像元素
傅立叶变换(图片由作者提供)
傅里叶变换概念是图像处理中众多先进主题中的一个。简单来讲,一些图像包含着用户想要除去的系统性噪声,如果这种噪音的规律性强,那么傅里叶变换这种方法就会对图像处理十分有效。在本文中,我们会知道如何进行相应的操作。
那咱们就开始吧!像往常一样,从导入所需的Python库开始。
import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage.color import rgb2hsv, rgb2gray, rgb2yuv
from skimage import color, exposure, transform
from skimage.exposure import equalize_hist
首先,我们需要加载本文将要用到的图像。
dark_image = imread('against_the_light.png')
带有深色水平线的图像
我们将使用上面的一张图像,它是在太阳直射相机时拍摄的街道图像。在这次简单的练习中,我们尝试找一种方法来消除(或至少大大弱化)后面的电源线。
灰度图像
dark_image_grey = rgb2gray(dark_image)
plt.figure(num=None, figsize=(8, 6), dpi=80)
plt.imshow(dark_image_grey, cmap='gray');
很好,从这里我们可以轻易地使用Skimage中的fft函数。
dark_image_grey_fourier = np.fft.fftshift(np.fft.fft2(dark_image_grey))
plt.figure(num=None, figsize=(8, 6), dpi=80)
plt.imshow(np.log(abs(dark_image_grey_fourier)), cmap='gray');
图像的傅里叶变换
通过观察图像,我们能看到有两个非常明显失真了。白色的垂直线和水平线分别表示的是图像中明显的水平和垂直元素。让我们看看如果遮住垂直线会发生什么。
def fourier_masker_ver(image):
f_size = 15
dark_image_grey_fourier =
np.fft.fftshift(np.fft.fft2(rgb2gray(image)))
dark_image_grey_fourier[:225, 235:240] = 1
dark_image_grey_fourier[-225:,235:240] = 1
fig, ax = plt.subplots(1,3,figsize=(15,15))
ax[0].imshow(np.log(abs(dark_image_grey_fourier)), cmap='gray')
ax[0].set_title('Masked Fourier', fontsize = f_size)
ax[1].imshow(rgb2gray(image), cmap = 'gray')
ax[1].set_title('Greyscale Image', fontsize = f_size);
ax[2].imshow(abs(np.fft.ifft2(dark_image_grey_fourier)),
cmap='gray')
ax[2].set_title('Transformed Greyscale Image',
fontsize = f_size);
fourier_masker(dark_image)
傅立叶变换垂直遮蔽图像
我们可以看到,水平电源线的尺寸已经明显缩小。通过这个有趣的实验,让我们看看如果把水平线屏蔽会发生什么。
def fourier_masker_hor(image):
f_size = 15
dark_image_grey_fourier =
np.fft.fftshift(np.fft.fft2(rgb2gray(image)))
dark_image_grey_fourier[235:240, :230] = 1
dark_image_grey_fourier[235:240,-230:] = 1
fig, ax = plt.subplots(1,3,figsize=(15,15))
ax[0].imshow(np.log(abs(dark_image_grey_fourier)), cmap='gray')
ax[0].set_title('Masked Fourier', fontsize = f_size)
ax[1].imshow(rgb2gray(image), cmap = 'gray')
ax[1].set_title('Greyscale Image', fontsize = f_size);
ax[2].imshow(abs(np.fft.ifft2(dark_image_grey_fourier)),
cmap='gray')
ax[2].set_title('Transformed Greyscale Image',
fontsize = f_size);
fourier_masker_hor(dark_image)
傅立叶变换水平版图像
我们还能看到,图像中所有垂直的线都被模糊处理了,特别是电杆上看起来非常明显。虽然在某些情况下这种设置是有帮助的,但在这里显然作用不大。
尽管我们将坚持屏蔽傅里叶变换的垂直线(记住,当转换回原始图像时,水平线也会变得模糊),下面,我们可以尝试一下不同程度上的屏蔽。
def fourier_iterator(image, value_list):
for i in value_list:
fourier_masker_ver(image, i)
fourier_iterator(dark_image, [0.001, 1, 100])
屏蔽值的迭代
我们发现,降低这个值对原始图像几乎没有影响,但是增加这个值似乎会使原图像变暗。由于设定的较小值几乎和1没有区别,为了方便起见,我们先坚持设定数值为1。
最后,让我们在保留原始图像颜色的同时,进行傅里叶变换调整。
def fourier_transform_rgb(image):
f_size = 25
transformed_channels = []
for i in range(3):
rgb_fft = np.fft.fftshift(np.fft.fft2((image[:, :, i])))
rgb_fft[:225, 235:237] = 1
rgb_fft[-225:,235:237] = 1
transformed_channels.append(abs(np.fft.ifft2(rgb_fft)))
final_image = np.dstack([transformed_channels[0].astype(int),
transformed_channels[1].astype(int),
transformed_channels[2].astype(int)])
fig, ax = plt.subplots(1, 2, figsize=(17,12))
ax[0].imshow(image)
ax[0].set_title('Original Image', fontsize = f_size)
ax[0].set_axis_off()
ax[1].imshow(final_image)
ax[1].set_title('Transformed Image', fontsize = f_size)
ax[1].set_axis_off()
fig.tight_layout()
傅里叶变换的彩色图像
这样看起来水平电源线已经被大大减少,而图像的其他部分则基本保持原样。这很好地展示了我们时如何通过傅里叶变换对图像进行微妙改变的。
总结
傅立叶变换是一个很强大的工具,是负责处理图像的数据科学家的得力助手。在未来的文章中,我们将讨论如何深度应用这一技术。现在,我希望你能基本掌握本篇文章所介绍的内容。
原文作者 Tonichi Edeza
原文链接https://towardsdatascience.com/image-processing-with-python-application-of-fourier-transformation-5a8584dc175b