1、聊一聊

其实每个人在无助的时候都需要一句"Cry On My Shoulder!"

今天跟大家介绍一种波峰波谷的检测方法,不是很难,不过能够凸显数学在编程算法中的重要作用。

2、正文部分

1

波峰波谷用处

对于信号波峰波谷识别在嵌入式领域应该是非常广泛的,因为大部分的信号都处于一种时变的状态,信号在时域上处于一种类似于正弦波的波动状态。

比如计步软件就是通过IMU模块所采集的变化的波形状态来识别波峰波谷,最终估算你所走过步数;

图片来源网络侵删

上图显示了一个典型的x-, y-和z-测量模式,对应于一个跑步者的垂直,向前和侧面加速度。无论如何佩戴计步器,至少有一个轴会有相对较大的周期性加速度变化,因此通过检测其波峰波谷等算法即可对于检测步行或跑步的单位周期至关重要。

图片来源网络侵删

还有在电力系统中的交流电压电流,我们需要通过检测波峰波谷来确定电压电流在交流周期中的最大最小值,从而动态调节系统参数来达到自适应的目的,所以波峰波谷的检测是非常有用的。

2

比较法识别

常规的设计办法为比较法 : 其中x表示当前采样点

波峰:f(x) > f(x−1) 且 f(x) > f(x+1)

波谷:f(x) < f(x−1) 且 f(x) < f(x+1)

然而这样识别对于没有什么噪声,且每个采样点为不同的信号来说还是合适的,但在严苛的环境中还需要构造更多的判断条件来进行一些错误判断的规避,终究还是麻烦了一些,并且容易遗漏。

3

差分识别

在学生阶段我们就学习了导数的概念,如果一个函数一阶导数左右异号,那分别就是波峰或者波谷。而对于数字信号的处理通过采样都会变成离散信号,信号对时间的微分在离散域内即为差分。

在进行波形识别之前数据采集是必不可少的,其中最重要的是采样速率和精度,以便从采样信号中不失真的恢复原连续信号。(香农采样)

采样的过程中由于电子器件的杂讯等,数据难免会引入噪声,为了简化识别算法一般都会进行滤波处理,比如一些平滑处理等,然后才开始波峰波谷识别。

A

识别算法过程

1、获得采样点序列

2、进行差分处理

3、由于不在乎具体的差分幅值,把所有数据归一到-1,0,1

4、差分值为0的点即为相同点,如果使用比较法则峰值检测可能失效,便需要更多的条件,而这里我们直接把相同点0置为前一个非0即可规避该问题。

5、最终Diff再次进行差分,-2/+2即为波峰/波谷。

B

参考代码

  1#include <stdio.h>2#include <stdlib.h>3#define SAMPLE_MAX  204#define PV_MAX      1056float Sample[SAMPLE_MAX]={1,2,3,4,4,4,5,2,1,0,0,5,1,0,0,1,2,3,4,0};7float SampleDiff[SAMPLE_MAX]={0};89typedef struct _tag_FindPV10{11    int Pos_Peak[PV_MAX];    //波峰位置存储12    int Pos_Valley[PV_MAX];  //波谷位置存储13    int Pcnt;                //所识别的波峰计数14    int Vcnt;                //所识别的波谷计数15}SFindPV;1617SFindPV stFindPV;1819/********************************************20 *  Fuction : initialFindPV21 *  Note    : 初始化相关数据 22 *******************************************/ 23void initialFindPV(void)24{25    int Index = 0;2627    for(Index = 0; Index < SAMPLE_MAX;Index ++)28    {29        SampleDiff[Index] = 0;30    }3132    for(Index = 0; Index < PV_MAX;Index ++)33    {34        stFindPV.Pos_Peak[Index] = -1;35        stFindPV.Pos_Valley[Index] = -1;36    }37    stFindPV.Pcnt = 0;38    stFindPV.Vcnt = 0;3940}4142/********************************************43 *  Fuction : FindPV44 *  Note    : 找波峰波谷 45 *******************************************/ 46void FindPV(SFindPV *pFindPV,float *Sample)47{48    int i = 0;4950    //step 1 :首先进行前向差分,并归一化51    for(i= 0; i < SAMPLE_MAX - 1; i++)52    {53        if (Sample[i + 1] - Sample[i]>0)54            SampleDiff[i] = 1;55        else if (Sample[i + 1] - Sample[i] < 0)56            SampleDiff[i] = -1;57        else58            SampleDiff[i] = 0;59    }6061    //step 2 :对相邻相等的点进行领边坡度处理62    for(i= 0; i < SAMPLE_MAX-1; i++)63    {64        if(SampleDiff[i] == 0)65        {66            if(i == (SAMPLE_MAX-2))67            {68                if (SampleDiff[i - 1] >= 0)69                    SampleDiff[i] = 1;70                else71                    SampleDiff[i] = -1;72            }73            else74            {75                if (SampleDiff[i + 1] >= 0)76                    SampleDiff[i] = 1;77                else78                    SampleDiff[i] = -1;79            }8081        }82    }8384    //step 3 :对相邻相等的点进行领边坡度处理85    for(i= 0; i < SAMPLE_MAX-1; i++)86    {87        if(SampleDiff[i + 1] - SampleDiff[i] == -2) //波峰识别88        {89            pFindPV->Pos_Peak[pFindPV->Pcnt] = i + 1;90            pFindPV->Pcnt++; 91        }92        else if(SampleDiff[i + 1] - SampleDiff[i] == 2) //波谷识别93        {94            pFindPV->Pos_Valley[pFindPV->Vcnt] = i + 1;95            pFindPV->Vcnt++;96        }97    }98}99
100/********************************************
101 *  Fuction : main
102 *  Note    : 模拟查找波峰波谷
103 *******************************************/
104int main(int argc, char *argv[]) {
105
106    int i = 0;
107
108    initialFindPV();
109
110    FindPV(&stFindPV,Sample);
111
112    printf("Peak\n");
113    for(i = 0 ;i< stFindPV.Pcnt;i++)
114    {
115        printf("-%d",stFindPV.Pos_Peak[i] + 1);  //加1是为了与上图横坐标一致
116    }
117
118    printf("\nValley\n");
119    for(i = 0 ;i< stFindPV.Vcnt;i++)
120    {
121        printf("-%d",stFindPV.Pos_Valley[i] + 1);
122    }
123
124    printf("\n\n");
125    printf("欢迎关注:最后一个bug\n");
126    return 0;
127}

2、最后

当然在实际的项目中为了更加稳定的识别波峰波谷可能会对波峰波谷的出现特点进行限制,从而进一步减少误识别,也有许多人使用数据拟合的办法来识别波峰波谷,那么识别的准确度就与所拟合的函数有关,通过数学方法对所拟合函数进行波峰波谷的求解,最终得到信号的波峰波谷,不过这样的拟合过程对平台的处理能力提出了一定的要求。

好了,今天的分享就到这里,我是bug菌,最近在公众号推送了一些软文,当不会忘本!感谢各位,顺手点个赞!

推荐专辑  点击蓝色字体即可跳转

☞  MCU进阶专辑 

☞  嵌入式C语言进阶专辑 

☞  “bug说”专辑 

☞ 专辑|Linux应用程序编程大全

☞ 专辑|学点网络知识

☞ 专辑|手撕C语言

☞ 专辑|手撕C++语言

☞ 专辑|经验分享

信号波峰波谷二阶差分识别算法相关推荐

  1. 信号识别-波峰波谷二阶差分识别算法

    信号识别-波峰波谷二阶差分识别算法 前言 波峰波谷算法 实际上代码 前言 在图像分析里,投影曲线是我们经常要用到的一个图像特征,通过投影曲线我们可以看到在某一个方向上,图像灰度变化的规律,这在图像分割 ...

  2. 二阶导数求信号波峰波谷算法

    最近在整理提取信号波峰波谷的算法原理,于是,在网上看到了一篇博文(链接见文末),写的比较清楚,方法也不难,就是利用二阶导数来求函数极值的问题,只是对于信号处理来说,这个过程是离散的. 博文中的问题背景 ...

  3. c语言检测正弦波波峰波谷,一种基于波峰波谷检测的计步算法的制作方法

    本发明涉及计步器算法领域,具体是一种基于波峰波谷检测的计步算法. 背景技术: 当今社会,健康越来越受到人们的重视,步行作为人类活动中最基础.最常见.最重要的运动形式,使得深入研究计步算法有着重要的意义 ...

  4. 识别波峰波谷算法_马丁普林格:波峰-波谷演进法

    我们有很多方法来识别趋势,计算机可以轻易地帮助我们实现各种复杂的想法.而在技术允许的条件下,我们还总是有把事物复杂化的倾向.事实也的确如此,目前市面上有无数复杂的方法.指标和程式化黑箱.但很显然,这些 ...

  5. 图像投影特征图的波峰波谷查找的相关原理及利用差分遍历法查找波峰的OpenCV代码

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 什么叫图像的投影特征图?定义如下: 图像水平方向 ...

  6. python波峰波谷算法_波动均分算法

    波动均分算法 by leeenx on 2018-01-11 「波动」和「均分」大部分读者朋友是知道的,但看到「波动均分」应该是一头雾水的.其实,这个名词是笔者拼凑出来的. 什么是「波动均分」? 把指 ...

  7. 基于波峰波谷法计算信号的周期

    波峰波谷法原理是:查找信号相邻波峰波谷间隔采样点的数量,乘上采样间隔的时间,最后求平均值即是信号的周期.但该方法对噪声较为敏感,采用波峰波谷法计算滤波后信号的周期,如图所示. 该方法主要是需要找到信号 ...

  8. Python信号分析—波峰波谷

    @[TOC](文章目录) #任务目标 以折线图的形式表现信号,以茎图的形式表现波峰波谷数值,检验给出的波峰波谷数值是否与原信号相符 一.Material 数据:GitHub - SHUTCM-tcme ...

  9. matlab如何寻找波谷,波峰波谷法计算信号的周期及其Matlab程序

    波峰波谷法原理是:查找信号相邻波峰波谷间隔采样点的数量,乘上采样间隔的时间,最后求平均值即是信号的周期.但该方法对噪声较为敏感,采用波峰波谷法计算滤波后信号的周期,如图所示. 该方法主要是需要找到信号 ...

最新文章

  1. 前端学习(2321):angular环境搭建1
  2. 游戏cg提取工具_记蒼の彼方のフォーリズム の CG提取
  3. MyEclipse教程:Web开发——调试JSP
  4. arduino安卓手机版_剥离安卓!华为鸿蒙系统手机版正式发布:这两大机型率先升级...
  5. nginx历史版本下载链接
  6. UE4之批量删除actor
  7. mininet编程实现交换机规则的插入、删除与修改。_三层以太网交换机基本原理及转发流程...
  8. CodeForces 980 E The Number Games
  9. 获取点击按钮的元素_Web API - DOM元素属性操作
  10. 小米2系列板砖自救行动
  11. adb通过usb连接手机
  12. 简化预测集合的永磁同步电机的无差拍预测转矩控制系统Simulink仿真
  13. 网站被挂马的处理办法以及预防措施
  14. 利用python代码 之将指定网易云歌单保存到Excel中
  15. WAITED TOO LONG FOR A ROW CACHE ENQUEUE LOCK
  16. 学习金字塔——谈谈对学习的一点理解
  17. http中302与304
  18. Web前端 CSS3 01
  19. 计算机内存的安装方法,内存条怎么装?内存条安装与拆卸方法
  20. 文章标题 SPOJ - DRUIDEOI : Fata7y Ya Warda!(单调栈)

热门文章

  1. 基于AT89C52做秒表0~99秒
  2. 徐小平都退群了,区块链的价值何在?
  3. 除了平台和功能外,企业年会直播方案还要考虑哪些内容?
  4. android 基带版本怎么升级,Android如何升级5.1系统?安卓5.1刷机技巧
  5. E-mark认证公司
  6. python 极坐标图xlabel_matplotlib极坐标图刻度/轴标签位置
  7. android 打开蓝牙可被发现,手机蓝牙隐藏功能,竟然被学姐发现了!
  8. 抢完咖啡生意,蜜雪冰城还要抢便利店的生意
  9. 功能最完善,代码最简洁的选项卡代码(div+css)
  10. Netbeans介绍