当前位置: 首页 > news >正文

滑动窗口滤波

 一、原理

        通过对连续采样数据窗口内的数值进行算术平均,减少随机噪声。其核心是固定长度的队列,更新时替换最旧的数据,计算平均。

二、用途

        主要用于实时检测线性数据----------平滑线性数据、去除噪声。

三、场景模拟

3.1、示例1

            每10ms获取 一个 数据 ,存储到一个【Len =5】  的缓存数组里(也叫缓存池)
注意:Len 是 常量    

3.2、解析步骤        

        以连续7笔数据为例。数据流是1-2-3-4-5-6-7,那么缓冲区的从最初始变化到最后:
初始状态: [0,0,0,0,0]

开始:
       第一次加入数据1 → [0,0,0,0,1] → sum = (0+0+0+0+1) / 5 = 0.2  


       第二次加入数据2 → [0,0,0,1,2] → sum = (0+0+0+1+2) / 5 = 0.6 


       第三次加入数据3 → [0,0,1,2,3] → sum = (0+0+1+2+3) / 5 = 1.2


       第四次加入数据4 → [0,1,2,3,4] → sum = (0+1+2+3+4) / 5 = 2


       第五次加入数据5 → [1,2,3,4,5] → sum = (1+2+3+4+5) / 5 = 3


       第六次加入数据6 → [2,3,4,5,6] → sum = (2+3+4+5+6) / 5 = 4


       第七次加入数据7 → [3,4,5,6,7] → sum = (3+4+5+6+7) / 5 = 5

sum    :表示 总和      
       /5 :表示 数组长度是5   
sum/5 :表示 平均 

四、补充知识点1

        众所周知,程序上 使用 “除法”计算得出的结果都是省略 【小数】

        为了 进一步 精确得出实际数值。我们数学上使用“约等于”也就是----【四舍五入】

4.1、四舍五入的数学原理

        (1)若小数部分 ‌≥0.5‌,则结果进位(+1)
        (2)若小数部分 ‌<0.5‌,则结果舍去

        这些都简单,那么如何运用在我们的程序里并去实现

4.2、思维导入

      Q整数  /  W整数  =  得出省略后小数的【E整数】

      Q整数  %  W整数 =  得出 余数

       余数  >   (W整数 / 2)      则【E整数】进位    即  最终结果【E整数 + 1】

       余数  <   (W整数 / 2)      则【E整数】不进位    即  最终结果【E整数】

4.3、示例

实例一:
               7    /    5 ≈   1   (实际值1.4,小数部分0.4 < 0.5  被丢弃-----四舍五入)
同理:
               7    /    5 ≈   1   (实际值1余2,【余数2】  小于  【5/2 = 2.5】被丢弃-----四舍五入)

实例二:
               8    /    5 ≈   2   (实际值1.6,小数部分0.6 > 0.5  进位+1-----四舍五入)
同理:
               8    /    5 ≈   2   (实际值1余3,【余数3】  大于  【5/2 = 2.5】进位+1-----四舍五入)


实例三:
               5    /    12 ≈   0   (实际值0.4,小数部分0.4 < 0.5  被丢弃-----四舍五入)
同理:
               5    /    12 ≈   0  (实际值0余5,【余数5】  小于  【12/2 = 6】被丢弃-----四舍五入)

实例四:
                7    /    12 ≈   1   (实际值0.58,小数部分0.58 > 0.5  进位+1-----四舍五入)
同理:
                7    /    12 ≈   1   (实际值0余7,【余数7】  大于  【12/2 = 6】进位+1-----四舍五入)

4.4、找规律

        上述例子,我们发现:【余数 > (除数/2) 】    是  决定  【余数】  是否进位的

 其次:

 程序上 使用 “除法”计算得出的结果都是省略小数  不管大于 0.5  或者小于 0.5都是省略的特性

      例子;
             15 / 10 =1.5 = 1余5           数学约等于 2       程序得出:1       
             16 / 10 =1.6 = 1余6           数学上约等于 2       程序上得出:1           
             18 / 10 =1.8 = 1余8           数学上约等于 2       程序上得出:1     
             11 / 10 =1.1 = 1余1           数学上约等于 1       程序上得出:1      
             12 / 10 =1.2 = 1余2           数学上约等于 1       程序上得出:1    
             22 / 10 =2.2 = 2余2           数学上约等于 2       程序上得出:2     
             28 / 10 =2.8 = 2余8           数学上约等于 3       程序上得出:2
              7 /   5  =1.4 = 1余2           数学上约等于 1       程序上得出:1

为了满足四舍五入 ;

     我们可以在 【  [被除数]上先  加上  [ 除数/2 ]  】 再除  。

    接着 根据  编程  【除法】 特性 省略小数,得出  四舍五入 值

 例子:  数学上四舍五入值                                     
             15 / 10 =1.5 = 1余5       数学约等于 2          (15+10/2) / 10 =2    程序得出2       
             16 / 10 =1.6 = 1余6       数学上约等于 2          (16+10/2) / 10 =2    程序上得出:2           
             18 / 10 =1.8 = 1余8       数学上约等于 2          (18+10/2) / 10 =2    程序上得出:2     
             11 / 10 =1.1 = 1余1       数学上约等于 1           (11+10/2) / 10 =1    程序上得出:1      
             12 / 10 =1.2 = 1余2       数学上约等于 1           (12+10/2) / 10 =1    程序上得出:1    
             22 / 10 =2.2 = 2余2       数学上约等于 2           (22+10/2) / 10 =2    程序上得出:2     
             28 / 10 =2.8 = 2余8       数学上约等于 3           (28+10/2) / 10 =3    程序上得出:3
              7 /   5  =1.4 = 1余2       数学上约等于 1           (7  +  5/2) /   5 =1    程序上得出:1

我们不难发现 ,数学上的四舍五入值   与   【被除数上先   加上  [除数/2]  】 再除 】 得出的  四舍五入值 是一致的

C语言代码实现四舍五入:

        ( (  sum + WINDOW_SIZE  / 2  )   /  WINDOW_SIZE  )

注意:负数运算可能不适用

 注释:sum :被除数     
            WINDOW_SIZE:除数
            (  sum + WINDOW_SIZE  / 2  )  ===== 被除数上先  加上 除数一半

五、补充知识点2

5.1、取模运算

当:WINDOW_SIZE    取偶数时 
     
        #define WINDOW_SIZE   64 
则:
        index = (index + 1) & (WINDOW_SIZE - 1); // 位运算代替取模


当:WINDOW_SIZE    取奇数时 
     
        #define WINDOW_SIZE   5 

则:
        index = (index + 1) & (WINDOW_SIZE); // 位运算代替取模


主要用途:循环定位  数组当前 第几位

六、C语言实现 滑动窗口滤波 ------------单通道数据 

#define WINDOW_SIZE  5  //奇数


//全局变量
int32_tbuffer[WINDOW_SIZE] = {0};
int32_t sum = 0;    
uint8_t index = 0;
uint8_t count = 0;

int32_t  moving_average_filter_int(int32_t  new_value) 
{

    /* 初始阶段:未填满窗口 */
    if(count < WINDOW_SIZE) 
   {
        sum += new_value;
        buffer[index] = new_value;
        index = (index + 1) % WINDOW_SIZE;
        count++;
        return (int32_t )(sum / count); 
    }

    /* 稳定阶段:窗口已满 */
    sum -= buffer[index];        // 移除旧数据
    sum += new_value;            // 加入新数据
    buffer[index] = new_value;   // 更新缓冲区
    index = (index + 1) % WINDOW_SIZE;

    // 四舍五入
    return (int32_t  )((sum + WINDOW_SIZE/2) / WINDOW_SIZE);
}




相关文章:

  • OpenIPC开源FPV之Adaptive-Link日志分析
  • 【Linux操作系统】:信号
  • 【Java设计模式】第10章 外观模式讲解
  • C++进阶笔记第一篇:程序的内存模型
  • 简单回溯(组合力扣77)
  • OpenCV 图形API(22)矩阵操作
  • SAP Overview
  • 淘宝 API 高并发优化:突破 QPS 限制的分布式爬虫架构设计
  • java导入excel更新设备经纬度度数或者度分秒
  • UTF-8和GBK编码的区别和详细解释
  • Unity Input 2023 Release-Notes
  • 数据结构第六章(一) -图
  • Dynamics 365 Business Central VS Code AL 开发 多语言的支持
  • Linux系统远程操作和程序编译
  • Spring Boot 国际化配置项详解
  • STM32单片机入门学习——第27节: [9-3] USART串口发送串口发送+接收
  • 【算法手记11】NC41 最长无重复子数组 NC379 重排字符串
  • 质数筛(循环遍历,埃氏筛法,欧拉筛法)
  • 多线程编程:提高程序效率与响应性
  • Plusar集群搭建-Ubuntu20.04-Winterm
  • 当创业热土遇上年轻气息,上海南汇新城发展如何再发力?
  • 体坛联播|曼联热刺会师欧联杯决赛,多哈世乒赛首日赛程出炉
  • 欧派家居:一季度营收降4.8%,目前海外业务整体体量仍较小
  • 王日春已任教育部社会科学司司长,此前系人教社总编辑
  • 李公明︱一周书记:浪漫主义为什么……仍然重要?
  • “用鲜血和生命凝结的深厚情谊”——习近平主席署名文章中的中俄友好故事