问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

傅立叶变换在信号和图像视觉领域的应用

创作时间:
作者:
@小白创作中心

傅立叶变换在信号和图像视觉领域的应用

引用
CSDN
1.
https://blog.csdn.net/DeepAIedu/article/details/121324040

傅立叶变换是一种重要的数学工具,广泛应用于信号处理、图像处理等领域。本文将从傅立叶变换的基本原理出发,详细解释其在语音信号处理中的应用,并通过代码演示傅立叶变换在图像去噪方面的实际效果。

傅立叶变换的基本原理

傅立叶变换可以将一个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。其公式是一个连续积分函数:

公式中F(ω)为f(t)的像函数,f(t)为F(ω)的像原函数。

傅立叶变换的实际意义就是对一个指定的信号曲线,可以使用傅立叶变换的方法对其进行分解重组,其目的就是将复杂问题简单化处理,再将处理后的结果综合起来考虑。

傅立叶变换在信号领域的应用

以语音信号为例,一般我们接触到的信号是一幅基于时间序列的音频声波图,也称为时域图。声音是介质振动在听觉系统中产生的反应。声音总可以被分解为不同频率不同强度正弦波的叠加(傅里叶变换)。声音有两个基本的物理属性:频率与振幅。声音的振幅就是音量,频率的高低就是指音调,频率用赫兹(Hz)作单位。人耳只能听到20Hz到20khz范围的声音。

音频图上波峰的高低象征着声音的振幅大小,从物理角度解释,振幅就是声带偏离原来位置的大小,声带偏离原来的位置越大,则声音越大,波峰越高的地方意味着音频的振幅越高,也就是音量越大。而频率就是声带在单位时间内振动的次数,在音频图上可以看作是一个周期,频率越高,就意味着声带振动的次数越多,也就是音调越高。

直接时域上的音频图进行处理比较麻烦,所以一般会先将时域图按照不同的频率振幅分解成若干个音频和振幅不同的音频信号图。再将这些不同的信号图按照不同的振幅映射到一个平面图上,就是我们所说的频域图。

傅立叶变换对于信号的处理主要作用是将信号从时域图像转换到频域图像,其完整步骤如下:傅立叶变换(时域图→频域图)→频域图排序→去除指定频率的信号→频域图顺序还原→逆傅立叶变换(频域图→时域图)→时域图取模还原。

傅立叶变换在图像视觉领域的应用

在图像处理领域,傅立叶变换同样发挥着重要作用。我们一般所说的信号是一个一维数据,数据前后是由顺序的,而图像是一个二维(灰度图)或三维(RGB图)的数据(在代码实现中,会统一转成二维灰度图),但是无论数据是多少个维度,他们的处理步骤都是一样的,只不过具体操作细节有所变换而已,但是要明白,不管是一维数据也好,还是二维三维数据也罢,它们之间其实都是可以互相转换的。

图像低通滤波(去高频,保低频)

接下来,我们就傅立叶变换在图像领域的应用进行代码实际操作演示,我们先通过傅立叶变换对图像进行去噪操作的演示,也就是去掉一部分高频信号的操作,由于是去高频信号,留低频信号,这个操作也被称为低通滤波。

在opencv中以离散傅立叶变换(DFT)来实现图像低通滤波操作:

import numpy
import cv2
import matplotlib.pyplot as plt

# 2.OpenCV中的 DFT(Discrete Fourier Transform) 离散傅里叶变换
img = cv2.imread(".images/1.jpg")
# 0.转化为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rows, cols = gray.shape
# 1.DFT离散傅里叶变换:空域--〉频域
dft = cv2.dft(src=numpy.float32(gray), flags=cv2.DFT_COMPLEX_OUTPUT)  # src为灰度图,并且是numpy.float32类型
print(dft.shape)  # 两个通道
# 2.中心化:将低频移动到图像中心
fftshift = numpy.fft.fftshift(dft)
# 获取振幅谱(展示图片用): numpy.log()是为了将值限制在[0, 255]
magnitude_spectrum = numpy.log(cv2.magnitude(fftshift[:, :, 0], fftshift[:, :, 1]))
# 3.滤波操作之低通滤波(去高频,保低频)
mask = numpy.zeros((rows, cols, 2), dtype=numpy.uint8)
mask[(rows / 2 - 30): (rows / 2 + 30), (cols / 2 - 30): (cols / 2 + 30)] = 1
fftshift = fftshift * mask
# 4.去中心化:将低频和高频的位置还原
ifftshift = numpy.fft.ifftshift(fftshift)
# 5.逆傅里叶变换:频域--〉空域
idft = cv2.idft(ifftshift)
# 6.二维向量取模(幅值)
img_back = cv2.magnitude(idft[:, :, 0], idft[:, :, 1])
# 结合matplotlib展示多张图片
plt.figure(figsize=(10, 10))
plt.subplot(221), plt.imshow(gray, cmap="gray"), plt.title("Input Gray Image")
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap="gray"), plt.title("Magnitude Spectrum")
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(img_back, cmap="gray"), plt.title("Image after LPF")
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back), plt.title("Result in JET")  # 默认cmap='jet'
plt.xticks([]), plt.yticks([])
plt.show()

通过上面案例,我们直观地感受到了傅立叶变换在图像去噪方面的实际效果,去掉了高频信号后,无论是灰度图,还是默认色彩图,图像的轮廓都会被软化,界限变得模糊,这是由于图像的噪声以及边缘部位往往梯度变化较大,而梯度较大的地方属于高频信号,所以在去噪的同时会软化图像边缘。

图像高通滤波(去低频,保高频)

接下来我们进行一个反向操作,也就是图像高通滤波操作,即去低频信号,留高频信号,看看处理后的图像最终有什么变化。我们这次以numpy中的快速傅立叶变换为例来实现图像高通滤波操作:

import numpy
import cv2
import matplotlib.pyplot as plt

img = cv2.imread(".images/1.jpg")
# 0.转化为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rows, cols = gray.shape
print(gray.shape)
# 1.FFT快速傅里叶变换:空域--〉频域
fft = numpy.fft.fft2(gray)  # 傅里叶变换,参数为灰度图
print(fft.shape)
# 2.中心化:将低频信号移动到图像中心
fftshift = numpy.fft.fftshift(fft)
print(numpy.min(numpy.abs(fftshift)))  # 绝对最低频率信号
print(numpy.max(fftshift), numpy.min(fftshift))  # 最高频率信号,最低频率信号
# 获取振幅谱(展示图片用): numpy.log()是为了将值压缩在[0, 255]附近
magnitude_spectrum = numpy.log(numpy.abs(fftshift))
print(numpy.max(magnitude_spectrum), numpy.min(magnitude_spectrum))
# 3.滤波操作之高通滤波(去低频,保高频)
fftshift[rows / 2 - 50:rows / 2 + 50, cols / 2 - 50: cols / 2 + 50] = 0
# print(fftshift.shape)
# 4.去中心化:将剩余的低频和高频的位置还原
ifftshift = numpy.fft.ifftshift(fftshift)
# 5.逆傅里叶变换:频域--〉空域
ifft = numpy.fft.ifft2(ifftshift)
# print(ifft)
# 6.二维向量取模(幅值)
img_back = numpy.abs(ifft)
# 结合matplotlib展示多张图片
plt.figure(figsize=(10, 10))
plt.subplot(221), plt.imshow(gray, cmap="gray"), plt.title("Input Gray Image")
plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap="gray"), plt.title("Magnitude Spectrum")
plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(img_back, cmap="gray"), plt.title("Image after HPF")
plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back), plt.title("Result in JET")  # 默认cmap='jet'
plt.xticks([]), plt.yticks([])
plt.show()

图像高通滤波的效果和低通滤波效果刚好相反,从上面案例的结果来看,高通滤波的操作会使图像失去更多的背景细节部分,只保留了图像相应的轮廓界面。这是因为背景部分的图像梯度变化相对轮廓部分的梯度变化较小,图像梯度变化较小的这部分属于低频信号,去除掉这部分低频信号,会使得图像缺少过渡,边缘显得生硬,当去除过多的低频信号时,甚至会让图像变成一副边缘轮廓图。

既然我们能够通过傅立叶变换对图像进行高通滤波或低通滤波的操作,那么同样也能对图像进行指定任意频段的滤波操作,比如中通滤波就是保留图像中间指定频段的数据,去除高频数据和低频数据的操作,而阻滞滤波刚好是去除图像中间指定频段的数据,保留高频和低频数据。

傅立叶变换的类型

关于普通傅立叶变换和离散傅立叶变换、快速傅立叶变换之间的概念关系如下:

  • DTFT是离散时间傅里叶变换,用来表达连续的信号的频谱。
  • DFT是离散傅里叶变换,针对的是离散的信号和频谱DFT是DTFT变化而来,其实就是将连续时间t变成了nT。为什么要这样做呢,因为计算机是在数字环境下工作的,它不可能看见或者处理现实中连续的信号,只能够进行离散计算,在真实性上尽可能地逼近连续信号。所以DFT是为了我们能够去用工具分析信号而创造出来的,通常我们直接用DTFT的机会很少。
  • FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。在FFT中,利用WN的周期性和对称性,把一个N项序列(设N=2k,k为正整数),分为两个N/2项的子序列,每个N/2点序列的DFT变换需要(N/2)2次运算,再用N次运算把两个N/2点的DFT变换组合成一个N点的DFT变换。这样变换以后,总的运算次数就变成N+N^2/2。FFT提高了运算速度,但是,也对参与运算的样本序列作出了限制,即要求样本数为2^N点。离散傅立叶变换DFT则无上述限制。

小结:FFT快,DFT灵活,各有优点,如果满足分析要求,两者准确度相同。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号