【C++】使用中值滤波算法过滤数据样本中的尖刺噪声

发布于:2025-07-25 ⋅ 阅读:(21) ⋅ 点赞:(0)

目录

前言:

一、中值滤波的基本原理

二、中值滤波的优势

三、中值滤波的局限性

四、中值滤波的应用领域

五、中值滤波算法代码及注释

六、如果这篇文章能帮助到你,请点个赞鼓励一下吧ξ( ✿>◡❛)~


前言:

        中值滤波是一种非线性图像处理技术,广泛用于去除噪声(尤其是椒盐噪声)并保留图像边缘信息,除此之外还可以对样本数据点进行滤波处理,以过滤掉尖刺噪声,以下是其核心原理、实现步骤、应用领域及优缺点的详细解析:

一、中值滤波的基本原理

        中值滤波的核心思想是通过排序统计的方法,将图像中每个像素点的值替换为其邻域内的中值。具体步骤如下:

  • 定义窗口:选择一个奇数大小的滑动窗口(如3×3、5×5),针对一维数据也可以选择如3、5等尺寸作为滑动窗口尺寸,窗口中心为当前像素点。
  • 收集邻域像素值:将窗口覆盖的所有像素值提取出来。
  • 排序与取中值:将这些像素值按大小排序,取中间值作为当前像素的新值。
  • 滑动窗口处理:重复上述步骤,直到图像所有像素都被处理

二、中值滤波的优势

  • 有效去除椒盐噪声
    椒盐噪声表现为孤立的黑白像素点,排序后这些异常值通常位于序列两端,不会成为中值。
  • 保留边缘信息
    相比均值滤波(线性滤波),中值滤波不会平滑边缘细节,避免图像模糊。
  • 计算简单
    实现逻辑清晰,适合硬件加速(如FPGA或GPU)。

三、中值滤波的局限性

  • 对高斯噪声效果有限
    高斯噪声是连续分布的,中值滤波无法有效抑制。
  • 窗口过大会导致模糊
    增大窗口尺寸虽然能增强去噪能力,但可能损失图像细节。
  • 计算开销较高
    需对每个窗口进行排序操作,时间复杂度为 O(k2log⁡k2)O(k2logk2)(kk 为窗口边长)。

四、中值滤波的应用领域

  • 图像去噪
    • 医学影像处理:去除X光或MRI图像中的椒盐噪声,保留关键解剖结构。
    • 卫星遥感:清理传感器噪声,提升地表特征识别精度。
  • 视频处理
    • 实时视频流中去除随机噪声,如摄像头拍摄的低光照场景。
  • 工业检测
    • 在缺陷检测中,保留产品边缘的同时去除背景噪声。
  • 文档扫描
    • 清除扫描图像中的斑点噪声,提升OCR识别准确率。
  • 数据滤波
    • 过滤掉数据样本中的尖刺噪声,如对ADC电压采集数据使用中值滤波,提升数据准确性。

五、中值滤波算法代码及注释

#include "stdlib.h"	    //使用其中的快速排序函数qsort

#define u16 uint16_t

//void 指针经过转化后可以指向任何一个类型
int compare(const void *a, const void *b) 
{
	return (*(int*)a - *(int*)b);	    //实现两个数值比大小函数功能
}

/*****************************************************************************
[函数名称]median_filter
[函数功能]中值滤波算法
[参    数]input:输入数组, output:输出数组, length:数组大小, window_size:滤波窗口大小
[备    注]就是将数组中的所有数据都替换为数组内窗口大小局部数组的中值
*****************************************************************************/
void median_filter(u16 *input, u16 *output, int length, int window_size)
{
    int half_window = window_size / 2;		//计算窗口一半尺寸,用以遍历
    u16 u16WindowBuf[window_size];			//创建缓存窗口数组
 
    for (int i = 0; i < length; i++) 		//开始遍历
	{
        int count = 0;						//创建数组下标变量
        for (int j = -half_window; j <= half_window; j++) //通过交叉滑动窗口遍历数组所有数据
		{
            int index = i + j;
            if (index >= 0 && index < length) 
			{
                u16WindowBuf[count++] = input[index];	//将输入数组的数据加载到窗口数组中
            }
        }
        qsort(u16WindowBuf, count, sizeof(u16), compare); // 对窗口数组内的元素进行排序
        output[i] = u16WindowBuf[count / 2]; //取排序后的中值,对窗口中间数据重新赋值,达到滤波效果
    }
}

六、如果这篇文章能帮助到你,请点个赞鼓励一下吧ξ( ✿>◡❛)~


网站公告

今日签到

点亮在社区的每一天
去签到