OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering)

这篇具有很好参考价值的文章主要介绍了OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

实现原理

       AMF(Adaptive Median Filter,自适应中值滤波)是一种用于图像处理和信号处理的滤波算法,其目的是在保持图像细节的同时去除噪声。它是基于中值滤波的一种改进,可以根据局部像素的灰度值特征自适应地调整滤波器的大小和形状。

       AMF算法的主要思想是根据像素邻域的特征动态调整滤波器的尺寸和形状,以适应不同区域的噪声水平和图像细节。具体步骤如下:

  1. 参数和初始化

    • 函数接受一个输入图像input和一个整数参数winSize,表示滤波器的初始大小。
    • 创建一个和输入图像大小相同的输出图像output,用于存储滤波结果。
    • 变量 R 为窗口半径的最大限制值。
  2. 并行遍历处理图像每个像素

    • 使用 OpenMP 实现并行化,对图像的每一个像素进行处理。注意需要在设置里打开OpenMP。
  3. 窗口处理

    • 对于每个像素(i, j),以其为中心构建一个大小为(2*r+1)*(2*r+1)的窗口。
    • 在窗口边界进行限制,防止越界。
  4. 窗口数据排序

    • 将窗口内的像素值存储在 datas 向量中,并进行排序。
  5. 计算中值和最值

    • 计算排序后的数据中的最小值 minValue、最大值 maxValue 和中值 midValue
  6. 判断是否需要扩大窗口

    • 根据中值与最小值、最大值的差值是否超过某个阈值 thresh 来决定是否需要扩大窗口。
    • 如果窗口内的中值不在最小值和最大值之间一定范围内,则继续扩大窗口,直到r大于R。
  7. 滤波处理

    • 如果当前像素值与窗口最值的差值大于阈值,说明不需要滤波,直接将当前像素值赋给输出图像的对应位置。
    • 否则,将窗口内的中值赋给输出图像的对应位置。
  8. 返回结果

    • 返回处理后的输出图像。

       AMF算法的优点是能够有效地处理不同区域的噪声和图像细节,因为它在滤波器大小和形状上具有自适应性。然而,它也有一些缺点,比如计算复杂度较高,处理速度较慢,特别是对于大尺寸的滤波器。

       总的来说,AMF算法是一种灵活而有效的滤波器,特别适用于那些噪声水平不均匀且图像细节丰富的场景,尤其是针对椒盐噪声。

功能函数代码

// AMF算法(Adaptive Median Filtering)
cv::Mat adaptiveMedianFiltering(cv::Mat input, int winSize)
{
	int row = input.rows;
	int col = input.cols;
	cv::Mat output(row, col, CV_8UC1);
	int R = winSize / 2;
	// 遍历处理
#pragma omp parallel for
	for (int i = 0; i < row; i++)
	{
		vector<float> datas;
		for (int j = 0; j < col; j++)
		{
			int r = 1;
			while (r <= R)
			{
				// 卷积窗口边界限制,防止越界
				int ms = ((i - r) > 0) ? (i - r) : 0;
				int me = ((i + r) < (row - 1)) ? (i + r) : (row - 1);
				int ns = ((j - r) > 0) ? (j - r) : 0;
				int ne = ((j + r) < (col - 1)) ? (j + r) : (col - 1);
				// 窗口内有效数据排序
				datas.clear();
				for (int m = ms; m <= me; ++m)
				{
					for (int n = ns; n <= ne; ++n)
					{
						datas.push_back(float(input.at<uchar>(m, n)));
					}
				}
				sort(datas.begin(), datas.end());
				// 计算数值
				float minValue = datas[0];
				float maxValue = datas[datas.size() - 1];
				float midValue = datas[datas.size() / 2];
				// 若窗口内中值不为在最值一定范围内,则说明当前窗口尺寸足够,不需要扩展也可完成有效滤波;反之,则继续扩大窗口,直到最大窗口尺寸
				float thresh = (maxValue - minValue) * 0.02f;
				if ((midValue - minValue) > thresh && (maxValue - midValue) > thresh)
				{
					// 若数据本身就不为最值,则不需要滤波,这也是自适应算法保持高分辨的关键
					if ((input.at<uchar>(i, j) - minValue) > thresh && (maxValue - input.at<uchar>(i, j)) > thresh)
					{
						output.at<uchar>(i, j) = input.at<uchar>(i, j);
					}
					// 若为最值,则说明当前数值大概率是噪声信息,进行中值滤波
					else
					{
						output.at<uchar>(i, j) = uchar(midValue);
					}
					break;
				}
				else
				{
					r++;
				}
				// 如果窗口尺寸达到限制了,则直接滤波
				if (r > R)
				{
					output.at<uchar>(i, j) = uchar(midValue);
				}
			}
		}
	}
	return output;
}

C++测试代码

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

using namespace std;
using namespace cv;

// AMF算法(Adaptive Median Filtering)
cv::Mat adaptiveMedianFiltering(cv::Mat input, int winSize)
{
	int row = input.rows;
	int col = input.cols;
	cv::Mat output(row, col, CV_8UC1);
	int R = winSize / 2;
	// 遍历处理
#pragma omp parallel for
	for (int i = 0; i < row; i++)
	{
		vector<float> datas;
		for (int j = 0; j < col; j++)
		{
			int r = 1;
			while (r <= R)
			{
				// 卷积窗口边界限制,防止越界
				int ms = ((i - r) > 0) ? (i - r) : 0;
				int me = ((i + r) < (row - 1)) ? (i + r) : (row - 1);
				int ns = ((j - r) > 0) ? (j - r) : 0;
				int ne = ((j + r) < (col - 1)) ? (j + r) : (col - 1);
				// 窗口内有效数据排序
				datas.clear();
				for (int m = ms; m <= me; ++m)
				{
					for (int n = ns; n <= ne; ++n)
					{
						datas.push_back(float(input.at<uchar>(m, n)));
					}
				}
				sort(datas.begin(), datas.end());
				// 计算数值
				float minValue = datas[0];
				float maxValue = datas[datas.size() - 1];
				float midValue = datas[datas.size() / 2];
				// 若窗口内中值不为在最值一定范围内,则说明当前窗口尺寸足够,不需要扩展也可完成有效滤波;反之,则继续扩大窗口,直到最大窗口尺寸
				float thresh = (maxValue - minValue) * 0.02f;
				if ((midValue - minValue) > thresh && (maxValue - midValue) > thresh)
				{
					// 若数据本身就不为最值,则不需要滤波,这也是自适应算法保持高分辨的关键
					if ((input.at<uchar>(i, j) - minValue) > thresh && (maxValue - input.at<uchar>(i, j)) > thresh)
					{
						output.at<uchar>(i, j) = input.at<uchar>(i, j);
					}
					// 若为最值,则说明当前数值大概率是噪声信息,进行中值滤波
					else
					{
						output.at<uchar>(i, j) = uchar(midValue);
					}
					break;
				}
				else
				{
					r++;
				}
				// 如果窗口尺寸达到限制了,则直接滤波
				if (r > R)
				{
					output.at<uchar>(i, j) = uchar(midValue);
				}
			}
		}
	}
	return output;
}

void main()
{
	cv::Mat image = cv::imread("test.jpg", cv::IMREAD_GRAYSCALE);
	// 添加随机椒盐噪声
	int row = image.rows;
	int col = image.cols;
	cv::Mat noise = image.clone();
	for (int i = 0; i < row; i += 10)
	{
		for (int j = 0; j < col; j += 10)
		{
			noise.at<uchar>(i, j) = rand() % 255;
		}
	}
	// 传统中值滤波
	int winSize = 15;
	cv::Mat median;
	cv::medianBlur(noise, median, winSize);
	// AMF算法处理
	cv::Mat resultimage = adaptiveMedianFiltering(noise, winSize);
	// 显示
	cv::imshow("ori", image);
	cv::imshow("noise", noise);
	cv::imshow("AMF", resultimage);
	cv::waitKey(0);
	cout << "end." << endl;
}

测试效果 

OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering),OpenCV,opencv,算法,计算机视觉
图1 原图
OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering),OpenCV,opencv,算法,计算机视觉
图2 噪声图
OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering),OpenCV,opencv,算法,计算机视觉
图3 传统中值滤波算法效果
OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering),OpenCV,opencv,算法,计算机视觉
图4 AMF算法效果图

       如上图所示,AMF算法在保留图像细节的同时有效去除了椒盐噪声。

       Matlab版本见:

Matlab-AMF算法(自适应中值滤波Adaptive Median Filtering)-CSDN博客   

       如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!文章来源地址https://www.toymoban.com/news/detail-857519.html

到了这里,关于OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV 入门教程:中值滤波和双边滤波

    在图像处理和计算机视觉领域,中值滤波和双边滤波是两种常见的滤波方法,用于平滑图像、去除噪声等。 OpenCV 提供了中值滤波和双边滤波的实现函数,使得图像处理更加灵活和高效。本文将以中值滤波和双边滤波为中心,为你介绍使用 OpenCV 进行滤波操作的基本步骤和实例

    2024年02月13日
    浏览(34)
  • [Opencv]中值滤波(medianBlur)

            OPENCV中的均值滤波、方框滤波、高斯滤波,都是线性滤波方式,由于线性滤波的结果是所有像素值的线性组合,因此含有噪声的像素也会被考虑进去,噪声不会被消除,而是以更柔和的方式存在。如果需要去除这些噪声,使用非线性滤波效果可能会更好。中值滤波采

    2024年02月10日
    浏览(45)
  • OpenCV-23中值滤波

    中值滤波原理比较简单,假设有一个数组[1556789],取其中的中间值(即中位数)作为卷积后的结果即可,中值滤波对胡椒噪音(也叫椒盐噪音)效果明显。 对下面带胡椒噪声的图片进行处理。 注意点: 方和滤波和均值滤波和高斯滤波的dsize均为元组,中值滤波为整数。 示例代

    2024年01月17日
    浏览(50)
  • OpenCV(二十三):中值滤波

    1.中值滤波的原理        中值滤波(Median Filter)是一种常用的非线性图像滤波方法,用于去除图像中的椒盐噪声等离群点。它的原理是基于邻域像素值的排序,并将中间值作为当前像素的新值。 2.中值滤波函数 medianBlur() void cv::medianBlur ( InputArray   src, OutputArray dst, int  

    2024年02月09日
    浏览(54)
  • Python Opencv实践 - 图像中值滤波

       

    2024年02月12日
    浏览(55)
  • opencv笔记:高斯滤波和中值滤波对椒盐噪声的处理

      目录 1. 椒盐噪声简介 2. 高斯滤波的原理和实现  2.1. 高斯滤波的原理    2.2. 高斯滤波的API  3. 中值滤波的原理和实现   3.1. 中值滤波的原理   3.2. 中值滤波的API 4. 高斯滤波和中值滤波对椒盐噪声的处理结果 数字图像处理中,噪声会导致图像质量下降和信息的丢失,因此

    2024年02月07日
    浏览(51)
  • Opencv之图像滤波:5.中值滤波(cv2.medianBlur)

            之前介绍的均值滤波、方框滤波、高斯滤波,都是线性滤波方式。由于线性滤波的结果是所有像素值的线性组合,因此含有噪声的像素也会被考虑进去,噪声不会被消除,而是以更柔和的方式存在。这时使用非线性滤波效果可能会更好。中值滤波与前面介绍的滤波

    2024年02月06日
    浏览(51)
  • python --opencv图像处理滤波详解(均值滤波、2D 图像卷积、方框滤波、 高斯滤波、中值滤波、双边滤波)

    第一件事情还是先做名词解释,图像平滑到底是个啥? 从字面意思理解貌似图像平滑好像是在说图像滑动。 emmmmmmmmmmmmmmm。。。。 其实半毛钱关系也没有,图像平滑技术通常也被成为图像滤波技术(这个名字看到可能大家会有点感觉)。 每一幅图像都包含某种程度的噪声,

    2024年02月04日
    浏览(64)
  • 中值滤波算法及例程

    中值滤波是一种常用的非线性图像滤波算法,它能够有效去除图像中的椒盐噪声(即孤立的亮或暗像素点),同时保持图像边缘和细节的清晰度。中值滤波的主要思想是使用一个滑动窗口,在窗口内对像素值进行排序,并将排序后的中间值作为中心像素的新值。 以下是中值滤

    2024年02月07日
    浏览(52)
  • Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理

    头文件 quick_opencv.h:声明类与公共函数 主函数调用 src:输入图像 。 dst:输出图像 。 ksize:内核大小 ,一般用 Size(w,h),w 为宽度,h 为深度。 anchor:被平滑的点,表示取 内核中心 ,默认值 Point(-1,-1)。 boderType:推断图像外部像素的某种边界模式。默认值 BORDER_DEFAULT 目的:

    2024年02月16日
    浏览(154)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包