在图像处理中,图像可以用不同域来表示和分析。
下面是几种最常用的域:
- 空间域是指由图像像素组成的空间。
- 时域是指图像随时间变化的域。对于动态图像,例如视频,时域表示图像帧随时间的变化。时域处理是指对图像序列进行操作,例如运动分析、视频压缩等。
- 频域是将图像从空间域变换到频率域得到的表示。在频域中,图像被表示为一个二维复数矩阵,其中每个元素代表图像中某一特定频率分量的幅度和相位。
图像的空间域、时域和频域是三种不同的表示图像信息的视角,这三者之间可以相互转换。
1. 频域
图像的频域 是通过傅里叶变换将图像从空间域转换到频率域而得到的。在频域中,图像的每个像素点都被表示为一个复数,其幅度表示该频率分量的能量,相位表示该频率分量的初始相位。
在空间域中,图像由像素值矩阵表示,每个像素值代表图像在该位置的颜色或亮度。在频率域中,图像由频谱图表示,频谱图上的每个点代表图像中特定频率的成分。图像的频率域与空间域具有互补关系,图像的任何信息都可以在空间域和频率域中找到。
频率域滤波的基本原理是将图像变换到频率域,然后利用滤波器对图像的频谱分量进行处理,最后将滤波后的频谱分量变换回空间域得到滤波后的图像。
在频率域中,图像的每个像素点都对应着一个频率分量。低频分量对应于图像中的平滑区域和整体形状,而高频分量对应于图像中的细节和边缘。
空间域和频率域的滤波器可以分为四类: 低通、高通、带阻、带通滤波器。
- 低通滤波器 允许低频分量通过,抑制高频分量。低频分量通常对应于图像中的平滑区域和整体亮度变化,可以用于平滑图像,去除噪声和模糊细节。
- 高通滤波器 允许高频分量通过,抑制低频分量。高频分量对应于图像中的边缘和细节,可以用于锐化图像,增强图像的边缘和细节。
- 带通滤波器 只允许特定频率范围内的信号通过,抑制其他频率范围内的信号。可以用于提取图像中的特定特征,例如纹理或边缘。
- 带阻滤波器 抑制特定频率范围内的信号,允许其他频率范围内的信号通过。可以用于去除图像中的特定噪声,例如摩尔纹。
2. 图像锐化的原理
在该系列的第三十一篇文章中介绍过图像锐化。锐化的目的是为了突出图像的边缘信息 ,加强图像的轮廓特征,以便于人眼的观察和机器的识别。
在空间域,可以用空间微分来实现锐化。微分算子的响应强度与图像在该点的突变程度有关,图像微分增强了边缘和其他突变(如噪声)而消弱了灰度变化缓慢的区域。
在频率域,由于图像中的边缘、线条等细节部分与图像频谱中的高频分量相对应,在频率域中使用高通滤波器能够使图像的边缘或线条变得清晰,从而使图像得到锐化。高通滤波器衰减傅立叶变换中的低频分量,让高频分量顺利通过,使低频分量受到抑制,就可以增强高频的成分。使图像的边沿或线条变得清晰,从而实现图像的锐化。
3. 傅里叶变换
空间域、时域和频域之间可以通过傅立叶变换(Fourier Transform)进行转换。傅立叶变换是一种数学工具,可以将信号从一个域变换到另一个域。
-
空间域到频域的傅立叶变换 :将图像从空间域 (x,y) 变换到频域 (u,v) ,可以得到图像的频谱。图像的频谱可以反映图像的频率成分,例如图像中边缘、纹理等信息的分布。
-
频域到空间域的傅立叶逆变换:将图像从频域变换回空间域,可以得到原始图像。
先上基础的公式作为直观地感受,后续文章会做介绍。
一维连续傅里叶变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> F ( μ ) = ∫ − ∞ ∞ f ( t ) e − j 2 π μ t d t F(\mu)=\int_{-\infty}^{\infty}f(t)e^{-j2\pi\mu t}\,dt </math>F(μ)=∫−∞∞f(t)e−j2πμtdt
一维连续傅里叶逆变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> f ( t ) = ∫ − ∞ ∞ F ( μ ) e j 2 π μ t d μ f(t)= \int_{-\infty}^{\infty}F(\mu)e^{j2\pi\mu t}\,d\mu </math>f(t)=∫−∞∞F(μ)ej2πμtdμ
一维离散傅里叶变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> F m = ∑ n = 0 M − 1 f n e − j 2 π m n / M m = 0 , 1 , 2 , . . . , M − 1 F_m = \sum_{n=0}^{M-1}f_n e^{-j2\pi mn/M} \quad m = 0,1,2,...,M-1 </math>Fm=∑n=0M−1fne−j2πmn/Mm=0,1,2,...,M−1
一维离散傅里叶逆变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> f n = 1 M ∑ m = 0 M − 1 F m e j 2 π m n / M n = 0 , 1 , 2 , . . . , M − 1 f_n = \frac{1}{M}\sum_{m=0}^{M-1}F_m e^{j2\pi mn/M} \quad n = 0,1,2,...,M-1 </math>fn=M1∑m=0M−1Fmej2πmn/Mn=0,1,2,...,M−1
二维连续傅里叶变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> F ( μ , ν ) = ∫ − ∞ ∞ ∫ − ∞ ∞ f ( t , z ) e − j 2 π ( μ t + ν z ) d t d z F(\mu,\nu)=\int_{-\infty}^{\infty}\int_{-\infty}^{\infty}f(t,z)e^{-j2\pi(\mu t+\nu z)}\,dtdz </math>F(μ,ν)=∫−∞∞∫−∞∞f(t,z)e−j2π(μt+νz)dtdz
二维连续傅里叶逆变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> f ( t , z ) = ∫ − ∞ ∞ ∫ − ∞ ∞ F ( μ , ν ) e j 2 π ( μ t + ν z ) d μ d ν f(t,z)=\int_{-\infty}^{\infty}\int_{-\infty}^{\infty}F(\mu,\nu)e^{j2\pi(\mu t+\nu z)}\,d\mu d\nu </math>f(t,z)=∫−∞∞∫−∞∞F(μ,ν)ej2π(μt+νz)dμdν
二维离散傅里叶变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> F ( μ , ν ) = ∑ x = 0 M − 1 ∑ y = 0 N − 1 f ( x , y ) e − j 2 π ( μ x / M + ν y / N ) F(\mu,\nu) = \sum_{x=0}^{M-1}\sum_{y=0}^{N-1}f(x,y) e^{-j2\pi(\mu x/M + \nu y/N)} </math>F(μ,ν)=∑x=0M−1∑y=0N−1f(x,y)e−j2π(μx/M+νy/N)
二维离散傅里叶逆变换:
<math xmlns="http://www.w3.org/1998/Math/MathML"> f ( x , y ) = 1 M N ∑ μ = 0 M − 1 ∑ ν = 0 N − 1 F ( μ , ν ) e j 2 π ( μ x / M + ν y / N ) f(x,y) = \frac{1}{MN}\sum_{\mu=0}^{M-1} \sum_{\nu=0}^{N-1}F(\mu,\nu)e^{j2\pi(\mu x/M + \nu y/N)} </math>f(x,y)=MN1∑μ=0M−1∑ν=0N−1F(μ,ν)ej2π(μx/M+νy/N)
图像傅里叶变换的计算通常使用离散傅里叶变换(Discrete Fourier Transform,DFT)来实现。DFT 是傅里叶变换的离散化版本,它可以将图像离散化成有限大小的矩阵,然后使用矩阵乘法来计算图像的傅里叶变换。
对于二维离散傅里叶变换,f(x,y) 表示大小为 M*N 的数字图像。 <math xmlns="http://www.w3.org/1998/Math/MathML"> F ( μ , ν ) F(\mu,\nu) </math>F(μ,ν) 表示 f(x,y) 的傅里叶变换。
在式中 f(x,y) 所在坐标系被称为空间域, 由 x = 0,1,2,···,M-1 和 y = 0,1,2,···,N-1 所定义的 M x N 矩阵常被称为空间域矩阵。 <math xmlns="http://www.w3.org/1998/Math/MathML"> F ( μ , ν ) F(\mu,\nu) </math>F(μ,ν) 所在坐标系被称为频域,由 u = 0,1,2,···,M-1 和 v = 0,1,2,···,N-1 定义的 M x N 矩阵常称为频域矩阵。
下面的例子,展示了灰度图像经过傅里叶变换后生成频谱图的过程。
为了便于频域和频谱分析,在傅里叶变换后进行频谱中心化,即对调频谱的四个象限。频谱中心化后,中间最亮的点是低频率,属于直流分量,越往外频率越高。
cpp
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
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
// M = log(1 + M)
dst += Scalar(1); // 取对数前将所有的像素都加1,防止 log0
log(dst, dst); // 取对数
normalize(dst, dst, 0, 1, NORM_MINMAX); //归一化
imshow("dft", dst); // 二维离散傅里叶
// 剪切和重分布幅度图像限,如果有奇数行或奇数列,进行频谱裁剪
dst = dst(Rect(0, 0, dst.cols & -2, dst.rows & -2));
// 重新排列傅里叶图像中的象限,将频谱中心移至图像中心
int cx = dst.cols / 2;
int cy = dst.rows / 2;
Mat q0(dst, Rect(0, 0, cx, cy)); // 左上区域
Mat q1(dst, Rect(cx, 0, cx, cy)); // 右上区域
Mat q2(dst, Rect(0, cy, cx, cy)); // 左下区域
Mat q3(dst, Rect(cx, cy, cx, cy)); // 右下区域
/*
origin:
q0 | q1
q2 | q3
new:
q3 | q2
q1 | q0
*/
// 交换象限
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);// q0 与 q3 进行交换
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);// q1 与 q2 进行交换
}
int main()
{
Mat src = imread(".../girl.jpg");
Mat gray, dst;
imshow("src", src);
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
myDFT(gray, dst); // 傅里叶变换
imshow("dst", dst); // 零频率分量移至频谱中心
waitKey(0);
return 0;
}
4. 总结
"万物皆可傅里叶",本文是傅里叶变换在该系列的一个开篇,后续还会继续介绍其在图像处理中的应用。
在图像处理领域,傅里叶变换可以将图像从空间域变换到频域,从而揭示图像的频率成分。傅里叶变换在图像处理中有着广泛的应用,例如:图像增强、图像分割、特征提取、图像压缩等。