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

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

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

目录

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)

配套例子:

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

实验目的:

  1. 学习中值滤波器 。

实验内容:

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

使用AC6注意事项

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

上电后串口打印的信息:

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

RTT方式打印信息:

程序设计:

系统栈大小分配:

硬件外设初始化

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

/*
*********************************************************************************************************
*    函 数 名: bsp_Init
*    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{/* STM32F429 HAL 库初始化,此时系统用的还是F429自带的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_InitExtIO();   /* 初始化扩展IO */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)

配套例子:

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

实验目的:

  1. 学习中值滤波器 。

实验内容:

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

使用AC6注意事项

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

上电后串口打印的信息:

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

RTT方式打印信息:

程序设计:

系统栈大小分配:

硬件外设初始化

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

/*
*********************************************************************************************************
*    函 数 名: bsp_Init
*    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{/* STM32F429 HAL 库初始化,此时系统用的还是F429自带的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_InitExtIO();   /* 初始化扩展IO */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 总结

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

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

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

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

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

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

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

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

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

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

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

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

  6. 【STM32F429的DSP教程】第12章 DSP基础函数-相反数,偏移,移位,减法和比例因子

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第12章       DSP基础函数-相反数,偏移,移位,减 ...

  7. 【STM32F429的DSP教程】第9章 Matlab的串口通信实现

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第9章   Matlab的串口通信实现 本章节主要为大家讲解 ...

  8. 【STM32F429的DSP教程】第21章 DSP矩阵运算-加法,减法和逆矩阵

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第21章       DSP矩阵运算-加法,减法和逆矩阵 本 ...

  9. 【STM32F429的DSP教程】第6章 ARM DSP源码和库移植方法(MDK5的AC5和AC6)

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547 第6章   ARM DSP源码和库移植方法(MDK5的AC5 ...

最新文章

  1. 「Excel技巧」Excel技巧之如何看文件里的宏?
  2. 【视频开发】图像清晰度评价方法
  3. SVN 报错svn: E200014: Checksum mismatch for 。。。。。
  4. ALV中调用Excel inplace时没能传递数据实例解决
  5. SAP中的邮件发送功能
  6. Selwyn College, Cambridge
  7. react中setState有三种用法
  8. 算法--Hash算法及其应用场所
  9. java移动文件导致tomcat死掉_原 netty导致tomcat假死
  10. 【数据结构与算法】二叉搜索树V2.0的Java实现
  11. 使用HttpsUrlConnedtion连接https地址时异常处理 (方式二)
  12. CAD图纸上面缺失的线条如何将其进行补充?
  13. 064 import和from...import
  14. C# NamePipe使用小结
  15. 商海导航系统 服务器配置,海信商海导航推出商业管理系统全新增强版V5
  16. 项目启动会应该注意的几点
  17. 斗鱼弹幕服务器第三方接入协议v1.6.2,.NET斗鱼直播弹幕客户端(上)
  18. 云存储平台——Seafile搭建
  19. js中对象属性、面向对象、面向过程、类、继承、以及原型原型链
  20. 单芯片无线供电IC 无线充电芯片 无线输电芯片FS68001

热门文章

  1. 《魔鬼搭讪培训班》全部1~6集
  2. 通过S7协议或opc协议远程连接西门子模拟器
  3. 前端设计一一个人博客网站怎么进行公安备案?
  4. 流水明细记账,选择晨曦记账本
  5. 从估值一亿到一夜分家:一个曾经存在过的教育产品的故事
  6. lgo怎么打开o文件_GO语言文件的创建与打开实例分析
  7. 数字经济创新(Digital-economy-innovation)
  8. 单片机 STM32 HAL 射频读卡器 RC522
  9. 离散数学——命题逻辑(命题、联结词、命题公式、对偶式、大小项、主范式、推论、直接证明、反证法、cp规则)
  10. 2023最新计算机毕业设计题目选题大全