Python3+OpenCV(四):离散傅里叶变换(DFT)


    • 1、原理
    • 2、实现


1、原理

对一张图像使用傅里叶变换就是将它分解成正弦和余弦两部分,也就是将图像从空间域(spatial domain)转换到频域(frequency domain)。这一转换的理论基础来自于以下事实:任一函数都可以表示成无数个正弦和余弦函数的和的形式。傅里叶变换就是一个用来将函数分解的工具。
二维图像的傅里叶变换可以用以下数学公式表达:

Python3+OpenCV(四):离散傅里叶变换(DFT)_第1张图片

式中f(i, j)是图像空间域的值而F是频域的值。傅里叶转换的结果是复数,这也显示出了傅里叶变换是一副实数图像(real image)和虚数图像(complex image)叠加或者是幅度图像(magitude image)和相位图像(phase image)叠加的结果。

在实际的图像处理算法中仅有幅度图像(magnitude image)图像能够用到,因为幅度图像包含了我们所需要的所有图像几何结构的信息。但是,如果想通过修改幅度图像或者相位图像来间接修改原空间图像,需要保留幅度图像和相位图像来进行傅里叶逆变换,得到修改后图像。

对于数字图像这种离散的信号,频率大小表示信号变化的剧烈程度或者说是信号变化的快慢。频率越大,变化越剧烈,频率越小,信号越平缓。 对应到图像中,高频信号往往是图像中的边缘信号和噪声信号,而低频信号包含图像变化频繁的图像轮廓及背景等信号。

对于一幅大小为M x N的图像,图像的傅里叶频谱关于(M/2, N/2)的对称性。

  • 频谱图A区与D区关于(M/2, N/2)对称
  • 频谱图B区和C区关于(M/2, N/2)对称
    Python3+OpenCV(四):离散傅里叶变换(DFT)_第2张图片

2、实现

cv2.dft(src, dst=None, flag=None, nonzeroRows=0)

作用:进行傅里叶变换
src:输入图像
dst:输出图像
flag:转换标识符

  • DFT_INVERSE: 用一维或二维逆变换取代默认的正向变换
  • DFT_SCALE: 缩放比例标识符,根据数据元素个数平均求出其缩放结果,如有N个元素,则输出结果以1/N缩放输出,常与DFT_INVERSE搭配使用。
  • DFT_ROWS: 对输入矩阵的每行进行正向或反向的傅里叶变换;此标识符可在处理多种适量的的时候用于减小资源的开销,这些处理常常是三维或高维变换等复杂操作。
  • DFT_COMPLEX_OUTPUT: 对一维或二维的实数数组进行正向变换,这样的结果虽然是复数阵列,但拥有复数的共轭对称性(CCS),可以以一个和原数组尺寸大小相同的实数数组进行填充,这是最快的选择也是函数默认的方法。你可能想要得到一个全尺寸的复数数组(像简单光谱分析等等),通过设置标志位可以使函数生成一个全尺寸的复数输出数组。
  • DFT_REAL_OUTPUT: 对一维二维复数数组进行逆向变换,这样的结果通常是一个尺寸相同的复数矩阵,但是如果输入矩阵有复数的共轭对称性(比如是一个带有DFT_COMPLEX_OUTPUT标识符的正变换结果),便会输出实数矩阵。

nonzeroRows:当参数不为0,函数会假设只有输入数组(没有设置DFT_INVERSE)的第一行或第一个输出数组(设置了DFT_INVERSE)包含非零值。这样的话函数就可以对其他的行进行更高效的处理节省一些时间,这项技术尤其是在采用DFT计算矩阵卷积时非常有效。

np.fft.fftshift(img)

作用:将图像中的低频部分移动到图像的中心
img:图像

cv2.magnitude(x, y)

作用:计算二维矢量的幅值
x:表示浮点型X坐标值,即实部
y:表示浮点型y坐标值,即虚部
计算方法:
在这里插入图片描述

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("D:/Study/digital image processing/test/Lena.bmp",0)

# np.float32()将图像数据转换成float32 然后进行傅里叶变换cv2.dft()
dft = cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
# 将低频信息转换至图像中心
dft_shift = np.fft.fftshift(dft)
# 傅里叶变换后的数据是由实部和虚部构成的,需要进行转换成图像格式才能显示(0,255)
# cv2.magnitude()将实部和虚部转换为实部,乘以20将结果放大
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('Input'),plt.xticks([]),plt.yticks([])
plt.subplot(122)
plt.imshow(magnitude_spectrum,cmap='gray')
plt.title('Output'),plt.xticks([]),plt.yticks([])
plt.show()

Python3+OpenCV(四):离散傅里叶变换(DFT)_第3张图片

参考博客
https://blog.csdn.net/chenjiazhou12/article/details/21240647
https://blog.csdn.net/zhu_hongji/article/details/81382000

你可能感兴趣的:(OpenCV,opencv)