欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

图像的傅里叶变换和逆变换C++版

发布时间:2023/12/20 26 豆豆
生活随笔 收集整理的这篇文章主要介绍了 图像的傅里叶变换和逆变换C++版 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

目录

头文件:包含OpenCV和标准库输出调试

读入并显示原图

进行离散傅里叶变换和逆变换

显示傅里叶变换图

完整代码:

参考文献:


首先把整体程序分段,每段都是单独的功能。最后再把完整代码给出:

头文件:包含OpenCV和标准库输出调试

#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> using namespace cv; #include <iostream> using std::cout; using std::endl;int main(int argc, char*argv[]){waitKey(0);return 0; }

读入并显示原图

Mat img = imread("2.png");if (!img.data)return -1;namedWindow("原图", WINDOW_AUTOSIZE);imshow("原图", img);

进行离散傅里叶变换和逆变换

//快速傅里叶变换 void ImageDFT(InputArray srcImage, OutputArray dstImage) {//得到Mat类型Mat src = srcImage.getMat();int rows = src.rows;int cols = src.cols;//快速傅里叶变换的计算速度与图像的大小有关,计算最优图像尺寸,然后进行扩充,扩充值为0Mat padded;int rPadded = getOptimalDFTSize(rows);int cPadded = getOptimalDFTSize(cols);copyMakeBorder(src, padded, 0, rPadded - rows, 0, cPadded - cols, BORDER_CONSTANT, Scalar::all(0));//快速的傅里叶变换(双通道:用于存储实部 和 虚部)dft(padded, dstImage, DFT_COMPLEX_OUTPUT); }//转换成灰度图,浮点型图Mat fImg;cvtColor(img, img, CV_BGR2GRAY); img.convertTo(fImg, CV_64FC1);//快速傅里叶变换Mat fftImage;ImageDFT(fImg, fftImage);//傅里叶逆变换Mat image;cv::dft(fftImage, image, DFT_INVERSE + DFT_REAL_OUTPUT + DFT_SCALE);namedWindow("fft逆变换图", WINDOW_AUTOSIZE);imshow("fft逆变换图", image);

显示傅里叶变换图

Mat planes[2];split(fftImage, planes);cout << fftImage.channels() << endl;magnitude(planes[0], planes[1], planes[0]);Mat magnitudeImage = planes[0];magnitudeImage += Scalar::all(1); // 所有的像素都加1log(magnitudeImage, magnitudeImage); // 求自然对数normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX);// 频谱图像长宽变为偶数,然后频谱中心化magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));int cx = magnitudeImage.cols / 2;int cy = magnitudeImage.rows / 2;Mat q0(magnitudeImage, Rect(0, 0, cx, cy));Mat q1(magnitudeImage, Rect(cx, 0, cx, cy));Mat q2(magnitudeImage, Rect(0, cy, cx, cy));Mat q3(magnitudeImage, 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("fft图", magnitudeImage);

完整代码:

#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> using namespace cv; #include <iostream> using std::cout; using std::endl;//快速傅里叶变换 void ImageDFT(InputArray srcImage, OutputArray dstImage) {//得到Mat类型Mat src = srcImage.getMat();//判断位深//CV_Assert(src.type() == CV_32FC1 || src.type() == CV_64FC1);//CV_Assert(src.channels() == 1 || src.channels() == 2);int rows = src.rows;int cols = src.cols;//快速傅里叶变换的计算速度与图像的大小有关,计算最优图像尺寸,然后进行扩充,扩充值为0Mat padded;int rPadded = getOptimalDFTSize(rows);int cPadded = getOptimalDFTSize(cols);copyMakeBorder(src, padded, 0, rPadded - rows, 0, cPadded - cols, BORDER_CONSTANT, Scalar::all(0));//快速的傅里叶变换(双通道:用于存储实部 和 虚部)dft(padded, dstImage, DFT_COMPLEX_OUTPUT); } int main(int argc, char*argv[]) {//输入图像矩阵//Mat img = imread("2.png", CV_LOAD_IMAGE_GRAYSCALE);Mat img = imread("2.png");if (!img.data)return -1;namedWindow("原图", WINDOW_AUTOSIZE);imshow("原图", img);//转换成灰度图,浮点型图Mat fImg;cvtColor(img, img, CV_BGR2GRAY); img.convertTo(fImg, CV_64FC1);//快速傅里叶变换Mat fftImage;ImageDFT(fImg, fftImage);//傅里叶逆变换Mat image;cv::dft(fftImage, image, DFT_INVERSE + DFT_REAL_OUTPUT + DFT_SCALE);Mat planes[2];split(fftImage, planes);cout << fftImage.channels() << endl;magnitude(planes[0], planes[1], planes[0]);Mat magnitudeImage = planes[0];magnitudeImage += Scalar::all(1); // 所有的像素都加1log(magnitudeImage, magnitudeImage); // 求自然对数normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX);magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));int cx = magnitudeImage.cols / 2;int cy = magnitudeImage.rows / 2;Mat q0(magnitudeImage, Rect(0, 0, cx, cy)); Mat q1(magnitudeImage, Rect(cx, 0, cx, cy)); Mat q2(magnitudeImage, Rect(0, cy, cx, cy)); Mat q3(magnitudeImage, 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("fft图", magnitudeImage);//裁剪傅里叶逆变换image = image(Rect(0, 0, img.cols, img.rows));image.convertTo(image, CV_8UC1);namedWindow("逆变换图", WINDOW_AUTOSIZE);imshow("逆变换图", image);waitKey(0);return 0; }

参考文献:

https://www.zhihu.com/question/355013340

https://blog.csdn.net/xddwz/article/details/110938652

https://blog.csdn.net/Moment3/article/details/79333781?utm_source=blogxgwz7

https://blog.csdn.net/qazwsxrx/article/details/104672192

总结

以上是生活随笔为你收集整理的图像的傅里叶变换和逆变换C++版的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。