0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用Numpy和OpenCV实现傅里叶和逆傅里叶变换

新机器视觉 来源:CSDN 作者:暴风雨中的白杨 2022-07-05 16:04 次阅读

文章从实际出发,讲述了什么是傅里叶变换,它的理论基础以及Numpy和OpenCV实现傅里叶和逆傅里叶变换,并最终用高通滤波和低通滤波的示例。

1. 什么是傅里叶变换及其基础理论

1.1傅里叶变换

图像处理一般分为直接对图像内的像素进行处理的空间域处理和频率域处理。

空间域处理主要划分为灰度变换和空间滤波两种形式。

灰度变换是对图像内的单个像素进行处理,比如调节对比度和处理阈值等。

空间滤波涉及图像质量的改变,例如图像平滑处理。空间域处理的计算简单方便,运算速度更快。

频率域处理是先将图像变换到频率域,然后在频率域对图像进行处理,最后再通过反变换将图像从频率域变换到空间域。

1.2基础理论

时间差,在傅里叶变换里就是相位。相位表述的是与时间差相关的信息

在图像处理过程中,傅里叶变换就是将图像分解为正弦分量和余弦分量两部分,即将图像从空间域转换到频域。

数字图像经过傅里叶变换后,得到的频域值是复数。因此,显示傅里叶变换的结果需要使用实数图像(real image)加虚数图像(complex image),或者幅度图像(magnitude image)加相位图像(phase image)的形式。因为幅度图像包含了原图像中我们所需要的大部分信息,所以在图像处理过程中,通常仅使用幅度图像。

如果希望先在频域内对图像进行处理,再通过逆傅里叶变换得到修改后的空域图像,就必须同时保留幅度图像和相位图像。对图像进行傅里叶变换后,会得到图像中的低频和高频信息。低频信息对应图像内变化缓慢的灰度分量。高频信息对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。

傅里叶变换的目的,就是为了将图像从空域转换到频域,并在频域内实现对图像内特定对象的处理,然后再对经过处理的频域图像进行逆傅里叶变换得到空域图像。

2. Numpy实现傅里叶和逆傅里叶变换

2.1Numpy实现傅里叶变换

Numpy模块中的fft2()函数可以实现图像的傅里叶变换。

Numpy提供的实现傅里叶变换的函数是numpy.fft.fft2(),它的语法格式是:

返回值 = numpy.fft.fft2(原始图像)

参数“原始图像”的类型是灰度图像,函数的返回值是一个复数数组(complex ndarray)。经过该函数的处理,就能得到图像的频谱信息。此时,图像频谱中的零频率分量位于频谱图像(频域图像)的左上角。

为了便于观察,通常会使用numpy.fft.fftshift()函数将零频率成分移动到频域图像的中心位置。函数numpy.fft.fftshift()的语法格式是:

返回值=numpy.fft.fftshift(原始频谱)

为了显示为图像,需要将它们的值调整到[0, 255]的灰度空间内,使用的公式为:

像素新值=20*np.log(np.abs(频谱值))

用Numpy实现傅里叶变换,观察得到的频谱图像

import cv2 import numpy as np import matplotlib.pyplot as plt
img=cv2.imread('./img/hand1.png',0)f = np.fft.fft2(img) fshift = np.fft.fftshift(f) magnitude_spectrum = 20*np.log(np.abs(fshift)) plt.subplot(121) plt.imshow(img, cmap = 'gray') plt.title('original') plt.axis('off') plt.subplot(122) plt.imshow(magnitude_spectrum, cmap = 'gray') plt.title('result') plt.axis('off') plt.show()

2.2 实现逆傅里叶变换

注意: 如果在傅里叶变换过程中使用了numpy.fft.fftshift()函数移动零频率分量,那么在逆傅里叶变换过程中,需要先使用numpy.fft.ifftshift()函数将零频率分量移到原来的位置,再进行逆傅里叶变换

函数numpy.fft.ifftshift()是numpy.fft.fftshift()的逆函数,其语法格式为:

调整后的频谱 = numpy.fft.ifftshift(原始频谱)

numpy.fft.ifft2()函数可以实现逆傅里叶变换,返回空域复数数组。

它是numpy.fft.fft2()的逆函数,该函数的语法格式为:

返回值=numpy.fft.ifft2(频域数据)

函数numpy.fft.ifft2()的返回值仍旧是一个复数数组(complex ndarray)。

逆傅里叶变换得到的空域信息是一个复数数组,需要将该信息调整至[0, 255]灰度空间内,使用的公式为:

iimg = np.abs(逆傅里叶变换结果)

在Numpy内实现傅里叶变换、逆傅里叶变换,观察逆傅里叶变换的结果图像。

import cv2 import numpy as np import matplotlib.pyplot as plt
img = cv2.imread('./img/hand1.png',0) f = np.fft.fft2(img) fshift = np.fft.fftshift(f)
ishift = np.fft.ifftshift(fshift) iimg = np.fft.ifft2(ishift) 
iimg = np.abs(iimg)  plt.subplot(121), plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122), plt.imshow(iimg, cmap = 'gray') plt.title('iimg'), plt.axis('off') plt.show()

2.3高通滤波示例

一幅图像内,同时存在着高频信号和低频信号。

低频信号对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频信号对应着颜色趋于一致的广袤草原。高频信号对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。如果在上面的大草原图像中还有一头狮子,那么高频信号就对应着狮子的边缘等信息。

滤波器能够允许一定频率的分量通过或者拒绝其通过,按照其作用方式可以划分为低通滤波器和高通滤波器。

允许低频信号通过的滤波器称为低通滤波器。低通滤波器使高频信号衰减而对低频信号放行,会使图像变模糊。允许高频信号通过的滤波器称为高通滤波器。高通滤波器使低频信号衰减而让高频信号通过,将增强图像中尖锐的细节,但是会导致图像的对比度降低。

傅里叶变换可以将图像的高频信号和低频信号分离。通过对图像的频域处理,可以实现图像增强、图像去噪、边缘检测、特征提取、压缩和加密等操作。

在Numpy内对图像进行傅里叶变换,得到其频域图像。然后,在频域内将低频分量的值处理为0,实现高通滤波。最后,对图像进行逆傅里叶变换,得到恢复的原始图像。

import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('./img/hand1.png',0) f = np.fft.fft2(img) fshift = np.fft.fftshift(f) rows, cols = img.shape crow, ccol = int(rows/2) , int(cols/2) fshift[crow-30:crow+30, ccol-30:ccol+30] = 0 ishift = np.fft.ifftshift(fshift) iimg = np.fft.ifft2(ishift) iimg = np.abs(iimg) plt.subplot(121), plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122), plt.imshow(iimg, cmap = 'gray') plt.title('iimg'), plt.axis('off') plt.show()

3.OpenCV实现傅里叶和逆傅里叶变换及低通滤波示例

3.1 OpenCV实现傅里叶变换

OpenCV提供了函数cv2.dft()和cv2.idft()来实现傅里叶变换和逆傅里叶变换

函数cv2.dft()的语法格式为:

返回结果=cv2.dft(原始图像,转换标识)

在使用该函数时,需要注意参数的使用规范:对于参数“原始图像”,要首先使用np.float32()函数将图像转换成np.float32格式。“转换标识”的值通常为“cv2.DFT_COMPLEX_OUTPUT”,用来输出一个复数阵列。

函数cv2.dft()返回的结果与使用Numpy进行傅里叶变换得到的结果是一致的,但是它返回的值是双通道的,第1个通道是结果的实数部分,第2个通道是结果的虚数部分。

经过函数cv2.dft()的变换后,得到了原始图像的频谱信息。此时,零频率分量并不在中心位置,为了处理方便需要将其移至中心位置,可以用函数numpy.fft.fftshift()实现。

例如,如下语句将频谱图像dft中的零频率分量移到频谱中心,得到了零频率分量位于中心的频谱图像dftshift。

dftShift = np.fft.fftshift(dft)

经过上述处理后,频谱图像还只是一个由实部和虚部构成的值。要将其显示出来,还要做进一步的处理才行。

函数cv2.magnitude()可以计算频谱信息的幅度。该函数的语法格式为:

返回值=cv2.magnitude(参数1,参数2)

参数1:浮点型x坐标值,也就是实部。参数2:浮点型y坐标值,也就是虚部,它必须和参数1具有相同的size

函数cv2.magnitude()的返回值是参数1和参数2的平方和的平方根,公式为:

得到频谱信息的幅度后,通常还要对幅度值做进一步的转换,以便将频谱信息以图像的形式展示出来。简单来说,就是需要将幅度值映射到灰度图像的灰度空间[0, 255]内,使其以灰度图像的形式显示出来。

这里使用的公式为:

result = 20*np.log(cv2.magnitude(实部,虚部))
import numpy as np import cv2 img = cv2.imread('./img/hand1.png',0) dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) print(dft) dftShift = np.fft.fftshift(dft) print(dftShift) result = 20*np.log(cv2.magnitude(dftShift[:, :,0], dftShift[:, :,1])) #两个参数,需要拆分通道print(result)
用OpenCV函数对图像进行傅里叶变换,并展示其频谱信息。
import numpy as np import cv2 import matplotlib.pyplot as plt
img=cv2.imread('./img/hand1.png',0)dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) dftShift = np.fft.fftshift(dft) result = 20*np.log(cv2.magnitude(dftShift[:, :,0], dftShift[:, :,1])) plt.subplot(121), plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122), plt.imshow(result, cmap = 'gray') plt.title('result'), plt.axis('off') plt.show()

3.2实现逆傅里叶变换

在OpenCV中,使用函数cv2.idft()实现逆傅里叶变换,该函数是傅里叶变换函数cv2.dft()的逆函数。其语法格式为:

返回结果=cv2.idft(原始数据)

对图像进行傅里叶变换后,通常会将零频率分量移至频谱图像的中心位置。如果使用函数numpy.fft.fftshift()移动了零频率分量,那么在进行逆傅里叶变换前,要使用函数numpy.fft.ifftshift()将零频率分量恢复到原来位置。

注意: 在进行逆傅里叶变换后,得到的值仍旧是复数,需要使用函数cv2.magnitude()计算其幅度。

用OpenCV函数对图像进行傅里叶变换、逆傅里叶变换,并展示原始图像及经过逆傅里叶变换后得到的图像。

import numpy as np import cv2 import matplotlib.pyplot as plt
img=cv2.imread('./img/hand1.png',0)dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) dftShift = np.fft.fftshift(dft)
ishift=np.fft.ifftshift(dftShift)iImg = cv2.idft(ishift) iImg= cv2.magnitude(iImg[:, :,0], iImg[:, :,1]) # 计算幅度plt.subplot(121), plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122), plt.imshow(iImg, cmap = 'gray') plt.title('inverse'), plt.axis('off') plt.show()

3.3低通滤波示例

在一幅图像内,低频信号对应图像内变化缓慢的灰度分量。图像进行低通滤波后会变模糊

实现的中间步骤

rows, cols = img.shape crow, ccol = int(rows/2) , int(cols/2) mask = np.zeros((rows, cols,2), np.uint8) # 二维的原因,有实部和虚部 mask[crow-30:crow+30, ccol-30:ccol+30,:] = 1

然后,将其与频谱图像进行运算,实现低通滤波。这里采用的运算形式是:

fShift = dftShift*mask

使用函数cv2.dft()对图像进行傅里叶变换,得到其频谱图像。然后,在频域内将其高频分量的值处理为0,实现低通滤波。最后,对图像进行逆傅里叶变换,得到恢复的原始图像。

import numpy as np import cv2 import matplotlib.pyplot as plt img = cv2.imread('./img/hand1.png',0) dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) dftShift = np.fft.fftshift(dft)
rows, cols = img.shape crow, ccol = int(rows/2) , int(cols/2) mask = np.zeros((rows, cols,2), np.uint8) #两个通道,与频域图像匹配 mask[crow-30:crow+30, ccol-30:ccol+30,:] = 1 fShift = dftShift*mask ishift = np.fft.ifftshift(fShift) iImg = cv2.idft(ishift) iImg= cv2.magnitude(iImg[:, :,0], iImg[:, :,1])
plt.subplot(121), plt.imshow(img, cmap = 'gray') plt.title('original'), plt.axis('off') plt.subplot(122), plt.imshow(iImg, cmap = 'gray') plt.title('inverse'), plt.axis('off') plt.show()
经过低通滤波后,图像的边缘信息被削弱了。

审核编辑:郭婷


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 滤波
    +关注

    关注

    10

    文章

    662

    浏览量

    56592
  • 频率
    +关注

    关注

    4

    文章

    1441

    浏览量

    59147

原文标题:图像处理:使用Numpy和OpenCV实现傅里叶和逆傅里叶变换

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    傅里叶变换的基本性质和定理

    傅里叶变换是信号处理和分析中的一项基本工具,它能够将一个信号从时间域(或空间域)转换到频率域。以下是傅里叶变换的基本性质和定理: 一、基本性质 线性性质 : 傅里叶变换是线性的,即对于信号的线性组合
    的头像 发表于 11-14 09:39 198次阅读

    经典傅里叶变换与快速傅里叶变换的区别

    经典傅里叶变换与快速傅里叶变换(FFT)在多个方面存在显著的区别,以下是对这两者的比较: 一、定义与基本原理 经典傅里叶变换 : 是一种将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数
    的头像 发表于 11-14 09:37 137次阅读

    如何实现离散傅里叶变换

    离散傅里叶变换(DFT)是将离散时序信号从时间域变换到频率域的数学工具,其实现方法有多种,以下介绍几种常见的实现方案: 一、直接计算法 直接依据离散
    的头像 发表于 11-14 09:35 139次阅读

    傅里叶变换与图像处理技术的区别

    )转换到频域的数学工具。它基于级数的概念,即任何周期函数都可以表示为不同频率的正弦波和余弦波的叠加。对于非周期信号,傅里叶变换提供了一种将信号分解为不同频率成分的方法。 在图像处
    的头像 发表于 11-14 09:30 208次阅读

    傅里叶变换在信号处理中的应用

    的数学方法。它基于级数的概念,即任何周期函数都可以表示为正弦和余弦函数的和。对于非周期信号,傅里叶变换提供了一种将信号分解为不同频率成分的方法。 应用1:频谱分析 频谱分析是
    的头像 发表于 11-14 09:29 294次阅读

    傅里叶变换的数学原理

    傅里叶变换的数学原理主要基于一种将函数分解为正弦和余弦函数(或复指数函数)的线性组合的思想。以下是对傅里叶变换数学原理的介绍: 一、基本原理
    的头像 发表于 11-14 09:27 207次阅读

    傅里叶变换红外光谱仪技术在光伏材料性能表征中的应用与优化

    傅里叶变换红外光谱仪在光伏领域应用广泛。美能FTIR4000红外光谱仪利用迈克尔逊干涉仪技术,将光源转化为干涉光并照射样品,通过傅里叶变换
    的头像 发表于 06-08 08:33 443次阅读
    <b class='flag-5'>傅里叶变换</b>红外光谱仪技术在光伏材料性能表征中的应用与优化

    一文道破傅里叶变换的本质,优缺点一目了然

    变换的公式为: 下面从公式分析下变换的意义:
    发表于 03-12 16:06

    傅里叶变换的应用 傅里叶变换的性质公式

    傅里叶变换(Fourier Transform)是一种数学方法,可以将一个函数在时间或空间域中的表示转化为频率域中的表示。它是由法国数学家约瑟夫·(Jean-Baptiste J
    的头像 发表于 02-02 10:36 1198次阅读

    红外光谱仪的用途 红外光谱仪的工作原理及基本结构

    或发射来获得样品的红外光谱信息,以分析样品的成分和结构。光谱仪具有高分辨率、高灵敏度、宽波长范围和量化能力强等优势,在科学研究、工业控制和生产监测等领域发挥着重要作用。
    的头像 发表于 02-01 13:43 2075次阅读

    一种基于扩散模型的单像素成像高分辨率迭代重建方法

    单像素成像(FSPI)是一种基于分析理论的计算光学成像技术。
    的头像 发表于 01-24 09:43 991次阅读
    一种基于扩散模型的<b class='flag-5'>傅</b><b class='flag-5'>里</b><b class='flag-5'>叶</b>单像素成像高分辨率迭代重建方法

    快速傅里叶变换-FFT分析仪基础知识

    FFT频谱分析仪的概念是围绕快速傅里叶变换建立的,该变换基于约瑟夫·(Joseph Fourier,1768-1830)开发的
    发表于 01-16 14:26 1133次阅读

    什么是傅里叶变换和逆变换?为什么要用傅里叶变换?

    傅里叶变换和逆变换是一对数学变换,用于分析信号和数据的频域特征。傅里叶变换将一个信号或函数从时间域转换到频域,而逆变换则将
    的头像 发表于 01-11 17:19 3632次阅读

    短时傅里叶变换STFT原理详解

    传统傅里叶变换的分析方法大家已经非常熟悉了,特别是快速傅里叶变换(FFT)的高效实现给数字信号处理技术的实时应用创造了条件,从而加速了数字信号处理技术的发展。
    的头像 发表于 01-07 09:46 2681次阅读
    短时<b class='flag-5'>傅里叶变换</b>STFT原理详解

    傅里叶变换的定义 傅里叶变换的意义

    连续傅里叶变换和离散傅里叶变换。最初分析是作为热过程的解析分析的工具被提出的。 傅里叶变换
    的头像 发表于 11-30 15:32 1945次阅读