opencv实现快速傅立叶变换和逆变换

举报
风吹稻花香 发表于 2021/06/05 01:30:51 2021/06/05
【摘要】 原文: http://www.tuicool.com/articles/VB3UNjf 说实话觉得网上很多人转载的文章的挺坑的,全部是opencv文档程序的翻译,看来看去都是那一 篇,真的没啥意思。 文档的地址。 本来opencv实现dft就是一个函数的事情,但是很少有关于逆变换使用的资料。我这几天在翻译 matlab版本的L0Smooth到opencv上面,...

原文: http://www.tuicool.com/articles/VB3UNjf

说实话觉得网上很多人转载的文章的挺坑的,全部是opencv文档程序的翻译,看来看去都是那一

篇,真的没啥意思。 文档的地址

本来opencv实现dft就是一个函数的事情,但是很少有关于逆变换使用的资料。我这几天在翻译

matlab版本的L0Smooth到opencv上面,就碰到这样一件很坑爹的事情。

首先,很少有人说清楚这个函数的使用方法。还有,根据教程,dft之前最好扩充原矩阵到合适的尺

寸(2,3,5的倍数),再调用dft会加快速度。那么,idft的时候了?如何恢复原有的尺寸?

在我的L0Smooth代码里,就碰到这样的事情了。如果,图片尺寸是2,3,5的倍数,那么能够得到

正确结果。否则得到是全黑的图片。如果,我不扩张矩阵,那么就能正确处理。

所以,到这里,我不推荐调用dft之前先扩充矩阵了。因为,我找了很久也没找到解决办法。

我数学水平有限,也分析不出原因,也没有时间去系统的学习这些了。

这里提供两个例子,说明dft和idft的使用。

例子一:类似于opencv官方文档的例子


    
  1. #include "opencv2/core/core.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include "opencv2/highgui/highgui.hpp"
  4. #include <iostream>
  5. #ifdef _DEBUG
  6. #pragma comment(lib, "opencv_core247d.lib")
  7. #pragma comment(lib, "opencv_imgproc247d.lib")
  8. #pragma comment(lib, "opencv_highgui247d.lib")
  9. #else
  10. #pragma comment(lib, "opencv_core247.lib")
  11. #pragma comment(lib, "opencv_imgproc247.lib")
  12. #pragma comment(lib, "opencv_highgui247.lib")
  13. #endif // DEBUG
  14. int main()
  15. {
  16. // Read image from file
  17. // Make sure that the image is in grayscale
  18. cv::Mat img = cv::imread("lena.JPG",0);
  19. cv::Mat planes[] = {cv::Mat_<float>(img), cv::Mat::zeros(img.size(), CV_32F)};
  20. cv::Mat complexI; //Complex plane to contain the DFT coefficients {[0]-Real,[1]-Img}
  21. cv::merge(planes, 2, complexI);
  22. cv::dft(complexI, complexI); // Applying DFT
  23. //这里可以对复数矩阵comlexI进行处理
  24. // Reconstructing original imae from the DFT coefficients
  25. cv::Mat invDFT, invDFTcvt;
  26. cv::idft(complexI, invDFT, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT ); // Applying IDFT
  27. cv::invDFT.convertTo(invDFTcvt, CV_8U);
  28. cv::imshow("Output", invDFTcvt);
  29. //show the image
  30. cv::imshow("Original Image", img);
  31. // Wait until user press some key
  32. cv::waitKey(0);
  33. return 0;
  34. }

代码意思很简单,dft之后再idft,注意参数额,必须有DFT_SCALE。代码中,先merge了个

复数矩阵,在例子2中可以看到,其实这一步可以去掉。

例子2:


    
  1. #include "opencv2/core/core.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include "opencv2/highgui/highgui.hpp"
  4. #include <iostream>
  5. #ifdef _DEBUG
  6. #pragma comment(lib, "opencv_core247d.lib")
  7. #pragma comment(lib, "opencv_imgproc247d.lib")
  8. #pragma comment(lib, "opencv_highgui247d.lib")
  9. #else
  10. #pragma comment(lib, "opencv_core247.lib")
  11. #pragma comment(lib, "opencv_imgproc247.lib")
  12. #pragma comment(lib, "opencv_highgui247.lib")
  13. #endif // DEBUG
  14. int main()
  15. {
  16. // Read image from file
  17. // Make sure that the image is in grayscale
  18. cv:;Mat img = cv::imread("lena.JPG",0);
  19. cv::Mat dftInput1, dftImage1, inverseDFT, inverseDFTconverted;
  20. cv::img.convertTo(dftInput1, CV_32F);
  21. cv::dft(dftInput1, dftImage1, cv::DFT_COMPLEX_OUTPUT); // Applying DFT
  22. // Reconstructing original imae from the DFT coefficients
  23. cv::idft(dftImage1, inverseDFT, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT ); // Applying IDFT
  24. cv::inverseDFT.convertTo(inverseDFTconverted, CV_8U);
  25. cv::imshow("Output", inverseDFTconverted);
  26. //show the image
  27. cv::imshow("Original Image", img);
  28. // Wait until user press some key
  29. waitKey(0);
  30. return 0;
  31. }

从代码中可以看到,dft时候添加参数DFT_COMPLEX_OUTPUT,就可以自动得到复数矩阵了,代码更加简洁。注意,必须先将图片对应的uchar矩阵转换为float矩阵,再进行dft,idft,最后再转换回来。

文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/54289001

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。