作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

场景需求

matlab的fftshift是进行傅里叶相关操作时常用的函数,傅里叶之后得到的结果频率范围是0到fs,为了便于进行频率域滤波,也便于观察频谱信息 ,通常将频率范围调整至-fs/2到fs/2,这样就将零频分量(直流分量)迁移到了图像中心,呈现的效果就是中心低频信息,四周外围是高频信息,这个实现我们就称为fftshift。C++中运用OpenCV也可以实现同matlab一致的效果,其实原理搞懂了,用数组、Eigen等其他数据结构或者运算库也都很方便实现。

功能函数代码

// fft变换后进行频谱搬移;分别将实部信息和虚部信息进行搬移
void fftshift(cv::Mat &plane0, cv::Mat &plane1)
{// 以下的操作是移动图像  (零频移到中心)int cx = plane0.cols / 2;int cy = plane0.rows / 2;cv::Mat part1_r(plane0, cv::Rect(0, 0, cx, cy));  // 元素坐标表示为(cx, cy)cv::Mat part2_r(plane0, cv::Rect(cx, 0, cx, cy));cv::Mat part3_r(plane0, cv::Rect(0, cy, cx, cy));cv::Mat part4_r(plane0, cv::Rect(cx, cy, cx, cy));cv::Mat temp;part1_r.copyTo(temp);  //左上与右下交换位置(实部)part4_r.copyTo(part1_r);temp.copyTo(part4_r);part2_r.copyTo(temp);  //右上与左下交换位置(实部)part3_r.copyTo(part2_r);temp.copyTo(part3_r);cv::Mat part1_i(plane1, cv::Rect(0, 0, cx, cy));  //元素坐标(cx,cy)cv::Mat part2_i(plane1, cv::Rect(cx, 0, cx, cy));cv::Mat part3_i(plane1, cv::Rect(0, cy, cx, cy));cv::Mat part4_i(plane1, cv::Rect(cx, cy, cx, cy));part1_i.copyTo(temp);  //左上与右下交换位置(虚部)part4_i.copyTo(part1_i);temp.copyTo(part4_i);part2_i.copyTo(temp);  //右上与左下交换位置(虚部)part3_i.copyTo(part2_i);temp.copyTo(part3_i);
}

C++测试代码

#include<iostream>
#include<opencv2/opencv.hpp>
#include<ctime>
using namespace std;
using namespace cv;void fftshift(cv::Mat &plane0, cv::Mat &plane1);int main(void)
{Mat test = imread("test.jpg", 0);test.convertTo(test, CV_32FC1);//创建通道,存储dft后的实部与虚部(CV_32F,必须为单通道数)cv::Mat plane[] = { test.clone(), cv::Mat::zeros(test.size() , CV_32FC1) };cv::Mat complexIm;cv::merge(plane, 2, complexIm); // 合并通道 (把两个矩阵合并为一个2通道的Mat类容器)cv::dft(complexIm, complexIm); // 进行傅立叶变换,结果保存在自身// 分离通道(数组分离)cv::split(complexIm, plane);// 以下的操作是频域迁移fftshift(plane[0], plane[1]);// 创建一个简单的高斯低通滤波器cv::Mat gaussianBlur(test.size(), CV_32FC1); //,CV_32FC1float d0 = 5;//高斯函数参数,越小,频率高斯滤波器越窄,滤除高频成分越多,图像就越平滑for (int i = 0; i < test.rows; i++) {for (int j = 0; j < test.cols; j++) {float d = pow(float(i - test.rows / 2), 2) + pow(float(j - test.cols / 2), 2);//分子,计算pow必须为float型gaussianBlur.at<float>(i, j) = expf(-d / (2 * d0*d0));//expf为以e为底求幂(必须为float型)}}// *****************滤波器函数与DFT结果的乘积****************cv::Mat blur_r, blur_i, BLUR;cv::multiply(plane[0], gaussianBlur, blur_r);  // 滤波(实部与滤波器模板对应元素相乘)cv::multiply(plane[1], gaussianBlur, blur_i);  // 滤波(虚部与滤波器模板对应元素相乘)cv::Mat plane1[] = { blur_r, blur_i };// 再次搬移回来进行逆变换fftshift(plane1[0], plane1[1]);cv::merge(plane1, 2, BLUR); // 实部与虚部合并cv::idft(BLUR, BLUR);       // idft结果也为复数BLUR = BLUR / BLUR.rows / BLUR.cols;cv::split(BLUR, plane);//分离通道,主要获取通道imshow("original", test/255);imshow("result", plane[0]/255);waitKey(0);system("pause");return 0;
}// fft变换后进行频谱搬移
void fftshift(cv::Mat &plane0, cv::Mat &plane1)
{// 以下的操作是移动图像  (零频移到中心)int cx = plane0.cols / 2;int cy = plane0.rows / 2;cv::Mat part1_r(plane0, cv::Rect(0, 0, cx, cy));  // 元素坐标表示为(cx, cy)cv::Mat part2_r(plane0, cv::Rect(cx, 0, cx, cy));cv::Mat part3_r(plane0, cv::Rect(0, cy, cx, cy));cv::Mat part4_r(plane0, cv::Rect(cx, cy, cx, cy));cv::Mat temp;part1_r.copyTo(temp);  //左上与右下交换位置(实部)part4_r.copyTo(part1_r);temp.copyTo(part4_r);part2_r.copyTo(temp);  //右上与左下交换位置(实部)part3_r.copyTo(part2_r);temp.copyTo(part3_r);cv::Mat part1_i(plane1, cv::Rect(0, 0, cx, cy));  //元素坐标(cx,cy)cv::Mat part2_i(plane1, cv::Rect(cx, 0, cx, cy));cv::Mat part3_i(plane1, cv::Rect(0, cy, cx, cy));cv::Mat part4_i(plane1, cv::Rect(cx, cy, cx, cy));part1_i.copyTo(temp);  //左上与右下交换位置(虚部)part4_i.copyTo(part1_i);temp.copyTo(part4_i);part2_i.copyTo(temp);  //右上与左下交换位置(虚部)part3_i.copyTo(part2_i);temp.copyTo(part3_i);
}

测试效果

图1 处理前频谱图

图2 处理后频谱图

图3 滤波前后对比图

如上图所示,fftshift实现的效果就是将低频信息迁移到中心,高频信息在四周,此时用滤波器相乘,频谱图中心的信息保留,即保留了低频成分,四周的信息归0,即去除了高频成分,这就实现了我们常说的低通滤波~

如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

C++-实现matlab的fftshift(OpenCV)相关推荐

  1. matlab中caitu_tiqu,车牌识别matlab语音版+OpenCV版+测试图像和设计文档

    [实例简介] 该文件包含了车牌识别的两个版本:matlab语音版+OpenCV版,有丰富的测试实例和文档信息,测试结果能满足大部分的车牌识别. [实例截图] [核心代码] 5d61aaaa-2457- ...

  2. matlab fft2的作用,为什么Matlab fft2比OpenCV dft快得多(why Matlab fft2 is much faster than OpenCV dft)...

    为什么Matlab fft2比OpenCV dft快得多(why Matlab fft2 is much faster than OpenCV dft) 我只是测试比较OpenCV的dft函数和Mat ...

  3. 如何把opencv编译到matlab,c – 为OpenCV编译MATLAB绑定

    我正在尝试编译OpenCV 3.0的MATLAB绑定,即 Github的当前版本.我一直收到以下错误: CMake Error at /opencv/modules/matlab/compile.cm ...

  4. 3.6总结半年来的专业学习——图像处理、光栅投影、四步相移、多频外差,从matlab入门到opencv入门

    2019.9.17 研究生导师定了,老师给了一些论文,并推荐了几本书 1.计算机辅助光学测量/金观昌著 作者是在美国奥克兰大学杨老师实验室做过访问学者,所以书的内容和实验室的研究方向非常切合 2.基于 ...

  5. matlab中fftshift的意义

    在matlab中,经过fft变换后,数据的频率范围是从[0,fs]排列的.而一般,我们在画图或者讨论的时候,是从[-fs/2,fs/2]的范围进行分析.因此,需要将经过fft变换后的图像的[fs/2, ...

  6. matlab imadjust 用 opencv改写

    原文:http://blog.csdn.net/yeyang911/article/details/18256393 自己测试的效果不是很好 实现函数功能 J = low_out +(high_out ...

  7. info matlab,c – 在OpenCV中是否有类似MATLAB的’impixelinfo()’功能?

    你可以这样做: #include #include using namespace std; using namespace cv; Mat img; void CallBackFunc(int ev ...

  8. matlab函数fftshift,matlab中fft算法_matlab中fftshift函数_matlab中fft函数的用法(2)

    plot([0 : PointNum/2 - 1], x1(1:PointNum/2)); grid on subplot(3,1,2); % [REX IMX] am = sqrt(abs(REX. ...

  9. opencv remap matlab,如何使用OpenCV的remap函数?

    这只是对文件的一个简单的误解,我不怪你--我也花了几次摸索才明白.文档很清楚,但是这个函数可能没有按您预期的方式工作:事实上,它在与我最初预期相反的方向工作. remap()没有做的是获取源图像的坐标 ...

  10. matlab 调用opencv,matlab调用opencv (mac 或 linux)

    思路为利用mexopencv编译opencv为mex,然后让MATLAB调用. 方法1 (仅适用于mac) 利用homebrew下载opencv3. $ brew install pkg-config ...

最新文章

  1. Proximal Algorithms 3 Interpretation
  2. 网络:TIME-WAIT
  3. 思考 | 人工智能时代:AI芯片能否实现弯道超越?
  4. python3.6sysos_求大佬,这是什么情况啊
  5. 如何在Appscale下发布自己的应用(一)
  6. android点赞刷新列表图片闪烁,RecyclerView使用——有效解决刷新数据错乱,图片闪烁,OOM问题...
  7. 蓝桥杯 基础练习 时间转换
  8. Lua1.0 数据结构
  9. Java多线程之二(Synchronized)
  10. 软中断上下文能够睡眠吗?
  11. 服务器安装黑苹果系统,黑苹果 单系统安装教程
  12. 2022年盐城市“黄海明珠人才计划”领军人才项目申报奖励补贴条件
  13. mysql 本周、上周、本月、上月SQL 语句
  14. min-height是什么意思?
  15. 房屋租赁合同无效条件包括哪些
  16. c51倒计时程序汇编语言,两位倒计时器程序(单片机—汇编语言).doc
  17. 使用WinRAR制作属于自己的单文件版软件
  18. 删除链接到WLW清单文件
  19. 算法导论的一道课后练习题,挺有意思
  20. SPL 工业智能:识别指定工况

热门文章

  1. android 手势密码存储,Android 简易手势密码开源库详解
  2. layui 之 laypage分页插件
  3. 北理珠计算机专业在广东排第几,【我们的珠澳】再破纪录!北师珠、吉珠、北理珠这几天要在全国出名了!...
  4. 分形理论在金相学中的应用
  5. 台电X80H平板安装ubantu
  6. Python数据挖掘之时序模型预测
  7. 加密狗映射至虚拟服务器,XenServer6.x U盘、加密狗等USB设备映射到VM虚拟机教程.pdf...
  8. 详细介绍ADMM交替方向乘子法
  9. 虚拟主机与云服务器的区别
  10. web应用程序的部署