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

【STM32F407的DSP教程】第48章 STM32F407的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)「建议收藏」完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547第48章STM32F407的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)本章节讲解中值滤波器实现,适用于噪声和脉冲的过滤。目录48.1初学者重要提示48.2中值滤波器介绍48.3中值滤波器原理48.4Matlab中值滤波器实现48.5中值滤波器设计48.5.1函数MidFilter…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

完整版教程下载地址: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 中值滤波器介绍

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

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

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运行效果:

 

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

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]);
    }
}

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

 

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

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]);
    }
}

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

 

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

48.6 实验例程说明(MDK)

配套例子:

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

实验目的:

  1. 学习中值滤波器 。

实验内容:

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

使用AC6注意事项

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

上电后串口打印的信息:

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

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

RTT方式打印信息:

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

程序设计:

  系统栈大小分配:

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

  硬件外设初始化

硬件外设的初始化是在 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();
#endif
    
    bsp_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。

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

RTT方式打印信息:

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

程序设计:

  系统栈大小分配:

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

  硬件外设初始化

硬件外设的初始化是在 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();
#endif
    
    bsp_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 总结

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196973.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • aero是什么意思啊_自动驾驶视觉算法

    aero是什么意思啊_自动驾驶视觉算法数据集介绍aeroscapes数据集下载链接AeroScapes航空语义分割基准包括使用商用无人机在5到50米的高度范围内捕获的图像。该数据集提供3269张720p图像和11个类别的真实掩码。数据加载dataloder写法(基于pytorch)由于该数据集提供了掩码图,因此不需要进行掩码图转换。下载完成后,文件结构如下:ImageSets文件夹:存放了两个txt文件,划分了训练集和验证集。JPEGImages文件夹:存放了RGB图像。SegmentationClass

    2022年8月15日
    1
  • Git安装配置教程

    Git安装配置教程1.Git简介Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理1。Git是LinusTorvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。2.Git工作示意图3.Windows下安装Git3.1Git下载下载地址:https://git-for-windows.github.io/下载有时候很慢,请耐心

    2022年5月10日
    26
  • 极验验证_验证码平台

    极验验证_验证码平台发送验证码下面是具体实现步骤:handleSendCode(){const{mobile}=this.formaxios({method:'GET',url

    2022年8月6日
    1
  • MSM8953配置I2C及SPI

    MSM8953配置I2C及SPI此次完成的任务是要使能高通8953平台的i2c和spi,主要做的工作就是在设备树文件中添加节点信息。主要的工作在于对设备树文件的修改,主要修改了msm8953-pinctrl.dtsi和msm8953.dtsi两个文件。msm8953-pinctrl.dtsi是配置MSM8953芯片中的GPIO。在此文件中定义i2c使用哪个gpio。因为引脚复用功能的存在,所以要先配置i2c的引脚复用功能…

    2022年10月18日
    0
  • java向上取整和向下取整,万字长文!

    java向上取整和向下取整,万字长文!一面:70分钟突击电话面试正思考着项目功能模块,阿里面试官打来了电话,开始了阿里一面。阿里面试官自我介绍,介绍了5分钟左右,部门的情况,主要的业务提问开始会哪些操作系统Linux会一点说一下操作指令,怎么看cpu,看进程,看端口操作系统进程间通信追问了一个信号相关的问题,我不知道了。io多路复用,说一说面向切面编程,说一说那些场景说说面向切面编程给一个场景,有很多方法,找出耗时长的方法spring的@autowired的作用mybatis和hibernate的区别C,C

    2022年6月21日
    26
  • 一些sql二

    1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)法一:select * into b from a&#

    2021年12月25日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号