4.2 傅里叶变换

4.2.1 图像掩码操作

filter2D函数:计算图像卷积

 1 ////////https://blog.csdn.net/qq_34784753/article/details/60144935
 2 #include "stdafx.h"
 3 
 4 #include <iostream>
 5 #include <opencv2corecore.hpp>
 6 #include <opencv2highguihighgui.hpp>
 7 #include <opencv2imgprocimgproc.hpp>
 8 
 9 using namespace std;
10 using namespace cv;
11 
12 Mat Myfilter2D(Mat srcImage);
13 Mat filter2D_(Mat srcImage);
14 
15 int main()
16 {
17     Mat srcImage = imread("D:\大海.jpg");
18     if (!srcImage.data)
19     {
20         cout << "读入图片失败" << endl;
21         return -1;
22     }
23     Mat srcGray;
24     cvtColor(srcImage, srcGray, CV_BGR2GRAY);
25     imshow("srcGray", srcGray);
26     Mat resultImage = Myfilter2D(srcGray);
27     imshow("resultImage1", resultImage);
28     resultImage = filter2D_(srcGray);
29     imshow("resultImage2", resultImage);
30     waitKey();
31     return 0;
32 }
33 
34 //基于像素邻域的掩码操作
35 Mat Myfilter2D(Mat srcImage)
36 {
37     const int nChannels = srcImage.channels();
38     Mat resultImage(srcImage.size(), srcImage.type());
39     for (int j = 1; j < srcImage.rows - 1; j++)
40     {
41         //获取邻域指针
42         const uchar* previous = srcImage.ptr<uchar>(j - 1);
43         const uchar* current = srcImage.ptr<uchar>(j);
44         const uchar* next = srcImage.ptr<uchar>(j + 1);
45         uchar * output = resultImage.ptr<uchar>(j);
46         for (int i = nChannels; i < nChannels*(srcImage.cols - 1); ++i)
47         {
48             //进行4-邻域掩码操作
49             *output++ = saturate_cast<uchar>(current[i - nChannels] + current[i + nChannels]
50                 + previous[i] + next[i]) / 4;
51         }
52     }
53 
54     //进行边界处理
55     resultImage.row(0).setTo(Scalar(0));
56     resultImage.row(resultImage.rows - 1).setTo(Scalar(0));
57     resultImage.col(0).setTo(Scalar(0));
58     resultImage.col(resultImage.cols - 1).setTo(Scalar(0));
59     return resultImage;
60 }
61 
62 //使用自带掩码库进行操作
63 Mat filter2D_(Mat srcImage)
64 {
65     Mat resultImage(srcImage.size(), srcImage.type());
66     //构造核函数因子
67     Mat kern = (Mat_<float>(3, 3) << 0, 1, 0,
68         1, 0, 1,
69         0, 1, 0) / (float)(4);
70     filter2D(srcImage, resultImage, srcImage.depth(), kern);
71     return resultImage;
72 }
View Code

4.2.2 离散傅里叶

 1 ///////https://blog.csdn.net/keith_bb/article/details/53389819
 2 #include <iostream>
 3 #include <opencv2/core.hpp>
 4 #include <opencv2/highgui.hpp>
 5 #include <opencv2/imgproc.hpp>
 6 
 7 using namespace std;
 8 using namespace cv;
 9 
10 int main()
11 {
12     Mat I = imread("D:\lena.jpg", IMREAD_GRAYSCALE);       //读入图像灰度图
13 
14                                                         //判断图像是否加载成功
15     if (I.empty())
16     {
17         cout << "图像加载失败!" << endl;
18         return -1;
19     }
20     else
21         cout << "图像加载成功!" << endl << endl;
22 
23     Mat padded;                 //以0填充输入图像矩阵
24     int m = getOptimalDFTSize(I.rows);
25     int n = getOptimalDFTSize(I.cols);
26 
27     //填充输入图像I,输入矩阵为padded,上方和左方不做填充处理
28     copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));
29 
30     Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(),CV_32F) };
31     Mat complexI;
32     merge(planes, 2, complexI);     //将planes融合合并成一个多通道数组complexI
33 
34     dft(complexI, complexI);        //进行傅里叶变换
35 
36                                     //计算幅值,转换到对数尺度(logarithmic scale)
37                                     //=> log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
38     split(complexI, planes);        //planes[0] = Re(DFT(I),planes[1] = Im(DFT(I))
39                                     //即planes[0]为实部,planes[1]为虚部
40     magnitude(planes[0], planes[1], planes[0]);     //planes[0] = magnitude
41     Mat magI = planes[0];
42 
43     magI += Scalar::all(1);
44     log(magI, magI);                //转换到对数尺度(logarithmic scale)
45 
46                                     //如果有奇数行或列,则对频谱进行裁剪
47     magI = magI(Rect(0, 0, magI.cols&-2, magI.rows&-2));
48 
49     //重新排列傅里叶图像中的象限,使得原点位于图像中心
50     int cx = magI.cols / 2;
51     int cy = magI.rows / 2;
52 
53     Mat q0(magI, Rect(0, 0, cx, cy));       //左上角图像划定ROI区域
54     Mat q1(magI, Rect(cx, 0, cx, cy));      //右上角图像
55     Mat q2(magI, Rect(0, cy, cx, cy));      //左下角图像
56     Mat q3(magI, Rect(cx, cy, cx, cy));     //右下角图像
57 
58                                             //变换左上角和右下角象限
59     Mat tmp;
60     q0.copyTo(tmp);
61     q3.copyTo(q0);
62     tmp.copyTo(q3);
63 
64     //变换右上角和左下角象限
65     q1.copyTo(tmp);
66     q2.copyTo(q1);
67     tmp.copyTo(q2);
68 
69     //归一化处理,用0-1之间的浮点数将矩阵变换为可视的图像格式
70     normalize(magI, magI, 0, 1, CV_MINMAX);
71 
72     imshow("输入图像", I);
73     imshow("频谱图", magI);
74     waitKey(0);
75 
76 
77     return 0;
78 }
View Code

4.2.3 图像卷积

 1 ////////https://blog.csdn.net/keith_bb/article/details/53103026
 2 #include <iostream>
 3 #include <opencv2/core.hpp>
 4 #include <opencv2/highgui.hpp>
 5 #include <opencv2/imgproc.hpp>
 6 
 7 using namespace std;
 8 using namespace cv;
 9 
10 int main()
11 {
12     Mat srcImage = imread("D:\彩色lena.jpg");
13 
14     //判断图像是否加载成功
15     if (srcImage.data)
16         cout << "图像加载成功!" << endl << endl;
17     else
18     {
19         cout << "图像加载失败!" << endl << endl;
20         return -1;
21     }
22     namedWindow("srcImage", WINDOW_AUTOSIZE);
23     imshow("srcImage", srcImage);
24 
25     Mat kern = (Mat_<char>(3, 3) << 0, -1, 0,
26         -1, 5, -1,
27         0, -1, 0);
28     Mat dstImage;
29     filter2D(srcImage, dstImage, srcImage.depth(), kern);
30     namedWindow("dstImage", WINDOW_AUTOSIZE);
31     imshow("dstImage", dstImage);
32 
33 
34     waitKey(0);
35 
36     return 0;
37 }
View Code

拓展:

https://blog.csdn.net/qq_32864683/article/details/79748027

https://blog.csdn.net/chaipp0607/article/details/72236892?locationNum=9&fps=1

原文地址:https://www.cnblogs.com/thebreakofdawn/p/9532087.html