本实验为计算机科学与技术学院计算机专业大四上限选课,2023-2024-1年度课程实验,较以往实验内容发生较大变化
本实验使用vs2019,c++语言,需要提前安装opencv,具体方法请自行搜索。
9.1 傅里叶变换
•利用cv::dft对输入图像(可以只考虑单通道图像)进行傅里叶变换,显示其功率谱,并测试非移中和移中的情况。
#include <iostream>
#include <cmath>
#include <opencv2/opencv.hpp>
#include <cfloat>
using namespace std;
using namespace cv;
Mat imgGray, output_image;
void DFT(Mat inputMat)
{
Mat transform_image;
int m = getOptimalDFTSize(inputMat.rows);
int n = getOptimalDFTSize(inputMat.cols);
copyMakeBorder(inputMat, inputMat, 0, m - inputMat.rows, 0, n - inputMat.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = { Mat_<float>(inputMat), Mat::zeros(inputMat.size(), CV_32F) };
merge(planes, 2, transform_image);
dft(transform_image, transform_image);
split(transform_image, planes);
magnitude(planes[0], planes[1], output_image);
output_image += Scalar(1);
log(output_image, output_image);
normalize(output_image, output_image, 0, 1, NORM_MINMAX);
output_image = output_image(Rect(0, 0, output_image.cols & -2, output_image.rows & -2));
imshow("未移中", output_image);
int cx = output_image.cols / 2;
int cy = output_image.rows / 2;
Mat q0(output_image, Rect(0, 0, cx, cy)); // 左上区域
Mat q1(output_image, Rect(cx, 0, cx, cy)); // 右上区域
Mat q2(output_image, Rect(0, cy, cx, cy)); // 左下区域
Mat q3(output_image, 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);//右上与左下进行交换
}
int main()
{
Mat img = imread("C:/Users/13441/Desktop/数字图像/back8.png", IMREAD_GRAYSCALE);
img.convertTo(imgGray, CV_32F);
imshow("原始图像", img);
//imshow("新的图像", imgGray);
Mat dst;
DFT(img);
imshow("移中", output_image);
waitKey(0);
return 0;
}
9.2 频率域滤波
对下图所示输入,进行频率域滤波,去除余弦噪声
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat img, output;
void DST_2()
{
Mat padded;
int m = getOptimalDFTSize(img.rows);
int n = getOptimalDFTSize(img.cols);
copyMakeBorder(img, padded, 0, m - img.rows, 0, n - img.cols, BORDER_CONSTANT, Scalar::all(0));
padded.convertTo(padded, CV_32FC1);
Mat planes[] = { padded, Mat::zeros(padded.size() , CV_32FC1) };
Mat compleximg;
Mat dst(padded.size(), CV_32FC2);
merge(planes, 2, compleximg);
dft(compleximg, compleximg, 0);
split(compleximg, planes);
magnitude(planes[0], planes[1], planes[0]);
planes[0] += Scalar::all(1);
log(planes[0], planes[0]);
double MaxV, MinV;
Point minloc, maxloc;
Mat rem = planes[0](Rect(1, 0, compleximg.cols / 2, 1));
minMaxLoc(rem, &MinV, &MaxV, &minloc, &maxloc);
float* a1 = compleximg.ptr<float>(0, maxloc.x + 1);
float* a2 = compleximg.ptr<float>(0, compleximg.rows - maxloc.x - 1);
float* a3 = compleximg.ptr<float>(compleximg.cols - 1, maxloc.x + 1);
float* a4 = compleximg.ptr<float>(compleximg.cols - 1, compleximg.rows - maxloc.x - 1);
a1[0] = a2[0] = a3[0] = a4[0] = a1[1] = a2[1] = a3[1] = a4[1] = 0;
multiply(compleximg, dst, dst);
normalize(planes[0], planes[0], 1, 0, NORM_MINMAX);
split(dst, planes);
magnitude(planes[0], planes[1], planes[0]);
planes[0] += Scalar::all(1);
log(planes[0], planes[0]);
normalize(planes[0], planes[0], 1, 0, NORM_MINMAX);
idft(dst, dst);
split(dst, planes);
magnitude(planes[0], planes[1], planes[0]);
normalize(planes[0], planes[0], 1, 0, NORM_MINMAX);
output = planes[0];
}
int main()
{
img = imread("C:/Users/13441/Desktop/数字图像/back13.png", 0);
imshow("原始图像", img);
DST_2();
imshow("去噪后", output);
waitKey(0);
return 0;
}