这是中山大学生物医学工程系图像处理课程的一份实验指导。
在OpenCV框架下实现灰度图像的二维傅里叶变换、频域滤波(Gaussian、Butterworth滤波器),以及频域滤波后的傅里叶反变换。
为了看懂这份程序你需要:
- 了解C++的语法以及基本编程思想。
- 学习OpenCV的C++接口,虽然名称上与C基本相仿,但是封装程度更高,更加“面向对象”。
- 遇到某个不懂的函数,OpenCV的官方文档中都进行了足够详细的描述,请自行Google。
- 了解怎么写程序,例如模块化思想、一些基本的程序优化方法,这些文章只是网上搜集,你应该找到适合自己的学习方法。
需要用到的头文件如下,将以下头文件添加进main.cpp
:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
此外,还需要将相应的与头文件相对应的动态链接库加入项目中才能保证程序正常编译,如果你使用Qt Creator,在项目设置中还需要把头文件目录加入.pro
文件。
作为频域滤波的基础建设,先编写有以下功能的函数模块:
- 将任意
Mat
对象(主要是频谱图)的坐标原点对称变换到中心。在这份程序中即quadrandshift()
。 - OpenCV提供的
dft()
函数将灰度图像变换成双通道浮点图像,其中两个通道各描述变换后的实部、虚部信息,为了方便观察频域特性,需要将变换后的频谱图做可视化处理,本程序中为visualDFT
。 - 傅里叶反变换函数。
- 以
Mat
对象的形式生成高斯低通/高通滤镜。 - 生成巴特沃斯滤波器(尚未完成)。
程序中拥有了这些模块化的功能以后,接下来的工作就比较简单了。
原本以为OpenCV中有封装程度更高的函数可以用来完成频域滤波,但目前学到的方案是用mulSpectrum()
函数,对频谱图和滤波器两个Mat
图像进行点乘,再进行反变换观察滤波效果,在源程序中的高斯高通/低通滤波部分注释的相当详尽,请直接阅读源程序。
在命令行窗口中运行:
./DFT -gaussian noise.png
在指定使用高斯滤波器的时候,程序会要求指定sigma,OpenCV中getGaussianKernel()
函数中对sigma的默认计算方法与实践不符,目前还没有找到恰当的计算sigma的方法,输入0或者任何负数相当于令程序用默认的sigma计算方法。
高斯低通滤波效果如下:
去噪效果并不好应该是因为sigma设置过大,在此仅是出于展示目的所以没有细致调整,具体如何计算sigma还在研究,