【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 总结

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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

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