最详细的图像傅里叶变换

图像傅里叶变换的理解

数学意义:傅里叶变换将一个任意的周期函数分解成为无穷个正弦函数的和的形式
物理效果:傅里叶变换实现了将信号从空间域到频率域的转换
信号分析: 一维傅里叶变换(将杂乱的信号由 时域转化到 频域中)一维傅里叶变化是将信号分解为正弦波的和的形式

时域
横轴是时间,纵轴是振幅

最详细的图像傅里叶变换

频域
横轴是频率,纵轴是振幅

最详细的图像傅里叶变换
对一个信号做时域到频域的变换,能够清除看到该信号主要由两个正弦波以及一些噪声混合,如下图所示:

最详细的图像傅里叶变换
将有效的信号频率提取并分离拟合出信号信息,然后将噪声过滤掉,得到滤波结果
最详细的图像傅里叶变换
最详细的图像傅里叶变换

二维信号的离散傅里叶变换所得到的结果的频率成分的分布如下所示:
在经过频谱居中后的频谱中,中间最亮的点是最低频率,属于直流分量(DC分量)。越往边外走,频率越高。所以,频谱图中的四个角和X,Y轴的尽头都是高频(未经过频谱居中的相反)

最详细的图像傅里叶变换
二维离散傅里叶变换的 作用:可以将空间域(二维灰度数表)的图像转换到频域(频率数表),使得更直观地观察和处理图像,也更有利于进行频域滤波等操作。

一副图像(不论是灰度的图像还是彩色图像)所提供的信息都是显而易见的(排除一些本身就很抽象的图片,不搞艺术哈哈哈)。然而,一副图像的傅里叶频谱图,却常常让人难以理解,满脸问号,一脸蒙B。

; 2. 常见频谱图

单色图
只有一种颜色

最详细的图像傅里叶变换

正弦波

最详细的图像傅里叶变换
分析:频率越低对称的频点越靠近频谱中心,随着频率增加远离中心(因为中心是低频,两端为高频)

灰度变化

最详细的图像傅里叶变换
分析:图像灰度变化方向体现在频谱图的方向中

根据上面两个信息可以得到下面结果:

最详细的图像傅里叶变换
常见几何形状
最详细的图像傅里叶变换
分析:还是和上面讲解的一样,频谱图的绘制规律是朝着梯度变化的方向改变的

这边可以这样理解傅里叶变换:
第一种理解:二维图像进行傅里叶变化得到的频谱图(图像梯度的分布图),当然频谱图上的各点与原图像各点并不存在一一对应关系,即使在不移频的情况下也不对应。傅里叶频谱图上看到的明亮不一的亮点,实际上图像上某一点的像素灰度值与它的邻域点差异的强弱,即梯度的大小,也即该点的频率的大小(也可以这么理解,低频部分指低梯度的点,高频部分指高梯度的点)。
另一种理解:图像二维频谱图通过对输入图像进行水平和竖直两个方向的所有扫描线的一维傅立叶变换进行叠加得到,用来表示输入图像的频率分布。
频谱图以图像的中心为圆心,圆的相位对应原图中频率分量的相位,半径对应频率高低。低频部分半径小,高频对应的半径较大,中心为直流分量(图像灰度的平均值),某点的灰度值对应该频率的能量高低。

  1. 傅里叶变换在图像中的应用

Opencv中的 傅里叶变换实现
实现步骤:

  • getOptimalDFTSize()函数得到DFT变换后结果的最优尺寸大小
  • 根据得到的尺寸大小,使用copyMakeBorder()函数填充图像,得到填充后的Mat
  • 根据新生成的Mat,使用merge()函数得到一个双通道的Mat,命名为planes
  • 使用dft()函数进行傅里叶变换,得到通道1为实部,通道2为虚部

实现代码如下所示:

image.convertTo(image, CV_32F);
    vector<Mat> channels;
    split(image, channels);
    Mat image_B = channels[0];

    int m1 = getOptimalDFTSize(image_B.rows);
    int n1 = getOptimalDFTSize(image_B.cols);
    Mat padded;

    copyMakeBorder(image_B, padded, 0, m1 - image_B.rows, 0, n1 - image_B.cols, BORDER_CONSTANT, Scalar::all(0));
    Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
    Mat complexI;
    merge(planes, 2, complexI);

    dft(complexI, complexI, DFT_SCALE | DFT_COMPLEX_OUTPUT);
    split(complexI, planes);

    Mat ph, mag, idft;
    phase(planes[0], planes[1], ph);
    magnitude(planes[0], planes[1], mag);

    int cx = mag.cols / 2;
    int cy = mag.rows / 2;
    Mat q0(mag, Rect(0, 0, cx, cy));
    Mat q1(mag, Rect(cx, 0, cx, cy));
    Mat q2(mag, Rect(0, cy, cx, cy));
    Mat q3(mag, Rect(cx, cy, cx, cy));

    Mat tmp;
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);

    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);

    imshow("mag", mag);

实现结果如下所示:

最详细的图像傅里叶变换

    polarToCart(mag, ph, planes[0], planes[1]);
    merge(planes, 2, idft);
    dft(idft, idft, DFT_INVERSE | DFT_REAL_OUTPUT);
    image_B = idft(Rect(0, 0, image.cols & -2, image.rows & -2));
    image_B.copyTo(channels[0]);

    merge(channels, image);
    image.convertTo(image, CV_8U);

傅里叶逆变换实现结果:

最详细的图像傅里叶变换
低通滤波
实现机制:将高频的信号舍去;(通低频,阻高频)

    for (int i = 0; i < mag.cols; i++){
        for (int j = 0; j < mag.rows; j++){
            if (abs(i - mag.cols / 2) > mag.cols / 10 || abs(j - mag.rows / 2) > mag.rows / 10)
                mag.at<float>(j, i) = 0;
        }
    }

低通滤波实现结果:

最详细的图像傅里叶变换
高通滤波
实现机制:将低频的信号舍去;(通高频,阻低频)

    for (int i = 0; i < mag.cols; i++){
        for (int j = 0; j < mag.rows; j++){
            if (abs(i - mag.cols / 2) < mag.cols / 30 && abs(j - mag.rows / 2) < mag.rows / 30)
                mag.at<float>(j, i) = 0;
        }
    }

高通滤波实现结果

最详细的图像傅里叶变换

Original: https://blog.csdn.net/weixin_44478077/article/details/124567210
Author: LV小猪精
Title: 最详细的图像傅里叶变换

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/651692/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球