频域滤波

这是课程第五次实验,时间太紧了,不是自己写的,难受,有空再改。
要是还能正常上课,我保证上课不睡瞌睡。

之前写的图像傅里叶变换的代码

https://www.cnblogs.com/cyssmile/p/12555602.html

这次实验的代码

#include<opencv2/opencv.hpp>
#include <vector>
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <string>

using namespace cv;
using namespace std;


Mat DFT(const Mat& image);
void genIPF(Mat& H);
Mat IDFT(const Mat& image);
Mat IPF_Filter(const Mat& image);
Mat BPF_Filter(const Mat& image);
//D0截至频率  t通过系数
static int D0, t;
static int unq_n;


int main(int argc, char** argv)
{

	Mat image = imread("D:/images/test.jpg", 0);
	if (!image.data)
	{
		printf("No image data \n");
		return -1;
	}
	//D0截至频率  t通过系数
	D0 = 0;
	t = 2;
	//截至频率
	unq_n = 0;
	Mat new_img;
	new_img = IPF_Filter(image);

	Mat bfp_img;
	bfp_img = BPF_Filter(image);
	namedWindow("Display img", 0);
	namedWindow("Display 理想高通/低通滤波", 0);
	namedWindow("Display 布特沃斯滤波", 0);
	//string name = "new_img";
	imshow("Display img", image);
	//理想高通/低通滤波
	imshow("Display 理想高通/低通滤波", new_img);
	//布特沃斯滤波
	imshow("Display 布特沃斯滤波", bfp_img);

	//imwrite(name, new_img);
	waitKey(0);
	return 0;
}
//理想高通/低通滤波器模板
void genIPF(Mat& H)
{
	int P = H.rows;
	int Q = H.cols;
	for (int u = 0; u < P; u++)
		for (int v = 0; v < Q; v++)
			H.at<float>(u, v) = sqrt(pow(u - P / 2, 2) + pow(v - Q / 2, 2)) > D0 ? abs(0 - t) : abs(1 - t);
}
//布特沃斯滤波器
void genBPF(Mat& I)
{
	int P = I.rows;
	int Q = I.cols;
	for (int u = 0; u < P; ++u)
		for (int v = 0; v < Q; ++v)
			if (t == 0)
				I.at<float>(u, v) = 1 / (1 + pow(sqrt(pow(u - P / 2, 2) + pow(v - Q / 2, 2)) / D0, 2 * unq_n));
			else
				I.at<float>(u, v) = 1 / (1 + pow(D0 / sqrt(pow(u - P / 2, 2) + pow(v - Q / 2, 2)), 2 * unq_n));
}

Mat DFT(const Mat& image) {
	int M = image.rows;
	int N = image.cols;
	int P = 2 * M, Q = 2 * N;

	//填充中心化图像
	Mat fill_img(P, Q, CV_32FC1);
	for (int i = 0; i < M; i++)
		for (int j = 0; j < N; j++)
			fill_img.at<float>(i, j) = (image.at<uchar>(i, j)) * pow(-1, i + j);

	for (int i = M; i < P; i++)
		for (int j = N; j < Q; j++)
			fill_img.at<float>(i, j) = 0;

	//实部(图像本身),虚部(全0),组合到一个Mat
	//Mat planes[] = {Mat_<float>(fill_img), Mat::zeros(fill_img.size(), CV_32F)};
	Mat combine(P, Q, CV_32FC2, Scalar(0, 0));
	for (int i = 0; i < P; i++)
		for (int j = 0; j < Q; j++)
			combine.at<Vec2f>(i, j)[0] = fill_img.at<float>(i, j);
	//对组合Mat进行dft
	dft(combine, combine);
	//对数变换,计算1+log|F|提高显示效果
	Mat f_chart(P, Q, CV_32FC1);
	for (int i = 0; i < P; i++)
		for (int j = 0; j < Q; j++)
			f_chart.at<float>(i, j) = 1 + log(sqrt(pow(combine.at<Vec2f>(i, j)[0], 2) + pow(combine.at<Vec2f>(i, j)[1], 2)));

	f_chart.convertTo(f_chart, CV_8UC1);
	normalize(f_chart, f_chart, 0, 255, NORM_MINMAX);
	namedWindow("Display f_chart", WINDOW_NORMAL);
	imshow("Display f_chart", f_chart);
	imwrite("f_chart.jpg", f_chart);
	return combine;
}

Mat IDFT(const Mat& image) {
	int P = image.rows;
	int Q = image.cols;
	Mat f(P, Q, CV_32FC1);
	dft(image, f, DFT_INVERSE | DFT_REAL_OUTPUT | DFT_SCALE);

	for (int i = 0; i < P; i++)
		for (int j = 0; j < Q; j++)
			f.at<float>(i, j) *= pow(-1, i + j);
	f.convertTo(f, CV_8UC1);
	return f;
}

Mat IPF_Filter(const Mat& image)
{
	Mat F = DFT(image);

	//生成滤波器
	int M = image.rows;
	int N = image.cols;
	int P = 2 * M, Q = 2 * N;
	Mat H(P, Q, CV_32FC1);
	genIPF(H);

	//滤波
	Mat G = F;
	for (int i = 0; i < P; i++)
		for (int j = 0; j < Q; j++) {
			//虚实部都要滤波
			G.at<Vec2f>(i, j)[0] = F.at<Vec2f>(i, j)[0] * H.at<float>(i, j);
			G.at<Vec2f>(i, j)[1] = F.at<Vec2f>(i, j)[1] * H.at<float>(i, j);
		}
	//逆变换并截取
	Mat new_img = IDFT(G)(Range(0, M), Range(0, N));
	return new_img;
}

Mat BPF_Filter(const Mat& image)
{
	Mat F = DFT(image);

	int M = image.rows;
	int N = image.cols;
	int P = 2 * M, Q = 2 * N;
	Mat H(P, Q, CV_32FC1);
	genBPF(H);

	Mat G = F;
	for (int i = 0; i < P; i++)
		for (int j = 0; j < Q; j++)
		{
			G.at<Vec2f>(i, j)[0] = F.at<Vec2f>(i, j)[0] * H.at<float>(i, j);
			G.at<Vec2f>(i, j)[1] = F.at<Vec2f>(i, j)[1] * H.at<float>(i, j);
		}
	Mat new_img = IDFT(G)(Range(0, M), Range(0, N));
	return new_img;
}

实验效果

我看了下这个代码,明显有不对的地方,明天起来自己写,这个代码仅供参考。

猜你喜欢

转载自www.cnblogs.com/cyssmile/p/13179684.html