完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547

第48章       STM32F407的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)

本章节讲解中值滤波器实现,适用于噪声和脉冲的过滤。

目录

48.1 初学者重要提示

48.2 中值滤波器介绍

48.3 中值滤波器原理

48.4 Matlab中值滤波器实现

48.5 中值滤波器设计

48.5.1        函数MidFilterBlock

48.5.2 函数MidFilterRT

48.5.3 宏定义设置 (重要)

48.5.4 整块数据中值滤波测试

48.5.5 逐个数据中值滤波测试 (支持实时滤波)

48.6 实验例程说明(MDK)

48.7 实验例程说明(IAR)

48.8 总结


48.1 初学者重要提示

1、  ARM DSP库没有提供中值滤波器,所以本章的实现是根据中值滤波器原理做了两个函数,一个函数是一块数据的滤波器实现,另一个函数是实时的逐点滤波实现。

48.2 中值滤波器介绍

中值滤波器是一种非线性数字过滤技术,通常用于消除图像或信号中的噪声。中值滤波器在数字图像处理中被广泛使用。在信号处理中也有应用,通过丢弃所有可疑测量结果来抑制脉冲干扰。有几个输入数据,筛选器计算中值值。

48.3 中值滤波器原理

这里我们通过一个实例来理解中值滤波器。比如我们要对如下五个数据求中值:

x = [14  18  16  21  11]

我们将滤波阶数设置为5,即y = medfilt1(x, 5),表示每5个采样值求一次中值。原理和实现如下:

函数是取x(k-2),x(k-1),  x(k),  x(k+1),  x(k+2)的中值作为输出y(k)。对于y(1),只有x(1), x(2), x(3)存在数值,之前的不存在,对于不存在的补0。每5个数按从小到大排列后取中值有:

y(1)的计算是从[0 0 14 16 18]中取中值是14。

y(2)的计算是从[0 14 16 18 21]中取中值是16。

y(3)的计算是从[11 14 16 18 21]中取中值是16。

y(4)的计算是从0 11 16 18 21]中取中值是16。

y(5)的计算是从[0 0 11 16 21]中取中值是11。

48.4 Matlab中值滤波器实现

首先创建两个混合信号,便于更好测试滤波器效果。

混合信号Mix_Signal_1 = 信号Signal_Original_1+白噪声。

混合信号Mix_Signal_2 = 信号Signal_Original_2+白噪声。

Fs = 1000;                                                          %采样率
N  = 1000;                                                          %采样点数
n  = 0:N-1;
t   = 0:1/Fs:1-1/Fs;                                                %时间序列
Signal_Original_1 =sin(2*pi*10*t)+sin(2*pi*20*t)+sin(2*pi*30*t);
Noise_White_1    = [0.3*randn(1,500), rand(1,500)]; %前500点高斯分部白噪声,后500点均匀分布白噪声
Mix_Signal_1   = Signal_Original_1 + Noise_White_1; %构造的混合信号Signal_Original_2  =  [zeros(1,100), 20*ones(1,20), -2*ones(1,30), 5*ones(1,80), -5*ones(1,30), 9*ones(1,140), -4*ones(1,40), 3*ones(1,220),
12*ones(1,100), 5*ones(1,20), 25*ones(1,30), 7 *ones(1,190)];Noise_White_2     =  0.5*randn(1,1000);                             %高斯白噪声
Mix_Signal_2        =  Signal_Original_2 + Noise_White_2;           %构造的混合信号

滤波代码实现如下:

%****************************************************************************************
%
%                信号Mix_Signal_1 和 Mix_Signal_2  分别作中值滤波
%
%***************************************************************************************%混合信号 Mix_Signal_1  中值滤波
Signal_Filter=medfilt1(Mix_Signal_1,10);subplot(4,1,1);                                          %Mix_Signal_1 原始信号
plot(Mix_Signal_1);
axis([0,1000,-5,5]);
title('原始信号 ');subplot(4,1,2);                                          %Mix_Signal_1 中值滤波后信号
plot(Signal_Filter);
axis([0,1000,-5,5]);
title('中值滤波后的信号');%混合信号 Mix_Signal_2  中值滤波
Signal_Filter=medfilt1(Mix_Signal_2,10);
subplot(4,1,3);                                          %Mix_Signal_2 原始信号
plot(Mix_Signal_2);
axis([0,1000,-10,30]);
title('原始信号 ');subplot(4,1,4);                                          %Mix_Signal_2 中值滤波后信号
plot(Signal_Filter);
axis([0,1000,-10,30]);
title('中值滤波后的信号');

Matlab运行效果:

48.5 中值滤波器设计

本章的实现是根据中值滤波器原理做了两个函数,一个函数是一块数据的滤波器实现,另一个函数是实时的逐点滤波实现。

48.5.1        函数MidFilterBlock

函数原型:

void MidFilter(float32_t *pSrc, float32_t *pDst, uint32_t blockSize, uint32_t order)

函数描述:

这个函数用于一段数据的中值滤波。

函数参数:

  • 第1个参数是源数据地址。
  • 第2个参数是目的数据地址。
  • 第3个参数是滤波数据个数,至少为2。
  • 第4个参数是滤波阶数,至少为2。

48.5.2 函数MidFilterRT

函数定义如下:

void MidFilterRT(float32_t *pSrc, float32_t *pDst, uint8_t ucFlag, uint32_t order)

函数描述:

这个函数用于逐个数据的实时滤波。

函数参数:

  • 第1个参数是源数据地址。
  • 第2个参数是目的数据地址。
  • 第3个参数设置为1表示首次滤波,后面继续滤波,需将其设置为0。
  • 第4个参数是滤波阶数,至少为2。

48.5.3 宏定义设置 (重要)

用到两个宏定义,大家根据自己的应用进行设置:

#define TEST_LENGTH_SAMPLES  1024    /* 采样点数 */

#define MidFilterOrder  16           /* 滤波阶数 */

第1个宏定义:采样点数用于整块数据滤波,一次性滤波的点数。

第2个宏定义:设置滤波阶数。

48.5.4 整块数据中值滤波测试

适用于分段数据滤波,测试波形是由原始信号+高斯白噪声+均匀白噪声。

/*
*********************************************************************************************************
*    函 数 名: MidFilterBlockTest
*    功能说明: 整块数据滤波测试
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void MidFilterBlockTest(void)
{MidFilterBlock((float32_t *)&testdata[0], &DstDate[0], TEST_LENGTH_SAMPLES, MidFilterOrder);for(int i = 0; i < TEST_LENGTH_SAMPLES; i++){printf("%f, %f\r\n", testdata[i], DstDate[i]);}
}

滤波器效果,红色是原始波形,杏黄色是滤波后效果:

48.5.5 逐个数据中值滤波测试 (支持实时滤波)

适用于逐个数据的实时滤波,测试波形是由原始信号+高斯白噪声+均匀白噪声。

/*
*********************************************************************************************************
*    函 数 名: MidFilterOneByOneTest
*    功能说明: 逐个数据滤波测试
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void MidFilterOneByOneTest(void)
{float32_t  *inputF32, *outputF32;inputF32 = (float32_t  *)&testdata[0];outputF32 = &DstDate[0];/* 从头开始,先滤第1个数据 */MidFilterRT(inputF32 , outputF32, 1, MidFilterOrder);/* 逐次滤波后续数据 */for(int i = 1; i < TEST_LENGTH_SAMPLES; i++){MidFilterRT(inputF32 + i , outputF32 + i, 0, MidFilterOrder);}for(int i = 0; i < TEST_LENGTH_SAMPLES; i++){printf("%f, %f\r\n", testdata[i], DstDate[i]);}
}

滤波器效果,红色是原始波形,杏黄色是滤波后效果:

48.6 实验例程说明(MDK)

配套例子:

V5-233_中值滤波器实现,适用于噪声和脉冲过滤(支持逐点实时滤波)

实验目的:

  1. 学习中值滤波器 。

实验内容:

  1. 启动一个自动重装软件定时器,每100ms翻转一次LED2。
  2. K1键按下,整块数据滤波测试。
  3. K2键按下,逐个数据滤波器测试。

使用AC6注意事项

特别注意附件章节C的问题

上电后串口打印的信息:

波特率 115200,数据位 8,奇偶校验位无,停止位 1。

RTT方式打印信息:

程序设计:

系统栈大小分配:

硬件外设初始化

硬件外设的初始化是在 bsp.c 文件实现:

/*
*********************************************************************************************************
*    函 数 名: bsp_Init
*    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{/* STM32F407 HAL 库初始化,此时系统用的还是F407自带的16MHz,HSI时钟:- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。- 设置NVIC优先级分组为4。*/HAL_Init();/* 配置系统时钟到168MHz- 切换使用HSE。- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。*/SystemClock_Config();/* Event Recorder:- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。- 默认不开启,如果要使能此选项,务必看V5开发板用户手册第8章*/
#if Enable_EventRecorder == 1  /* 初始化EventRecorder并开启 */EventRecorderInitialize(EventRecordAll, 1U);EventRecorderStart();
#endifbsp_InitKey();        /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */bsp_InitTimer();      /* 初始化滴答定时器 */bsp_InitUart();    /* 初始化串口 */bsp_InitLed();        /* 初始化LED */
}

主功能:

主程序实现如下操作:

  • 启动一个自动重装软件定时器,每100ms翻转一次LED2。
  • K1键按下,整块数据滤波测试。
  • K2键按下,逐个数据滤波器测试。
/*
*********************************************************************************************************
*    函 数 名: main
*    功能说明: c程序入口
*    形    参: 无
*    返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{uint8_t ucKeyCode;        /* 按键代码 */uint16_t i;bsp_Init();        /* 硬件初始化 */PrintfLogo();    /* 打印例程信息到串口1 */PrintfHelp();    /* 打印操作提示信息 */bsp_StartAutoTimer(0, 100);    /* 启动1个100ms的自动重装的定时器 *//* 进入主程序循环体 */while (1){bsp_Idle();        /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */if (bsp_CheckTimer(0))    /* 判断定时器超时时间 */{/* 每隔100ms 进来一次 */bsp_LedToggle(2);    /* 翻转LED的状态 */}ucKeyCode = bsp_GetKey();    /* 读取键值, 无键按下时返回 KEY_NONE = 0 */if (ucKeyCode != KEY_NONE){switch (ucKeyCode){case KEY_DOWN_K1:            /* K1键按下,整块数据滤波测试 */MidFilterBlockTest();break;case KEY_DOWN_K2:            /* K2键按下,逐个数据滤波器测试 */MidFilterOneByOneTest();break;                default:/* 其它的键值不处理 */break;}}}
}

48.7 实验例程说明(IAR)

配套例子:

V5-233_中值滤波器实现,适用于噪声和脉冲过滤(支持逐点实时滤波)

实验目的:

  1. 学习中值滤波器 。

实验内容:

  1. 启动一个自动重装软件定时器,每100ms翻转一次LED2。
  2. K1键按下,整块数据滤波测试。
  3. K2键按下,逐个数据滤波器测试。

使用AC6注意事项

特别注意附件章节C的问题

上电后串口打印的信息:

波特率 115200,数据位 8,奇偶校验位无,停止位 1。

RTT方式打印信息:

程序设计:

系统栈大小分配:

硬件外设初始化

硬件外设的初始化是在 bsp.c 文件实现:

/*
*********************************************************************************************************
*    函 数 名: bsp_Init
*    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{/* STM32F407 HAL 库初始化,此时系统用的还是F407自带的16MHz,HSI时钟:- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。- 设置NVIC优先级分组为4。*/HAL_Init();/* 配置系统时钟到168MHz- 切换使用HSE。- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。*/SystemClock_Config();/* Event Recorder:- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。- 默认不开启,如果要使能此选项,务必看V5开发板用户手册第8章*/
#if Enable_EventRecorder == 1  /* 初始化EventRecorder并开启 */EventRecorderInitialize(EventRecordAll, 1U);EventRecorderStart();
#endifbsp_InitKey();        /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */bsp_InitTimer();      /* 初始化滴答定时器 */bsp_InitUart();    /* 初始化串口 */bsp_InitLed();        /* 初始化LED */
}

主功能:

主程序实现如下操作:

  • 启动一个自动重装软件定时器,每100ms翻转一次LED2。
  • K1键按下,整块数据滤波测试。
  • K2键按下,逐个数据滤波器测试。
/*
*********************************************************************************************************
*    函 数 名: main
*    功能说明: c程序入口
*    形    参: 无
*    返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{uint8_t ucKeyCode;        /* 按键代码 */uint16_t i;bsp_Init();        /* 硬件初始化 */PrintfLogo();    /* 打印例程信息到串口1 */PrintfHelp();    /* 打印操作提示信息 */bsp_StartAutoTimer(0, 100);    /* 启动1个100ms的自动重装的定时器 *//* 进入主程序循环体 */while (1){bsp_Idle();        /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */if (bsp_CheckTimer(0))    /* 判断定时器超时时间 */{/* 每隔100ms 进来一次 */bsp_LedToggle(2);    /* 翻转LED的状态 */}ucKeyCode = bsp_GetKey();    /* 读取键值, 无键按下时返回 KEY_NONE = 0 */if (ucKeyCode != KEY_NONE){switch (ucKeyCode){case KEY_DOWN_K1:            /* K1键按下,整块数据滤波测试 */MidFilterBlockTest();break;case KEY_DOWN_K2:            /* K2键按下,逐个数据滤波器测试 */MidFilterOneByOneTest();break;                default:/* 其它的键值不处理 */break;}}}
}

48.8 总结

本章节主要讲解了中值滤波器的实现,非常时候噪声滤除场景。

【STM32F407的DSP教程】第48章 STM32F407的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)相关推荐

  1. 【STM32F407的DSP教程】第37章 STM32F407的FIR低通滤波器实现(支持逐个数据的实时滤波)

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第37章       STM32F407的FIR低通滤波器实 ...

  2. 【STM32F429的DSP教程】第48章 STM32F429的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第48章       STM32F429的中值滤波器实现,适 ...

  3. 【STM32H7的DSP教程】第38章 STM32H7的FIR高通滤波器实现(支持逐个数据的实时滤波)

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第38章       STM32H7的FIR高通滤波器实现( ...

  4. 【STM32F429的DSP教程】第47章 STM32F429的IIR带阻滤波器实现(支持逐个数据的实时滤波)

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第47章       STM32F429的IIR带阻滤波器实 ...

  5. 【STM32F407的DSP教程】第22章 DSP矩阵运算-放缩,乘法和转置矩阵

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第22章       DSP矩阵运算-放缩,乘法和转置矩阵 ...

  6. 【STM32F407的DSP教程】第31章 STM32F407实数浮点FFT(支持单精度和双精度)

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第31章       STM32F407实数浮点FFT(支持 ...

  7. 【STM32F407的DSP教程】第33章 STM32F407不限制点数FFT实现

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第33章       STM32F407不限制点数FFT实现 ...

  8. 【STM32F407的DSP教程】第18章 DSP控制函数-更好用的SIN,COS计算

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第18章       DSP控制函数-更好用的SIN,COS ...

  9. keil编写正弦函数_【STM32F407的DSP教程】第18章 DSP控制函数-更好用的SIN,COS计算...

    第18章       DSP控制函数-更好用的SIN,COS计算 本期教程主要讲解控制函数中的cos和sin函数数值的获取,这里使用的函数比起第13章中使用的sin和cos函数数值的获取要方便很多. ...

最新文章

  1. 程序员之间的门户之见有多深?
  2. 【2012年终总结】之一 opencv + ds采集摄像头视频 MFC点点滴滴
  3. matlab多维数组
  4. 嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat
  5. Query String Parameters、Form Data、Request Payload的区别
  6. 图像处理PILLOW的使用
  7. dorado 7 使用总结
  8. c++虚函数动态联编需要避免的内存泄漏问题
  9. QSettings实现记住密码
  10. BP算法的身份证号码识别
  11. empty是什么意思 php,empty是什么意思中文翻译
  12. 贵港职称计算机考试网,贵港工程师职称等级时间
  13. Linux - last 命令
  14. S3C2440-裸机篇-07 | S3C2440内存控制器(Memory Controller)
  15. codeforces 158E. Phone Talks(dp)
  16. android 软解8k视频,一种基于CPU的8K超高清视频高速解码方法与流程
  17. 医用IT隔离电源在医院特殊场所接地系统的应用
  18. 4.JDK安装与卸载
  19. 2021 ICPC 沈阳赛区J题 Luggage Lock
  20. pycharm下载及安装说明

热门文章

  1. 华为HCIA(RS网络工程师)2021题库
  2. 拍照图像偏绿(sensor输出正常)
  3. [NOIP2017 提高组] 时间复杂度
  4. Wallystech|802.11r Fast Roaming hardware IPQ4019 IPQ4029 routerboard
  5. (五)以太坊——委托投票智能合约
  6. c语言第二版课后答案pdf,数据结构(C语言版)第2版习题答案—严蔚敏.pdf
  7. 类似微信聊天界面加载历史记录的样式
  8. 微信小程序 历史记录和长按清除
  9. 【MFC】使用MFC框架(10)
  10. 使用知行之桥EDI系统进行OFTP连接需要准备什么?