傅里叶变换
对于傅里叶变换的介绍,此处有一篇很好的帖子可供参考。(至少知乎上说很好。。虽然有些地方没懂,但是我不想掐它 呵呵)
傅里叶分析之掐死教程(完整版)更新于2014.06.06
说句题外话,文中结尾作者的阐述的一些观点,本人表示赞同!嘿嘿。。
傅里叶变换是把一个信号从时域变换到其对应的频域进行分析。
- 这种变换的思想是任何函数可以很精确的接近无穷个sin()函数和cos()函数的和。傅里叶变换提供了这种方法来达到这种效果。
- 傅里叶公式如下:
上式中f(i, j)是图像空间域的值而F是频域的值。傅里叶转换的结果是复数,这也显示出了傅里叶变换是一副实数图像(real image)和虚数图像(complex image)叠加或者是幅度图像(magitude image)和相位图像(phase image)叠加的结果。在实际的图像处理算法中仅有幅度图像(magnitude image)图像能够用到,因为幅度图像包含了我们所需要的所有图像几何结构的信息。但是,如果想通过修改幅度图像或者相位图像来间接修改原空间图像,需要保留幅度图像和相位图像来进行傅里叶逆变换,从而得到修改后图像。
傅里叶变换的作用之滤波
- 高频:变换剧烈的灰度变量,例如 边界
- 低频:变换缓慢的灰度变量,流入 大海
滤波:
- 低通滤波器:保留 低频,使得图像 模糊
- 高通滤波器:保留 高频,使得图像 细节增强
opencv的傅里叶变换
方法 | 作用 |
---|---|
cv2.dif() | 把图像进行傅里叶变换,时域->频域 |
cv2.idft() | 逆傅里叶变换,频域-> 时域 |
注:输入图像必须要转成numpy.float32格式
void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);
- InputArray src: 输入图像,可以是实数或虚数
- OutputArray dst: 输出图像,其大小和类型取决于第三个参数flags
- int flags = 0: 转换的标识符,有默认值0.其可取的值如下所示:
DFT_INVERSE: 用一维或二维逆变换取代默认的正向变换 。DFT_SCALE:
缩放比例标识符,根据数据元素个数平均求出其缩放结果,如有N个元素,则输出结果以1/N缩放输出,常与DFT_INVERSE搭配使用。
DFT_ROWS:
对输入矩阵的每行进行正向或反向的傅里叶变换;此标识符可在处理多种适量的的时候用于减小资源的开销,这些处理常常是三维或高维变换等复杂操作。
DFT_COMPLEX_OUTPUT:
对一维或二维的实数数组进行正向变换,这样的结果虽然是复数阵列,但拥有复数的共轭对称性(CCS),可以以一个和原数组尺寸大小相同的实数数组进行填充,这是最快的选择也是函数默认的方法。你可能想要得到一个全尺寸的复数数组(像简单光谱分析等等),通过设置标志位可以使函数生成一个全尺寸的复数输出数组。
DFT_REAL_OUTPUT:
对一维二维复数数组进行逆向变换,这样的结果通常是一个尺寸相同的复数矩阵,但是如果输入矩阵有复数的共轭对称性(比如是一个带有DFT_COMPLEX_OUTPUT标识符的正变换结果),便会输出实数矩阵。
- int nonzeroRows = 0: 当这个参数不为0,函数会假设只有输入数组(没有设置DFT_INVERSE)的第一行或第一个输出数组(设置了DFT_INVERSE)包含非零值。这样的话函数就可以对其他的行进行更高效的处理节省一些时间,这项技术尤其是在采用DFT计算矩阵卷积时非常有效。
实例代码:
画出傅里叶变换后的频域图像
import numpy as np
import cv2
from matplotlib import pyplot as plt
img=cv2.imread("lenna.jpg",0)
#化成np.float32
img_float32=np.float32(img)
#执行傅里叶变换
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
#把低频率图像放到中间位置
dft_shift=np.fft.fftshift