1.离散傅里叶变换
void visionagin:: Mydft()
{
Mat src = imread("C:\\Users\\86176\\Downloads\\visionimage\\star.jfif");
resize(src, src, Size(502, 502));
Mat gry;
cvtColor(src, gry, COLOR_BGR2GRAY);
imshow("原图像", gry);
int Row = getOptimalDFTSize(gry.rows);//计算傅里叶变换最适合尺寸
int Col = getOptimalDFTSize(gry.cols);
Mat fitmat;
int t = ( Row - gry.rows) / 2;
int b = Row - gry.rows - t ;
int l = ( Col- gry.cols) / 2;
int r = Col-gry.cols - l ;
copyMakeBorder(gry, fitmat, t, b, l, r, BORDER_CONSTANT, Scalar(0));//边界填充
imshow("扩充后的图像", fitmat);
//构建傅里叶变换输入量
Mat flo[2], complex;
flo[0] = Mat_(fitmat);//实数部分
flo[1] = Mat::zeros(fitmat.size(),CV_32F);//虚数部分cv_32F
merge(flo, 2, complex);//合并
Mat result;//傅里叶变换结果
dft(complex, result);//离散傅里叶变换
//将复数转化为幅值
Mat resultc[2];
split(result, resultc);//将结果分离成实数和虚数部分
Mat amplitude;//幅值
magnitude(resultc[0], resultc[1], amplitude);//计算幅值
//使用对数缩小m1=log(m+1),保证所有值为正
amplitude = amplitude + 1;
log(amplitude, amplitude);//求自然对数
//扩展后的图像与原图像对应的部分
amplitude = amplitude(Rect(t, l, gry.cols, gry.rows));
normalize(amplitude, amplitude, 0, 1, NORM_MINMAX);//归一化
imshow("傅里叶变换后的图像", amplitude);//得到的原点在四个角上
//调整显示图像 左上和右下互换 右上和左下互换
Mat leftup = amplitude(Rect(0, 0, amplitude.cols / 2, amplitude.rows / 2));
Mat rightup = amplitude(Rect(amplitude.cols / 2, 0, amplitude.cols / 2, amplitude.rows / 2));
Mat leftdown= amplitude(Rect(0,amplitude.rows / 2, amplitude.cols / 2, amplitude.rows / 2));
Mat rightdown = amplitude(Rect(amplitude.cols / 2, amplitude.rows / 2, amplitude.cols / 2, amplitude.rows / 2));
//交换
Mat temp1,temp2;
leftup.copyTo(temp1);
rightdown.copyTo(leftup);
temp1.copyTo(rightdown);
rightup.copyTo(temp2);
leftdown.copyTo(rightup);
temp2.copyTo(leftdown);
imshow("调整后的结果", amplitude);
}
2.傅里叶变换进行卷积
void visionagin:: MyMulspectrums()
{
Mat src = imread("C:\\Users\\86176\\Downloads\\visionimage\\star.jfif");
Mat imggry;
cvtColor(src, imggry, COLOR_BGR2GRAY);
imshow("原图", imggry);
Mat gry = Mat_(imggry);//数据转化成float
Mat kernel = (Mat_(5, 5) << 1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1);
Mat result;//构建输出图像
int rwidth = abs(gry.cols - kernel.cols) + 1;
int rheight = abs(gry.rows - kernel.rows) + 1;
result.create(rheight, rwidth, gry.type());
//计算傅里叶变换最优SIZE
int width = getOptimalDFTSize(gry.cols+kernel.cols-1);
int height = getOptimalDFTSize(gry.rows+kernel.rows-1);
Mat tempa;
//扩展输入图像尺寸
int a_t = 0;
int a_b = height- gry.rows ;
int a_l = 0;
int a_r = width- gry.cols ;
copyMakeBorder(gry, tempa, a_t, a_b, a_l, a_r, BORDER_CONSTANT);
//扩展卷积核尺寸
Mat tempk;
int k_t = 0;
int k_b = height - kernel.rows;
int k_l = 0;
int k_r = width - kernel.cols;
copyMakeBorder(kernel, tempk, k_t, k_b, k_l, k_r, BORDER_CONSTANT);
//分别进行傅里叶变换
dft(tempa, tempa, 0, gry.rows);
dft(tempk, tempk, 0, kernel.rows);
mulSpectrums(tempa, tempk, tempa, DFT_COMPLEX_OUTPUT);
//对相乘结果进行逆变换
idft(tempa, tempa, DFT_SCALE,result.rows);//DFT_SCALE
//结果归一化
normalize(tempa, tempa, 0, 1,NORM_MINMAX);
//截取部分图像显示
tempa(Rect(0, 0, result.cols, result.rows)).copyTo(result);
imshow("result", result);
}