opencv 傅里叶变换的实现

目录
  • 傅里叶变换
    • 理论基础
    • Numpy实现傅里叶变换
    • 实现傅里叶变换
    • 实现逆傅里叶变换
    • 高通滤波示例
    • OpenCV实现傅里叶变换
    • 实现逆傅里叶变换
    • 低通滤波示例

傅里叶变换

图像处理一般分为空间域处理和频率域处理。

空间域处理是直接对图像内的像素进行处理。

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

  • 灰度变换是对图像内的单个像素进行处理,比如调节对比度和处理阈值等。
  • 空间滤波涉及图像质量的改变,例如图像平滑处理。空间域处理的计算简单方便,运算速度更快。

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

理论基础

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

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

数字图像经过傅里叶变换后,得到的频域值是复数。因此,显示傅里叶变换的结果需要使用实数图像(real image)加虚数图像(complex image),或者幅度图像(magnitude image)加相位图像(phase image)的形式。

因为幅度图像包含了原图像中我们所需要的大部分信息,所以在图像处理过程中,通常仅使用幅度图像。

如果希望先在频域内对图像进行处理,再通过逆傅里叶变换得到修改后的空域图像,就必须同时保留幅度图像和相位图像。

对图像进行傅里叶变换后,会得到图像中的低频和高频信息。

低频信息对应图像内变化缓慢的灰度分量。高频信息对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。

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

傅里叶变换在图像处理领域发挥着非常关键的作用,可以实现图像增强、图像去噪、边缘检测、特征提取、图像压缩和加密等。

Numpy实现傅里叶变换

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()

实现逆傅里叶变换

注意: 如果在傅里叶变换过程中使用了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()

高通滤波示例

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

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

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

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

傅里叶变换可以将图像的高频信号和低频信号分离。

通过对图像的频域处理,可以实现图像增强、图像去噪、边缘检测、特征提取、压缩和加密等操作。

在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()

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.jpg',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()

实现逆傅里叶变换

在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()

低通滤波示例

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

实现的中间步骤

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()

经过低通滤波后,图像的边缘信息被削弱了。

时域卷积 --> 频域乘积

到此这篇关于opencv 傅里叶变换的实现的文章就介绍到这了,更多相关opencv 傅里叶变换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python用opencv 图像傅里叶变换

    傅里叶变换 dft = cv.dft(np.float32(img),flags = cv.DFT_COMPLEX_OUTPUT) 傅里叶逆变换 img_back = cv.idft(f_ishift) 实验:将图像转换到频率域,低通滤波,将频率域转回到时域,显示图像 import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('d:/paojie_g.jpg',0) rows,

  • opencv python 傅里叶变换的使用

    理论 傅立叶变换用于分析各种滤波器的频率特性,对于图像,2D离散傅里叶变换(DFT)用于找到频域.快速傅里叶变换(FFT)的快速算法用于计算DFT. 于一个正弦信号,x(t)=Asin(2πft),我们可以说 f 是信号的频率,如果它的频率域被接受,我们可以看到 f 的峰值.如果信号被采样来形成一个离散信号,我们得到相同的频率域,但是在[−π,π] or [0,2π]范围内是周期性的 (or [0,N] for N-point DFT). 可以将图像视为在两个方向上采样的信号.因此,在X和Y方向

  • OpenCV半小时掌握基本操作之傅里叶变换

    目录 概述 高频 vs 低频 傅里叶变换 代码详解 输入转换 傅里叶变换 获取幅度谱 傅里叶逆变换 获取低频 获取高频 概述 OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大. 今天小白就带大家一起携手走进 OpenCV 的世界. 高频 vs 低频 高频 vs 低频: 高频: 变换剧烈的灰度分量, 例如边界 低频: 变换缓慢的灰度分量, 例如一片大海 滤波: 低通滤波器: 只保留低频, 会使得图像模糊 高通滤波器: 只保留高频, 会使得图像细节增强 傅里叶变换 傅里叶变化 (F

  • Python OpenCV实现图像傅里叶变换

    目录 二维离散傅里叶变换(DFT) OpenCV 实现图像傅里叶变换(cv.dft) 示例代码 二维离散傅里叶变换(DFT) 对于二维图像处理,通常使用 x , y x, yx,y 表示离散的空间域坐标变量,用 u , v u,vu,v 表示离散的频率域变量.二维离散傅里叶变换(DFT)和反变换(IDFT)为: 二维离散傅里叶变换也可以用极坐标表示: 傅里叶频谱(Fourier spectrum)为: 傅里叶相位谱(Fourier phase spectrum)为: 傅里叶功率谱(Fourier

  • OpenCV图像变换之傅里叶变换的一些应用

    目录 前言 1. 效果图 2. 原理 3. 源码 3.1 Numpy实现傅里叶变换 3.2 OpenCV实现傅里叶变换 3.3 HPF or LPF? 参考 总结 前言 这篇博客将介绍OpenCV中的图像变换,包括用Numpy.OpenCV计算图像的傅里叶变换,以及傅里叶变换的一些应用: 2D Discrete Fourier Transform (DFT)二维离散傅里叶变换 Fast Fourier Transform (FFT) 快速傅里叶变换 傅立叶变换用于分析各种滤波器的频率特性.对于图

  • OpenCV-Python使用cv2实现傅里叶变换

    前言 在前一篇的博文中,我们详细讲解了傅里叶变换的原理以及使用Numpy库实现傅里叶变换.但是其实OpenCV有直接实现傅里叶变换的函数. 在OpenCV中,我们通过cv2.dft()来实现傅里叶变换,使用cv2.idft()来实现逆傅里叶变换.两个函数的定义如下: cv2.dft(原始图像,转换标识) 这里的原始图像必须是np.float32格式.所以,我们首先需要使用cv2.float32()函数将图像转换.而转换标识的值通常为cv2.DFT_COMPLEX_OUTPUT,用来输出一个复数阵

  • Opencv实现傅里叶变换

    傅里叶变换将图像分解成其正弦和余弦分量,它将图像由空域转换为时域.任何函数都可以近似的表示为无数正弦和余弦函数的和,傅里叶变换就是实现这一步的,数学上一个二维图像的傅里叶变换为: 公式中,f是图像在空域的值,F是频域的值.转换的结果是复数,但是不可能通过一个真实图像和一个复杂的图像或通过大小和相位图像去显示这样的一个图像.然而,在整个图像处理算法只对大小图像是感兴趣的,因为这包含了所有我们需要的图像几何结构的信息. 可通过以下几步显示一副傅里叶变换后的图像 1.将图像扩展到它的最佳尺寸,DFT(

  • opencv 傅里叶变换的实现

    目录 傅里叶变换 理论基础 Numpy实现傅里叶变换 实现傅里叶变换 实现逆傅里叶变换 高通滤波示例 OpenCV实现傅里叶变换 实现逆傅里叶变换 低通滤波示例 傅里叶变换 图像处理一般分为空间域处理和频率域处理. 空间域处理是直接对图像内的像素进行处理. 空间域处理主要划分为灰度变换和空间滤波两种形式. 灰度变换是对图像内的单个像素进行处理,比如调节对比度和处理阈值等. 空间滤波涉及图像质量的改变,例如图像平滑处理.空间域处理的计算简单方便,运算速度更快. 频率域处理是先将图像变换到频率域,然

  • 详解python中GPU版本的opencv常用方法介绍

    引言 本篇是以python的视角介绍相关的函数还有自我使用中的一些问题,本想在这篇之前总结一下opencv编译的全过程,但遇到了太多坑,暂时不太想回看做过的笔记,所以这里主要总结python下GPU版本的opencv. 主要函数说明 threshold():二值化,但要指定设定阈值 blendLinear():两幅图片的线形混合 calcHist() createBoxFilter ():创建一个规范化的2D框过滤器 canny边缘检测 createGaussianFilter():创建一个Ga

  • opencv python简易文档之图像处理算法

    目录 将图片转为灰度图 HSV 图像阈值 图像平滑 形态学-腐蚀操作 形态学-膨胀操作 开运算与闭运算 梯度运算 礼帽与黑帽 图像梯度处理 Canny边缘检测 图像金字塔 图像轮廓 直方图 直方图均衡化: 自适应均衡化: 傅里叶变换 模板匹配 总结 上一篇已经给大家介绍了opencv python图片基本操作的相关内容,这里继续介绍图像处理算法,下面来一起看看吧 将图片转为灰度图 import cv2 #opencv读取的格式是BGR img=cv2.imread('cat.jpg') # 将图

随机推荐