频域图像处理
频域图像处理
实验目的
- 掌握图像快速傅里叶变换及其实现
- 掌握图像二维频谱的分布特点
实验原理
图像的快速傅里叶变换
傅里叶变换频谱图像
实验内容或步骤
- 对一张图像进行平移,显示原始图像和处理后的图像;
- 分别对两幅图像进行傅里叶变换,显示变换后的结果,分析原图傅里叶频谱与平移后图像频谱的对应关系;
- 对rectangular.jpg及其旋转图rectangular-rotation.jpg分别进行傅里叶变换,显示变换后的结果,分析原图傅里叶频谱与旋转后图像频谱的对应关系。
参考
- 图像平移
- 傅里叶变换cv.dft (src, dst, flags = 0, nonzeroRows = 0)
- https://docs.opencv.org/3.4.1/dd/d02/tutorial_js_fourier_transform.html
- https://docs.opencv.org/3.4.1/d2/de8/group__core__array.html#gadd6cf9baf2b8b704a11b5f04aaf4f39d
- https://blog.csdn.net/qq_19655645/article/details/77295987
注意几个图像傅里叶变换的步骤:
- 需要先获取最佳DFT变换的大小(cv.getOptimalDFTSize),然后以这个大小对原图进行扩充( padding,cv.copyMakeBorder)
- 需要DFT变换后的矩阵进行分解(cv.split),从中提取谱分量(cv.magnitude)
- 如果谱分量行列为奇数,需要对其进行裁剪成偶数(cv.Rect)
- 如果谱分量太大,需要对其进行对数变换(log),以便更好的显示
- 将傅里叶变换后图像的原点调整到中心
实验报告
- 描述实验的基本原理和步骤
- 用数据和图片给出各个步骤中取得的实验结果 ,包括原始图像及其处理后的图像,并进行必要的讨论
- 完整的源代码
图像平移
代码流程如下:
读取图像→显示原图像→调用自定义的函数translateTransform,作平移后图像大小不变的平移处理并显示处理结果→调用自定义的函数translateTransformSize,作平移后图像大小变化的平移处理并显示处理结果。
dst_window显示的是平移时图像尺寸不变的平移结果,可以看见,损失了部分原图;而dst_wind
傅里叶变换,分析原图傅里叶频谱与平移后图像频谱的对应关系
傅立叶变换的步骤
1.需要先获取最佳DFT变换的大小(cv.getOptimalDFTSize),然后以这个大小对原图进行扩充( padding,cv.copyMakeBorder)
2.需要DFT变换后的矩阵进行分解(cv.split),从中提取谱分量(cv.magnitude)
3.如果谱分量行列为奇数,需要对其进行裁剪成偶数(cv.Rect)
4.如果谱分量太大,需要对其进行对数变换(log),以便更好的显示
5.将傅里叶变换后图像的原点调整到中心
什么是DFT,和傅立叶变换有什么联系
根据信号的不同类型,可以把傅立叶变换分为四类:
1) 非周期性连续信号: 傅立叶变换(Fourier Transform,FT)
2) 周期性连续信号: 傅立叶级数(Fourier Series,FS)
3) 非周期性离散信号: 离散时域傅立叶变换(Discrete Time Fourier Transform ,DTFT)
4)周期性离散信号: 离散傅立叶变换(Discrete Fourier Series,DFS)
根据时域与频域的对应关系,我们可以知道,周期<—->离散,是一对对偶关系,即周期信号的傅里叶变换一定是离散的,离散信号的傅里叶变换一定是周期的,反之也成立。
所以针对上述四种傅里叶变换,我们知道,FT的结果具有连续非周期性质,FS的结果具有离散非周期性质,DTFT结果具有连续周期性质,DFT结果具有离散周期性质。
非周期连续信号的傅里叶变换(FT)为:
𝐹(𝜔)=∫−∞∞𝑥(𝑡)𝑒−𝑖𝜔𝑡𝑑𝑡
非周期离散序列的傅里叶变换(DTFT)为:
𝐹(𝜔)=∑𝑛=−∞∞𝑥(𝑛)𝑒−𝑖𝜔𝑛𝑇𝑠
周期连续信号的傅里叶变换(FS)为:
𝐹(𝜔𝑘)=1𝑇∫0𝑇𝑥(𝑡)𝑒−𝑖𝜔𝑘𝑡𝑑𝑡=1𝑇∫0𝑇𝑥(𝑡)𝑒−𝑖2𝜋𝑘𝑡/𝑇𝑑𝑡
周期离散信号的傅里叶变换(DFS)为:
𝐹(𝜔𝑘)=∑𝑛=0𝑁−1𝑥(𝑛)𝑒−𝑖𝜔𝑘𝑛=∑𝑛=0𝑁−1𝑥(𝑛)𝑒−𝑖2𝜋𝑘𝑁𝑛
假定x(n)为Ts区域上x(t)的均值,且Ts(抽样间隔)足够小,如下图所示:
则有
𝐹𝐹𝑇(𝜔)=∫−∞∞𝑥(𝑡)𝑒𝑖𝜔𝑡𝑑𝑡=∑𝑛=−∞∞∫(𝑛+1)𝑇𝑠𝑛𝑇𝑠𝑥(𝑡)𝑒𝑖𝜔𝑡𝑑𝑡=𝑇𝑠∑𝑛=−∞∞𝑥(𝑛)𝑒𝑖𝜔𝑛𝑇𝑠=𝑇𝑠𝐹𝐷𝑇𝐹𝑇(𝜔)
其中
𝑥(𝑛)=1𝑇𝑠∫(𝑛+1)𝑇𝑠𝑛𝑇𝑠𝑥(𝑡)𝑑𝑡
所以非周期连续信号与非周期离散信号之间频谱关系为:
FFT(ω)=Ts·FDTFT(ω) (ω<2πfs)
同样可以推导周期连续信号与周期离散信号之间频谱关系为:
FFS(ωk)=Ts/T·FDFS(ωk)=1/N·FDFS(ωk) (k<N)
上述等式所加的限定是由于离散信号的频谱具有周期性,等价于原连续信号频谱以fs为周期进行平移。这是由于离散信号的傅里叶变换的核函数具有周期性,例如DTFT的核函数为𝑒−𝑖𝜔𝑛𝑇𝑠,当ω增加2πfs时,其值仍然不变。
假若连续信号为一个波包,最高频率为fH,只在有限时间内幅值不为0,则连续信号按周期T延拓后周期信号的傅里叶级数是原连续信号的频域抽样,抽样周期为1/T,其中T为周期信号的周期。公式表示为:
FFS(ωk)=1/T·FFT(ω=ωk)
上述四种傅里叶变换的关系由下图可以对比看出:
上图中,离散信号的采样周期fs>2fH;FS变换的频谱分辨率为1/T.
在实际使用用计算机处理数据时,要求数据都是有限长度,而上述四种傅立叶变换都是针对无穷长度的信号。
针对有限长度的离散信号,定义了DFT:设x(n)是一个长度为N的有限长序列,则定义x(n)的N点离散傅里叶变换为:
𝑋(𝑘)=𝐷𝐹𝑇[𝑥(𝑛)]=∑𝑛=0𝑁−1𝑥(𝑛)𝑊𝑘𝑛𝑁, k = 0, 1, …, N - 1
其中WN=exp(-j2π/N).
三张图片分别为平移大小不变,平移大小变化,原图,第一张图片把窗口和图片同时增大相应的图片变量,第一张图片只把图片平移导致部分缺失
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计算矩阵卷积时非常有效。
从原图傅里叶频谱与平移后图像频谱可以看出,平移后四条线不会特别的明显,原点也不会很明显
对rectangular.jpg及其旋转图rectangular-rotation.jpg分别进行傅里叶变换
旋转前的图片频谱分布为十字架型,旋转后的图片的频谱与图片旋转的角度相似,但显然旋转后的频谱有些地方模糊,并且有很多噪点,个人觉得频谱还跟图片的形状有关,如果该图片包括白色的部分也一块旋转,那旋转后就不会那么模糊了
源代码
1 |
|
本文使用 CC BY-NC-SA 3.0 中国大陆 协议许可
具体请参见 知识共享协议
本文链接:https://zyhang8.github.io/2019/11/24/cv-exp5/