关于中值滤波算法,以及C语言实现

2023-05-16

1、什么是中值滤波?

中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊。

中值滤波可以过滤尖峰脉冲。目的在于我们对于滤波后的数据更感兴趣。滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响。

    以一维信号的中值滤波举例。对灰度序列80、120、90、200、100、110、70,如果按大小顺序排列,其结果为70、80、90、10O、110、120、200,其中间位置上的灰度值为10O,则该灰度序列的中值即为100。一维信号中值滤波实际上就是用中值代替规定位置(一般指原始信号序列中心位置)的信号值。对前面所举的序列而言,中值滤波的结果是用中值100替代序列80、120、90、200、100、110、70中的信号序列中心位置值200,得到的滤波序列就是80、120、90、100、100、110、70。如果在此序列中200是一个噪声信号,则用此方法即可去除这个噪声点。

    二维中值滤波算法是:对于一幅图像的象素矩阵,取以目标象素为中心的一个子矩阵窗口,这个窗口可以是3*3 ,5*5 等根据需要选取,对窗口内的象素灰度排序,取中间一个值作为目标象素的新灰度值。窗口示例如ooooxoooo上面x为目标象素,和周围o组成3*3矩阵Array,然后对这9个元素的灰度进行排序,以排序后的中间元素Array[4]为x的新灰度值,如此就完成对象素x的中值滤波,再迭代对其他需要的象素进行滤波即可。

图像处理中,中值滤波的实现方法

1:通过从 图像中的某个 采样窗口取出奇数个数据进行排序
2: 用排序后的中值取代要处理的数据即可
中值滤波的算法实现过程,重点是排序,最常用的冒泡排序~~
把滤波区间的数据从小到大进行排序,然后取中值,(如果是奇数个数据,那么中值就只有一个了,如果偶数个数据,中值有两个,可以对两个数据再求平均)
下面是一个C语言实现中值滤波的函数:
unsigned char GetMedianNum(int * bArray, int iFilterLen)
{
	int i,j;// 循环变量
	unsigned char bTemp;
	
	// 用冒泡法对数组进行排序
	for (j = 0; j < iFilterLen - 1; j ++)
	{
		for (i = 0; i < iFilterLen - j - 1; i ++)
		{
			if (bArray[i] > bArray[i + 1])
			{
				// 互换
				bTemp = bArray[i];
				bArray[i] = bArray[i + 1];
				bArray[i + 1] = bTemp;
			}
		}
	}
	
	// 计算中值
	if ((iFilterLen & 1) > 0)
	{
		// 数组有奇数个元素,返回中间一个元素
		bTemp = bArray[(iFilterLen + 1) / 2];
	}
	else
	{
		// 数组有偶数个元素,返回中间两个元素平均值
		bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
	}

	return bTemp;
}


注:bArray 是一个整形指针,我们传入的一般是一个数组,用来存储待排序的数据
    iFilterLen 是滤波器的长度
   用在图像处理中时,由于像素的取值范围是0~255,刚好是unsigned char 的范围,所以函数的返回值是unsigned char,如果我们要处理的数是float型,或其他类型,返回值也可以更改~~返回值是bTemp,也即是我们想得到的中值
下面是一个完整的C语言程序,用在图像处理中
/*************************************************************************
 * 函数名称:
 *   MedianFilter()
 * 参数:
 *   int   iFilterH			- 滤波器的高度
 *   int   iFilterW			- 滤波器的宽度
 *   int   iFilterMX		- 滤波器的中心元素X坐标
 *   int   iFilterMY		- 滤波器的中心元素Y坐标
 * 说明:
 *   该函数对DIB图像进行中值滤波。
 ************************************************************************/
#define iFilterW 1
#define iFilterH 1
#define iFilterMX 1
#define iFilterMY 1
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)


unsigned char GetMedianNum(int * bArray, int iFilterLen);
void MedianFilter(unsigned char *pImg1,unsigned char *pImg,int nWidth,int nHeight)
{		
    unsigned char   *lpSrc;			                // 指向源图像的指针	
	unsigned char   *lpDst;		                 	// 指向要复制区域的指针
	int         aValue[iFilterH*iFilterW];		    // 指向滤波器数组的指针
	int			i,j,k,l;		                    // 循环变量	
	int			lLineBytes;		                    // 图像每行的字节数	
	lLineBytes = WIDTHBYTES(nWidth * 8);
	for ( i=0;i<nWidth;i++,pImg++ )
		(*pImg)=0;
	// 开始中值滤波
	// 行(除去边缘几行)
	for(i = iFilterMY; i < nHeight - iFilterH + iFilterMY + 1; i++)
	{
		// 列(除去边缘几列)
		for(j = iFilterMX; j < nWidth - iFilterW + iFilterMX + 1; j++)
		{
			// 指向新DIB第i行,第j个象素的指针
			lpDst = pImg + lLineBytes * (nHeight - 1 - i) + j;
			
			// 读取滤波器数组
			for (k = 0; k < iFilterH; k++)
			{
				for (l = 0; l < iFilterW; l++)
				{
					// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针
					lpSrc = pImg1 + lLineBytes * (nHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l;
				
					// 保存象素值
					aValue[k * iFilterW + l] = *lpSrc;
				}
			}
			
			// 获取中值
			* lpDst = GetMedianNum(aValue, iFilterH * iFilterW);
		}
	}

}

unsigned char GetMedianNum(int * bArray, int iFilterLen)
{
	int		i,j;			// 循环变量
	unsigned char bTemp;
	
	// 用冒泡法对数组进行排序
	for (j = 0; j < iFilterLen - 1; j ++)
	{
		for (i = 0; i < iFilterLen - j - 1; i ++)
		{
			if (bArray[i] > bArray[i + 1])
			{
				// 互换
				bTemp = bArray[i];
				bArray[i] = bArray[i + 1];
				bArray[i + 1] = bTemp;
			}
		}
	}
	
	// 计算中值
	if ((iFilterLen & 1) > 0)
	{
		// 数组有奇数个元素,返回中间一个元素
		bTemp = bArray[(iFilterLen + 1) / 2];
	}
	else
	{
		// 数组有偶数个元素,返回中间两个元素平均值
		bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
	}
	
	return bTemp;
}





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于中值滤波算法,以及C语言实现 的相关文章

  • [C++][原创]ubuntu上C++发送http请求get和post

    找到一个开源项目 xff1a GitHub elnormous HTTPRequest Single header C 43 43 HTTP request class 使用项目都有介绍 xff0c 很简单 xff0c 这里我在ubuntu
  • 网络通信编程(UDP和TCP协议的实现)

    网络通信 1 网络编程入门1 1网络编程概述1 2网络编程三要素第一要素第二要素第三要素 1 3IP地址 xff08 网络中设备的唯一标识 xff09 常用命令特殊IP地址 1 4InetAddress类的使用 xff08 为了方便对IP地
  • STM32F0 HAL库的串口中断调用顺序

    首先在主函数里执行发送中断或者接收中断函数 xff1a HAL UART Receive IT amp UartHandle uint8 t RxBuf 1 HAL UART Transmit IT amp UartHandle uint8
  • 最全综述 | 图像分割算法

    点击上方 AI算法与图像处理 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 图像分割是计算机视觉研究中的一个经典难题 xff0c 已经成为图像理解领域关注的一个热点 xff0c 图像分割是图像分析的第一
  • CNN的Flatten操作 | Pytorch系列(七)

    点击上方 AI算法与图像处理 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 文 AI study 欢迎回到这个关于神经网络编程的系列 在这篇文章中 xff0c 我们将可视化一个单一灰度图像的张量flat
  • PyTorch中Linear层的原理 | PyTorch系列(十六)

    点击上方 AI算法与图像处理 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 文 AI study 原标题 xff1a PyTorch Callable Neural Networks Deep earn
  • python-opencv报错:QObject::moveToThread: Current thread

    报错 xff1a QObject moveToThread Current thread 0x55ab2a343120 is not the object s thread 0x55ab2a4f8820 Cannot move to tar
  • 谷歌又放大招 Disco Diffusion!AI生成超高质量绘画!

    En点击下方 AI算法与图像处理 xff0c 一起进步 xff01 重磅干货 xff0c 第一时间送达 大家好 xff0c 我是 阿潘 xff5e 我在b站刷到了一个博主分享最新的算法 xff0c 用AI生成高质量的插画 本文主要是分享现在
  • ikun必学!python 画一个简单的只因

    大家好呀 xff0c 我是阿潘 现在有很多虚假的ikun 1 看似维护鸡哥 xff0c 实则想吃鸡哥下的蛋 每次看到这种网络攻击 xff0c 鼻子一酸 xff0c 泪流不止 这个世界太不友善了 xff0c 真的不知道面对那么多无端的谩骂他是
  • CVPR2023论文速递(2023.3.23)!已接入ChatGPT总结!共26篇!

    整理 xff1a AI算法与图像处理 CVPR2023论文和代码整理 xff1a https github com DWCTOD CVPR2023 Papers with Code Demo 欢迎关注公众号 AI算法与图像处理 xff0c
  • 5个python常用的装饰器!

    大家好呀 xff0c 我是阿潘 首先 xff0c 每个开发人员的目标都是让事情正常进行 慢慢地 xff0c 我们担心可读性和可扩展性 这是我们第一次开始考虑装饰器的时候 装饰器是为函数提供额外行为的绝佳方式 使用装饰器 xff0c 你会惊讶
  • PerSAM!单图即可定制专属SAM模型!支持微调,甚至可增强DreamBooth

    大家好呀 xff0c 我是阿潘 Meta 的 Segment Anything Model 着实火了一把 xff0c 今天来和大家分享一篇相关的研究成果 xff0c 论文和代码都已开源 xff1a 从标题的字面意思应该就是指仅需一个样本即可
  • Python绘制可爱的卡通人物 | 【turtle使用】

    Turtle库 简介 什么是Turtle 首先 xff0c turtle库是一个点线面的简单图像库 xff0c 能够完成一些比较简单的几何图像可视化 它就像一个小乌龟 xff0c 在一个横轴为x 纵轴为y的坐标系原点 xff0c 0 0 位
  • STM32 Keil5 Bug记录 汇总和解决办法

    STM32 Keil5 Bug记录 汇总和解决办法 文章目录 STM32 Keil5 Bug记录 汇总和解决办法前言一 Warning1 warning no newline at end of file2 warning function
  • STM32重要源文件和头文件说明

    对于STM32F4xx StdPeriph Driver xff0c 其重要源文件为 xff1a stm32f4xx ppp h xff1a 外设头文件 这里的ppp只是一个代码 xff0c 在实际上是具体的外设名字 xff0c 如ADC
  • 带参宏定义和带参函数的区别

    在带参宏定义中 xff0c 不会为形式参数分配内存 xff0c 因此不必指明数据类型 而在宏调用中 xff0c 实参包含了具体的数据 xff0c 要用它们去代换形参 xff0c 因此必须指明数据类型 这一点和函数是不同的 xff1a 在函数
  • “段寄存器”的故事

    一 段寄存器的产生 段寄存器的产生源于Intel 8086 CPU体系结构中数据总线与地址总线的宽度不一致 数据总线的宽度 xff0c 也即是ALU 算数逻辑单元 的宽度 xff0c 平常说一个CPU是 16位 或者 32位 指的就是这个
  • 阿里面试官:为什么MySQL数据库索引选择使用B+树而不是跳表?

    来源 xff1a https www cnblogs com andydao p 12891690 html 作者 xff1a andydaopeng 在进一步分析为什么MySQL数据库索引选择使用B 43 树之前 xff0c 我相信很多小
  • AD生成bom表

    1 Report Bill of material 2 可通过点击右侧的Columns xff0c 更改导出属性 3 点击Preview 查看生成的excel文件 4 生成的 excel文件 注 xff1a 出bom表的原理图需要在工程里
  • 你对Linux下的实时性应该多点了解

    本文讲述一些有利于提高xenomai实时性的配置建议 xff0c 部分针对X86架构 xff0c 但它们的底层原理相通 xff0c 同样适用于其他CPU架构和系统 xff0c 希望对你有用 一 前言 1 什么是实时 实时 一词在许多应用领域

随机推荐

  • HTTP/3.0 ,它来了!

    HTTP 3 0 是 HTTP 协议的第三个主要版本 xff0c 前两个分别是 HTTP 1 0 和 HTTP 2 0 xff0c 但其实 HTTP 1 1 我认为才是真正的 HTTP 1 0 我们大家知道 xff0c HTTP 是应用层协
  • 简单聊聊从 nginx 到 kong 的进化

    在我们的传统业务中 xff0c Nginx 在七层网关场景中应用得很广 但是最近几年由于微服务的盛行 Nginx 上的这套生态链也在不断地进化 2007 年国人章亦春大神在 Nginx 的基础上开发出了 OpenResty 2009 年 m
  • golang中的缓存一致性、内存序、内存屏障与CAS原理

    CPU缓存架构 现代处理器一般是多核架构 xff0c 并且为了平衡CPU和内存的速度差距 xff0c 还引入了多级Cache CPU Cache 是由很多个 Cache Line 组成 xff0c 每个Cache Line大小为64KB C
  • HashMap与红黑树

    一 为什么需要HashMap 在我们写程序的时候经常会遇到数据检索等操作 xff0c 对于几百个数据的小程序而言 xff0c 数据的存储方式或是检索策略没有太大影响 xff0c 但对于大数据 xff0c 效率就会差很远 1 线性检索 xff
  • docker执行报错:no such file or directory: unknown

    在linux下编译的golang程序放到docker的busybox镜像里无法执行 xff0c 显示报错信息 xff1a exec No such file or directory 在Docker化的今天 xff0c 我们经常需要静态编译
  • 香烟价格

    上海地区报价 欢迎补漏 改错 有的价格过高或偏底是地域不同 品名 产地 批发 零售 白沙 xff08 硬盒 xff09 长沙卷烟厂 42 00 4 50 白沙 xff08 软盒 xff09 长沙卷烟厂 37 00 4 00 芙蓉 xff08
  • java关键字Transient

    Java的serialization提供了一种持久化对象实例的机制 当持久化对象时 xff0c 可能有一个特殊的对象数据成员 xff0c 我们不想用serialization机制来保存它 为了在一个特定对象的一个域上关闭serializat
  • 拨打国际电话的国际字冠和国家代码

    中国 字冠 代码 中国大陆 00 86 中国香港 001 852 中国澳门 01 853 中国台湾 002 886 其它国家或地区 序号 国家 国际字冠 国家代码 1 美国 011 1 2 加拿大 011 1 3 智利 0 56 4 秘鲁
  • VirtualBox Host-Only 连接设置

    1 VirtualBox连接方式选择 xff1a Host Only 在宿主机windows上会自动新建连接 xff1a VirtualBox Host Only Network 2 启用宿主机windows的连接共享 xff0c 此时Vi
  • 基于HHARM9-EDU的TCP/IP(UDP)协议的实现

    基于HHARM9 EDU的TCP IP UDP 协议的实现 摘 要 xff1a 嵌入式技术的发展日新月异 xff0c 现如今 xff0c 嵌入式设备已经广泛应用于各种网络 xff0c 本文简要地说明一下如何实现 PC 与 HHARM9 ED
  • 简单的linux c socket例子

    服务端代码 xff1a span style color 000000 span style color 0000cc span span style color ff0000 include span span style color 0
  • Mask R-CNN图像识别和分割实现步骤(二)

    一 搭建环境 xff08 widdows10 xff09 xff08 一 xff09 安装anaconda3 1 下载地址 xff1a Anaconda Individual Edition 2 安装步骤 xff1a 图上双击 xff0c
  • C++ STL

    C 43 43 STL vector 变长数组 xff0c 倍增的思想 size 返回元素个数 empty 返回是否为空 clear 清空 front back push back pop back begin end 支持比较运算 xff
  • 结构体对齐规则

    结构体对齐规则 xff1a 1 第一个成员在于结构体变量偏移量为0的地址处 2 其他成员变量要对齐到某个数字 xff08 对齐数 xff09 的整数倍的地址处 对齐数 61 编译器默认的一个对齐数 与 该成员大小的 较小值 3 结构体总大小
  • 串口通信数据位长度对传输数据的影响

    针对串口通信 xff0c 关于设置数据位长度对通信的影响 xff0c 如图 xff1a 在串口数据通信中 xff0c 会看到串口参数设置 其中 数据位 设置 xff0c 共有四档选项 xff0c 分别是8 7 6 5 那么改变这个参数会对数
  • 建议收藏丨你想了解的动捕内容全在这儿!

    导语 对于第一次听说动作捕捉的大多数人而言 xff0c 动作捕捉听起来是一个 34 高级 34 同时 摸不清门路 的词汇 它作为虚拟与现实的沟通桥梁 xff0c 被应用于科学研究 影视制作 虚拟主播 体育运动 步态分析等广泛领域 xff0c
  • ROS速成之发送&接收消息

    人真的老了 xff0c 扔了个周末 xff0c 完全不记得干了什么 论纪录的重要性啊 xff0c 当时觉得明白的很 xff0c 你扔两天试试 xff1f 扔一年试试 xff1f 扔几年试试 xff1f 最近参加的各种项目脑疼眼乏 xff0c
  • MFC VC 双缓冲绘图基本原理与实现,详细解释

    MFC VC 双缓冲绘图基本原理与实现 xff0c 详细解释 MFC做了一些时间了 xff0c 不得不面对 的是在界面上画图的 当然你可以直接搜索到能用的代码 xff0c 并且基本能满足要求 不过这样总不是学习的态度 本着学习分享的态度 x
  • 关于dlg.DoModal()==IDOk的理解

    问题1 xff1a if dlg DoModal 61 61 IDOK 怎么理解啊 xff1f 问题2 xff1a 当我 CMyDlg dlg 时 xff0c 对话框显示了吗 xff1f 是不是要写dlg DoModal 这时对话框才显示出
  • 关于中值滤波算法,以及C语言实现

    1 什么是中值滤波 xff1f p p p style line height 28px margin top 0px margin bottom 10px padding top 0px padding bottom 0px color