当前位置: 首页 > article >正文

数字图像处理(c++ opencv):图像复原与重建-常见的滤波方法--统计排序滤波器

中值滤波器

中值滤波器原理(Median Filter)

在这里插入图片描述

中值滤波器就是将滤波窗口内像素灰度值的中间值作为滤波结果。中值滤波器与大小相同的线性平滑滤波器相比,能有效地降低某些随机噪声且模糊程度较低,应用较为广泛。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//定义滤波函数
void MedianFilter(Mat img_input, Mat& img_output, int m, int n); //输入图像,输出图像,m,n为滤波器大小。

int main()
{
	Mat image, image_gray, image_output, image_output2;   //定义输入图像,灰度图像,输出图像,输出图像2
	image = imread("高斯噪声.png");  //读取图像;
	if (image.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}
	imshow("image", image);

	//转换为灰度图像
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	imshow("image_gray", image_gray);

	//自己编写的滤波函数
	MedianFilter(image_gray, image_output, 7, 7);
	imshow("image_output", image_output);

	//opencv自带中值滤波
	medianBlur(image_gray, image_output2, 7);
	imshow("image_output2", image_output2);

	waitKey(0);  //暂停,保持图像显示,等待按键结束
	return 0;
}


//实现滤波函数
void MedianFilter(Mat img_input, Mat& img_output, int m, int n)
{
	img_output = img_input.clone();
	int num = m * n;
	vector<uchar> sortarray(num);

	//1、为了保证图像的边缘也能够被滤波,这里首先扩展图像边缘,扩展方法为镜像
	copyMakeBorder(img_input, img_input, (m - 1) / 2, (m - 1) / 2, (n - 1) / 2, (n - 1) / 2, BORDER_REFLECT);

	//2、中值滤波
	for (int i = (m - 1) / 2; i < img_input.rows - (m - 1) / 2; i++)
	{
		for (int j = (n - 1) / 2; j < img_input.cols - (n - 1) / 2; j++)
		{
			int h = 0;
			for (int x = -(m - 1) / 2; x <= (m - 1) / 2; x++)
			{
				for (int y = -(n - 1) / 2; y <= (n - 1) / 2; y++)
				{
					sortarray[h] = img_input.at<uchar>(i + x, j + y);
					h++;
				}
			}
			sort(sortarray.begin(), sortarray.end()); //排序
			img_output.at<uchar>(i - (m - 1) / 2, j - (n - 1) / 2) = sortarray[(num - 1)/2];
		}
	}
}

在这里插入图片描述

最大值滤波器

最大值滤波器原理(Max Filters)

在这里插入图片描述

最大值滤波器就是将滤波窗口内像素灰度值的最大值作为滤波结果。最大值滤波器可以削弱明色区域相邻的暗色区域,可以用来降低胡椒噪声

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//定义滤波函数
void MaxFilter(Mat img_input, Mat& img_output, int m, int n); //输入图像,输出图像,m,n为滤波器大小。

int main()
{
	Mat image, image_gray, image_output;   //定义输入图像,灰度图像,输出图像
	image = imread("胡椒噪声.png");  //读取图像;
	if (image.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}
	imshow("image", image);

	//转换为灰度图像
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	imshow("image_gray", image_gray);

	//自己编写的滤波函数
	MaxFilter(image_gray, image_output, 7, 7);
	imshow("image_output", image_output);

	waitKey(0);  //暂停,保持图像显示,等待按键结束
	return 0;
}


//实现滤波函数
void MaxFilter(Mat img_input, Mat& img_output, int m, int n)
{
	img_output = img_input.clone();
	int num = m * n;
	vector<uchar> sortarray(num);

	//1、为了保证图像的边缘也能够被滤波,这里首先扩展图像边缘,扩展方法为镜像
	copyMakeBorder(img_input, img_input, (m - 1) / 2, (m - 1) / 2, (n - 1) / 2, (n - 1) / 2, BORDER_REFLECT);

	//2、滤波
	for (int i = (m - 1) / 2; i < img_input.rows - (m - 1) / 2; i++)
	{
		for (int j = (n - 1) / 2; j < img_input.cols - (n - 1) / 2; j++)
		{
			int h = 0;
			for (int x = -(m - 1) / 2; x <= (m - 1) / 2; x++)
			{
				for (int y = -(n - 1) / 2; y <= (n - 1) / 2; y++)
				{
					sortarray[h] = img_input.at<uchar>(i + x, j + y);
					h++;
				}
			}
			sort(sortarray.begin(), sortarray.end()); //排序
			img_output.at<uchar>(i - (m - 1) / 2, j - (n - 1) / 2) = sortarray[num - 1];
		}
	}
}

在这里插入图片描述

最小值滤波器

最小值滤波器原理(Min Filter)

在这里插入图片描述

最小值滤波器就是将滤波窗口内像素灰度值的最小值作为滤波结果。最小值滤波可以削弱与暗色区域相邻的明色区域,可以用来降低盐粒噪声

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//定义滤波函数
void MinFilter(Mat img_input, Mat& img_output, int m, int n); //输入图像,输出图像,m,n为滤波器大小。

int main()
{
	Mat image, image_gray, image_output;   //定义输入图像,灰度图像,输出图像
	image = imread("盐粒噪声.png");  //读取图像;
	if (image.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}
	imshow("image", image);

	//转换为灰度图像
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	imshow("image_gray", image_gray);

	//自己编写的滤波函数
	MinFilter(image_gray, image_output, 7, 7);
	imshow("image_output", image_output);

	waitKey(0);  //暂停,保持图像显示,等待按键结束
	return 0;
}


//实现滤波函数
void MinFilter(Mat img_input, Mat& img_output, int m, int n)
{
	img_output = img_input.clone();
	int num = m * n;
	vector<uchar> sortarray(num);

	//1、为了保证图像的边缘也能够被滤波,这里首先扩展图像边缘,扩展方法为镜像
	copyMakeBorder(img_input, img_input, (m - 1) / 2, (m - 1) / 2, (n - 1) / 2, (n - 1) / 2, BORDER_REFLECT);

	//2、滤波
	for (int i = (m - 1) / 2; i < img_input.rows - (m - 1) / 2; i++)
	{
		for (int j = (n - 1) / 2; j < img_input.cols - (n - 1) / 2; j++)
		{
			int h = 0;
			for (int x = -(m - 1) / 2; x <= (m - 1) / 2; x++)
			{
				for (int y = -(n - 1) / 2; y <= (n - 1) / 2; y++)
				{
					sortarray[h] = img_input.at<uchar>(i + x, j + y);
					h++;
				}
			}
			sort(sortarray.begin(), sortarray.end()); //排序
			img_output.at<uchar>(i - (m - 1) / 2, j - (n - 1) / 2) = sortarray[0];
		}
	}
}

在这里插入图片描述

中点滤波器

中点滤波器原理(Midpoint Filter)

在这里插入图片描述

中点滤波器将滤波窗口内像素灰度值最大最小值的均值作为滤波结果。中点滤波器是统计排序滤波器和平均滤波器的组合,适合处理随机噪声,如高斯噪声和均匀噪声。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//定义滤波函数
void MidpointFilter(Mat img_input, Mat& img_output, int m, int n); //输入图像,输出图像,m,n为滤波器大小。

int main()
{
	Mat image, image_gray, image_output;   //定义输入图像,灰度图像,输出图像
	image = imread("高斯噪声.png");  //读取图像;
	if (image.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}
	imshow("image", image);

	//转换为灰度图像
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	imshow("image_gray", image_gray);

	//自己编写的滤波函数
	MidpointFilter(image_gray, image_output, 7, 7);
	imshow("image_output", image_output);

	waitKey(0);  //暂停,保持图像显示,等待按键结束
	return 0;
}


//实现滤波函数
void MidpointFilter(Mat img_input, Mat& img_output, int m, int n)
{
	img_output = img_input.clone();
	int num = m * n;
	vector<uchar> sortarray(num);

	//1、为了保证图像的边缘也能够被滤波,这里首先扩展图像边缘,扩展方法为镜像
	copyMakeBorder(img_input, img_input, (m - 1) / 2, (m - 1) / 2, (n - 1) / 2, (n - 1) / 2, BORDER_REFLECT);

	//2、滤波
	for (int i = (m - 1) / 2; i < img_input.rows - (m - 1) / 2; i++)
	{
		for (int j = (n - 1) / 2; j < img_input.cols - (n - 1) / 2; j++)
		{
			int h = 0;
			for (int x = -(m - 1) / 2; x <= (m - 1) / 2; x++)
			{
				for (int y = -(n - 1) / 2; y <= (n - 1) / 2; y++)
				{
					sortarray[h] = img_input.at<uchar>(i + x, j + y);
					h++;
				}
			}
			sort(sortarray.begin(), sortarray.end()); //排序
			img_output.at<uchar>(i - (m - 1) / 2, j - (n - 1) / 2) = round((sortarray[0] + sortarray[num-1])/2);
		}
	}
}

在这里插入图片描述

修正阿尔法均值滤波器

修正阿尔法均值滤波器原理(Alpha-Trimmed Mean Filter)

在这里插入图片描述

将滤波窗口内像素灰度值的d/2最低值和最高值删除后的平均值作为滤波结果。修正阿尔法均值滤波器适合处理多种混合噪声,如均匀噪声+椒盐噪声。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//定义滤波函数
void AlphaTrimmedMeanFilter(Mat img_input, Mat& img_output, int m, int n, int d); //输入图像,输出图像,m,n为滤波器大小, d为去掉前后像素的个数

int main()
{
	Mat image, image_gray, image_output;   //定义输入图像,灰度图像,输出图像
	image = imread("均匀+椒盐.png");  //读取图像;
	if (image.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}
	imshow("image", image);

	//转换为灰度图像
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	imshow("image_gray", image_gray);

	//自己编写的滤波函数
	AlphaTrimmedMeanFilter(image_gray, image_output, 7, 7, 5);
	imshow("image_output", image_output);

	waitKey(0);  //暂停,保持图像显示,等待按键结束
	return 0;
}


//实现滤波函数
void AlphaTrimmedMeanFilter(Mat img_input, Mat& img_output, int m, int n, int d)
{
	img_output = img_input.clone();
	int num = m * n;
	vector<uchar> sortarray(num);

	//1、为了保证图像的边缘也能够被滤波,这里首先扩展图像边缘,扩展方法为镜像
	copyMakeBorder(img_input, img_input, (m - 1) / 2, (m - 1) / 2, (n - 1) / 2, (n - 1) / 2, BORDER_REFLECT);

	//2、滤波
	for (int i = (m - 1) / 2; i < img_input.rows - (m - 1) / 2; i++)
	{
		for (int j = (n - 1) / 2; j < img_input.cols - (n - 1) / 2; j++)
		{
			int h = 0;
			for (int x = -(m - 1) / 2; x <= (m - 1) / 2; x++)
			{
				for (int y = -(n - 1) / 2; y <= (n - 1) / 2; y++)
				{
					sortarray[h] = img_input.at<uchar>(i + x, j + y);
					h++;
				}
			}
			sort(sortarray.begin(), sortarray.end()); //排序
			int sum = 0;
			for (int k = d; k < num - d - 1; k++)
			{
				sum = sum + sortarray[k];
			}
			img_output.at<uchar>(i - (m - 1) / 2, j - (n - 1) / 2) = round(sum / (num - 2 * d));
		}
	}
}

在这里插入图片描述


http://www.kler.cn/a/394325.html

相关文章:

  • 机器学习【激活函数】
  • 飞牛云fnOS本地部署WordPress个人网站并一键发布公网远程访问
  • 手动实现promise的all,race,finally方法
  • 文件输入输出——NOI
  • 密码学的基本原理
  • 前端垂直居中的多种实现方式及应用分析
  • 机器学习—模型选择和训练交叉验证测试集
  • 鸿蒙HarmonyOS 网络请求获取数据Http
  • 2024-11-12 问AI: [AI面试题] 您将如何设计一个人工智能系统来预测电信公司的客户流失?
  • SpringBoot-自定义注解,拦截器
  • Prometheus面试内容整理-Exporters
  • docker之容器设置开机自启(4)
  • 力扣 LeetCode 242. 有效的字母异位词(Day3:哈希表)
  • 天云数据联手举办“科学传播沙龙”活动,探讨Sora是否会带来新的科学革命
  • 镭速大文件传输软件向金融银行的文档管理提供高效的解决方案
  • Whalestudio助力西南某商业银行数据中台建设 | 实践探索
  • Vue3.js - 一文看懂Vuex
  • Python自动化运维DevSecOps与安全自动化
  • JavaScript——DOM编程、JS的对象和JSON
  • 【大语言模型学习】LORA微调方法
  • 分布式光伏智慧平台建设现场 系统集成商如何盈利
  • 【网络安全 | 漏洞挖掘】隐藏的 DOS 技术
  • 【人工智能】从零开始用Python实现逻辑回归模型:深入理解逻辑回归的原理与应用
  • 【HAProxy09】企业级反向代理HAProxy高级功能之压缩功能与后端服务器健康性监测
  • 图形 2.6 伽马校正
  • 详解一下JVM诊断方法和其工具的使用