在图像处理中,图像可以用不同域来表示和分析。
下面是几种最常用的域:
时域
是指图像随时间变化的域。对于动态图像,例如视频,时域表示图像帧随时间的变化。时域处理是指对图像序列进行操作,例如运动分析、视频压缩等。
频域
是将图像从空间域变换到频率域得到的表示。在频域中,图像被表示为一个二维复数矩阵,其中每个元素代表图像中某一特定频率分量的幅度和相位。
图像的空间域、时域和频域是三种不同的表示图像信息的视角,这三者之间可以相互转换。
时域图像和频域图像.png
1. 频域
图像的
频域
是通过
傅里叶变换
将图像从空间域转换到频率域而得到的。在频域中,图像的每个像素点都被表示为一个复数,其幅度表示该频率分量的能量,相位表示该频率分量的初始相位。
在空间域中,图像由像素值矩阵表示,每个像素值代表图像在该位置的颜色或亮度。在频率域中,图像由
频谱图
表示,频谱图上的每个点代表图像中特定频率的成分。图像的频率域与空间域具有互补关系,图像的任何信息都可以在空间域和频率域中找到。
频率域滤波的基本原理是将图像变换到频率域,然后利用滤波器对图像的频谱分量进行处理,最后将滤波后的频谱分量变换回空间域得到滤波后的图像。
在频率域中,图像的每个像素点都对应着一个频率分量。低频分量对应于图像中的平滑区域和整体形状,而高频分量对应于图像中的细节和边缘。
空间域和频率域的滤波器可以分为四类: 低通、高通、带阻、带通滤波器。
低通滤波器
允许低频分量通过,抑制高频分量。低频分量通常对应于图像中的平滑区域和整体亮度变化,可以用于
平滑图像
,去除噪声和模糊细节。
高通滤波器
允许高频分量通过,抑制低频分量。高频分量对应于图像中的边缘和细节,可以用于
锐化图像
,增强图像的边缘和细节。
带通滤波器
只允许特定频率范围内的信号通过,抑制其他频率范围内的信号。可以用于
提取图像中的特定特征
,例如纹理或边缘。
带阻滤波器
抑制特定频率范围内的信号,允许其他频率范围内的信号通过。可以用于
去除图像中的特定噪声
,例如摩尔纹。
2. 图像锐化的原理
在该系列的第三十一篇文章中介绍过图像锐化。锐化的目的是为了突出图像的边缘信息 ,加强图像的轮廓特征,以便于人眼的观察和机器的识别。
在空间域,可以用空间微分来实现锐化。微分算子的响应强度与图像在该点的突变程度有关,图像微分增强了边缘和其他突变(如噪声)而消弱了灰度变化缓慢的区域。
在频率域,由于图像中的边缘、线条等细节部分与图像频谱中的高频分量相对应,在频率域中使用
高通滤波器
能够使图像的边缘或线条变得清晰,从而使图像得到锐化。高通滤波器衰减傅立叶变换中的低频分量,让高频分量顺利通过,使低频分量受到抑制,就可以增强高频的成分。使图像的边沿或线条变得清晰,从而实现图像的锐化。
3. 傅里叶变换
空间域、时域和频域之间可以通过傅立叶变换(Fourier Transform)进行转换。傅立叶变换是一种数学工具,可以将信号从一个域变换到另一个域。
空间域到频域的傅立叶变换
:将图像从空间域 (x,y) 变换到频域 (u,v) ,可以得到图像的
频谱
。图像的频谱可以反映图像的频率成分,例如图像中边缘、纹理等信息的分布。
频域到空间域的傅立叶逆变换
:将图像从频域变换回空间域,可以得到原始图像。
先上基础的公式作为直观地感受,后续文章会做介绍。
一维连续傅里叶变换:
一维连续傅里叶逆变换:
一维离散傅里叶变换:
一维离散傅里叶逆变换:
二维连续傅里叶变换:
二维连续傅里叶逆变换:
二维离散傅里叶变换:
二维离散傅里叶逆变换:
图像傅里叶变换的计算通常使用离散傅里叶变换(Discrete Fourier Transform,DFT)来实现。DFT 是傅里叶变换的离散化版本,它可以将图像离散化成有限大小的矩阵,然后使用矩阵乘法来计算图像的傅里叶变换。
对于二维离散傅里叶变换,f(x,y) 表示大小为 M*N 的数字图像。
表示 f(x,y) 的傅里叶变换。
在式中 f(x,y) 所在坐标系被称为空间域, 由 x = 0,1,2,···,M-1 和 y = 0,1,2,···,N-1 所定义的 M x N 矩阵常被称为空间域矩阵。
所在坐标系被称为频域,由 u = 0,1,2,···,M-1 和 v = 0,1,2,···,N-1 定义的 M x N 矩阵常称为频域矩阵。
下面的例子,展示了灰度图像经过傅里叶变换后生成频谱图的过程。
为了便于频域和频谱分析,在傅里叶变换后进行频谱中心化,即对调频谱的四个象限。频谱中心化后,中间最亮的点是低频率,属于直流分量,越往外频率越高。
#include #include #include using namespace cv;using namespace std ;void myDFT (Mat src, Mat& dst) { // 扩充边界 int m = getOptimalDFTSize(src.rows); int n = getOptimalDFTSize(src.cols); copyMakeBorder(src, src, 0 , m - src.rows, 0 , n - src.cols, BORDER_CONSTANT, Scalar::all(0 )); // 创建一个双通道矩阵 planes,用来储存复数的实部与虚部 Mat planes[] = {Mat_<float >(src), Mat::zeros(src.size(), CV_32F) }; Mat complexI; // 增加一个通道,将两个 planes 合并,为了存储复数 merge(planes, 2 , complexI); // 进行离散傅立叶变换 dft(complexI, complexI); split(complexI, planes); // 将双通道分为两个单通道,一个表示实部,一个表示虚部 magnitude(planes[0 ], planes[1 ], dst); //计算复数的幅值,保存在频谱图 dst