#include <iostream>
#include <opencv2/opencv.hpp>
#define WITH 600
#define window1 "【原图】"
#define window2 "【效果图】"
using namespace cv;
using namespace std;
void convolve_dft(Mat& a, Mat& b, Mat& c);
//计算两个图片的卷积,一个图片为灰度图, 另一个图片为简单核。设置为核心。(3x3)
int main()
{
//1.原图像。
Mat src = imread("女战士.jpg", 0);
resize(src, src, Size(), 0.4, 0.4);
imshow(window1, src);
if (!src.data) cout << "error,no signal input!";
//2.定义卷积核。
Mat kernel(3, 3, CV_8UC1);
kernel.at<uchar>(0, 0) = -1;
kernel.at<uchar>(0, 1) = 0;
kernel.at<uchar>(0, 2) = 1;
kernel.at<uchar>(1, 0) = -2;
kernel.at<uchar>(1, 1) = 1;
kernel.at<uchar>(1, 2) = 2;
kernel.at<uchar>(2, 0) = 1;
kernel.at<uchar>(2, 1) = 0;
kernel.at<uchar>(2, 2) = -1;
//3.调用卷积函数进行卷积。
Mat c;
src.convertTo(src,CV_32F);
kernel.convertTo(kernel,CV_32F);
convolve_dft(src, kernel, c);
//4.归一化。
normalize(c,c,0,1,NORM_MINMAX);
imshow(window2, c);
waitKey(0);
return 0;
}
void convolve_dft(Mat& a, Mat& b, Mat& c)
{
//1.确定c的尺寸,长宽大小为a-b+1
int csize = a.cols - b.cols + 1;
int rsize = a.rows - b.rows + 1;
c.create(rsize, csize, CV_32F);
//2.定义临时变量,al,bl,大小为a+b-1,经过傅里叶尺寸转换所得。
Size dftsize;
dftsize.width = getOptimalDFTSize(a.cols + b.cols - 1);//最合适的傅里叶尺寸。
dftsize.height = getOptimalDFTSize(a.rows + b.rows - 1);
Mat al(dftsize, a.type(), Scalar(Scalar::all(0)));
Mat bl(dftsize, b.type(), Scalar(Scalar::all(0)));//必须为浮点型。
//3.将a和b分别复制到a1和b1.
Mat x1(al, Rect(0, 0, a.cols, a.rows));
Mat y1(bl, Rect(0, 0, b.cols, b.rows));
a.copyTo(x1);
b.copyTo(y1);
//4.对a1,b1,进行傅里叶转换。
dft(al, al, 0, a.rows);
dft(bl, bl, 0, b.rows);
//5.对傅里叶结果进行点ji。
mulSpectrums(al, bl, al, DFT_COMPLEX_OUTPUT);//逐点想乘。...............................................
//6.对结果进行傅里叶逆变换,得到卷积。
dft(al, al, DFT_INVERSE + DFT_SCALE, c.rows);
//7.将结果赋值给c
al(Rect(0, 0, c.cols, c.rows)).copyTo(c);
}