栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【OpenCV4】图像的傅里叶变换 cv::dft() 和逆变换 cv::idft() 解析(c++)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【OpenCV4】图像的傅里叶变换 cv::dft() 和逆变换 cv::idft() 解析(c++)

图像傅里叶变换的作用:

  • 频谱分析,获取图像中高频低频的分布情况
  • 快速卷积,两个矩阵的傅里叶变换结果相乘

案例代码:

cv::Mat TestOpencvDft()
{
    cv::Mat lena = cv::imread("lena.jpg", 0);
    cv::resize(lena, lena, cv::Size(501, 501));

    // 确定适合做傅里叶变换的图像最佳尺寸
    int rows = cv::getOptimalDFTSize(lena.rows);
    int cols = cv::getOptimalDFTSize(lena.cols);

    // 扩展图像
    cv::Mat lena_pad;
    int up = (rows - lena.rows) / 2;
    int down = rows - lena.rows - up;
    int left = (cols - lena.cols) / 2;
    int right = cols - lena.cols - left;
    cv::copyMakeBorder(lena, lena_pad, up, down, left, right, cv::BORDER_CONSTANT);

    // 构建输入
    cv::Mat channels[2], complex;
    channels[0] = cv::Mat_(lena_pad); // 构建实数部分
    channels[1] = cv::Mat::zeros(lena_pad.size(), CV_32FC1); // 构建虚数部分
    cv::merge(channels, 2, complex); // 构建复数矩阵

    // 离散傅里叶变换
    cv::Mat lena_dft;
    cv::dft(complex, lena_dft);

    // 拆分实数部分和虚数部分,将复数转化为幅值
    cv::Mat result_channels[2];
    cv::split(lena_dft, result_channels);
    cv::Mat amplitude;
    cv::magnitude(result_channels[0], result_channels[1], amplitude);
    
    // 将幅值进行对数缩小,公式: amp = log(amp+1),这里 +1 是为了防止有小于 1 的值转换后形成负数
    amplitude += 1;
    log(amplitude, amplitude);

    // 截取和原图对应的区域
    amplitude = amplitude(cv::Rect(up, left, lena.cols, lena.rows));
    cv::normalize(amplitude, amplitude, 0, 1, cv::NORM_MINMAX);

    // 最值中心化
    int center_x = amplitude.cols / 2;
    int center_y = amplitude.rows / 2;
    // 分解成 4 个象限
    cv::Mat up_left = amplitude(cv::Rect(0, 0, center_x, center_y));
    cv::Mat up_right = amplitude(cv::Rect(center_x, 0, center_x, center_y));
    cv::Mat down_left = amplitude(cv::Rect(0, center_y, center_x, center_y));
    cv::Mat down_right = amplitude(cv::Rect(center_x, center_y, center_x, center_y));
    // 对角区域调换
    cv::Mat temp;
    temp = up_left.clone();
    down_right.copyTo(up_left);
    temp.copyTo(down_right);

    temp = up_right.clone();
    down_left.copyTo(up_right);
    temp.copyTo(down_left);

    // 傅里叶逆变换
    cv::Mat re;
    cv::idft(lena_dft, re, cv::DFT_SCALE);
    cv::Mat re_channels[2];
    cv::split(re, re_channels);

    cv::Mat result;
    re_channels[0].convertTo(result, CV_8UC1);
    return result;
}

输入图片:

读取灰度图:

修改宽高

按照最优的宽高扩展图像

傅里叶变换结果

转换成幅值图:

  • 四个角是低频部分,中心是高频部分

    最值中心化:
  • 将低频部分移动到中心

    傅里叶逆变换结果
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1033562.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号