原创 查找序列中的峰值点位置

2024-1-4 17:22 1487 7 4 分类: MCU/ 嵌入式 文集: matlab

查找序列中的脉冲峰值点位置。W中保存位置信息,v中为幅度值。

 

常规的办法是使用相关运算使用卷积求解。这里探索一种简单粗暴的方法。先设定一个脉冲的宽度,使用这个宽度作为窗在数据序列上判断,如果中心的数据不小于两侧的数据,则判断为可能是峰。找到峰后跳过当前区间继续查找后续的数据。没找到峰则平移一格继续查找。遍历所有数据,即可找出所有峰值点。

然而数据序列的噪声点也有可能满足这个条件。找到峰值点后可以增加一个判断,峰值点需要大于平均值才能视为有效峰值点。

matlab代码

% 需要把 w v 提前准备好

w = [569778 569883 569988 570093 570198 570303 570408 570513 570618 570723 570828 ...

570933 571038 571143 571248 571353 571458 571563 571668 571772 571877 571982 ...

572087 572192 572297 572402 572507 572612 572717 572822 572927 573032 573137 ...

573242 573347 573452 573557 573662 573767 573872 573977 574082 574187 574291 ...

574396 574501 574606 574711 574816 574921 575026 575131 575236 575341 575446 ...

575551 575656 575761 575866 575971 576000 576001 576105 576210 576315 576420 ...

576525 576630 576735 576840 576945 577050 577155 577260 577365 577470 577575 ...

577680 577785 577890 577995];


v = [38727  38540  43489  47164  54550  29620 162377 162825 281311 284985 312675 ...

271594 150447 142803  25754  60432  54621  58933  54952  41425  38375  35609  ...

40576  38131  34671  34041  51897  12021  33252  50940 142025 159748 130990  ...

47486  21280  33784  57522   7234  32753   9176   9331  17528  29384  30439  ...

43606  47916  47562  37912  16863  15923  49290  46001  23900  55387  15898  ...

17223  24232  17170  12982  44943 144313 142653 167944 167001 291899 311106 ...

318415 295938 269152 150283 143796  28813  11361  53365  42364  39616  40523  ...

35293  41373  46670  39177];


PEAKDUR = 8;  %脉冲近似宽度

clear peak

clear wave

x = v;

len = length(x);

pcnt = 1;

avg = mean(x);

for i=0:len-PEAKDUR-1

    trycnt = 0;

    for j=0:PEAKDUR/2-1

        if (x(i+PEAKDUR/2+1)

            trycnt = -1;

            break

        end

    end

    if (trycnt == 0) & (x(i+PEAKDUR/2+1) > avg) 

%    if (trycnt == 0) 

        peak(pcnt)=x(i+PEAKDUR/2+1);

        wave(pcnt)=w(i+PEAKDUR/2+1);

        pcnt = pcnt + 1;

        i = i+PEAKDUR;

    end

end

subplot(2,1,1)

plot(w,v)


if exist('peak', 'var')   

for i=1:length(peak)

    text(wave(i)+0.5, peak(i)-0.3, ['(' num2str(wave(i)) ', ' num2str(peak(i)) ')'], ...

    'HorizontalAlignment', 'left', 'VerticalAlignment', 'top', 'FontSize', 14);

end

grid on

subplot(2,1,2)

plot(wave,peak,'*')

for i=1:length(peak)

    text(wave(i)+0.5, peak(i)-0.3, ['(' num2str(wave(i)) ', ' num2str(peak(i)) ')'], ...

    'HorizontalAlignment', 'left', 'VerticalAlignment', 'top', 'FontSize', 14);

end

grid on

end

subplot(2,1,2)

plot(wave,peak,'*')

for i=1:length(peak)

    text(wave(i)+0.5, peak(i)-0.3, ['(' num2str(wave(i)) ', ' num2str(peak(i)) ')'], ...

    'HorizontalAlignment', 'left', 'VerticalAlignment', 'top', 'FontSize', 14);

end

grid on

end


另外一种更加可靠的方法是峰值点前的数据是单调增加的后面的数据是单调减小的。同样可以设定一个检测窗WinWidth。使用一个trycnt作为状态机。

遍历所有数据当trycnt 小于WinWidth/2时,比较当前的数据与后一个数据,当后一个数据大于当前数据时trycnt++,否则清零。当trycnt 等于WindWidth/2时,如果后一个数据小于当前数据则trycnt++,否则保持不变。当trycnt 大于 WindWidth/2时,判断后一个数据是否小于当前数据。如果小于则trycnt++ 如果trycnt大于等于WinWidth,说明找到峰,标记出来后并将trycnt清零。 当trycnt 大于 WindWidth/2时,判断后一个数据是否大于当前数据。如果大于说明不是峰,trycnt清零。 如此能找到峰值点的位置。

% 需要把 w v 提前准备好

w = [ 462435 462449 462480 462511 462542 462573 462604 462635 462666 462697 462728 462759 462790 ...

462821 462852 462883 462914 462945 462976 463007 463038 463069 463100 463131 463162 463193 ...

463224 463255 463286 463317 463348 463379 463410 463441 463472 463503 463534 463565 463596 ...

463627 463658 463689 463720 463751 463782 463813 463844 463875 463906 463937 463968 463999 ...

464030 464061 464092 464123 464154 464185 464216 464247 464278 464309 464340 464371 464402 ...

464433 464464 464495 464526 464557 464588 464619 464650 464681 464712 464743 464774 464805 ...

464836 464867 464898 464929 464960 464991 465022 465053 465084 465115 465146 465177 465208 ...

465239 465270 465301 465332 465363 465394 465425 465456 465487 465518 465549 465580 465611 ...

465642 465673 465704 465735 465766 465797 465828 465859 465890 465921 465952 465983 466014 ...

466045 466076 466107 466138 466169 466200 466231 466262 466293 466324 466355 466386 466417 ...

466448 466479 466510 466541 466572 466603 466634 466665 466696 466727 466758 466789 466820 ...

466851 466882 466913 466944 466975 467006 467037 467068 467099 467130 467161 467192 467223 ...

467254 467285 467316 467347 467378 467409 467440 467471 467502 467533 467564 467595 467626 ...

467657 467688 467719 467750 467781 467812 467843 467874 467905 467936 467967 467998 468029 ...

468060 468091 468122 468153 468184 468215 468246 468277 468308 468339 468370 468401 468432 ...

468463 468494 468525 468556 468587 468618 468649 468680 468711 468742 468773 468804 468835 ];


v = [ 1056110 1078560 1086790 1094130 1081890 1053250 1016240 1007900 1080470 1046850 1012930 ...

      1018920 990912 990611 1014940 1033810 1040280 1060290 1080080 1069110 1045650 1051720 ...

      1047490 1025120 1029100 1004390 990458 1027360 1054000 1052720 1056580 1039940 1040160 ...

      1059850 1035930 1016330 1005190 968061 939753 941126 946590 950410 925057 900343 898082 ...

      930454 932764 942933 894949 902633 903744 928736 915309 931095 894984 875089 924239 933796 ...

      924801 924697 916751 947187 946459 956707 965739 979989 974229 968613 926795 928007 940406 ...

      934936 940563 934341 902148 901271 952841 934052 948474 979532 1005510 1036730 1124840 1122550 ...

      1242570 1309850 1429930 1596770 1775910 2083710 2407030 2712450 3071310 3393410 3745090 4075450 ...

      4407150 4738800 5024550 5248700 5455110 5834890 5989950 6084700 6103790 6027510 5873240 5610030 ...

      5265000 4896170 4514690 4320410 3935990 3575700 3213470 2900420 2616340 2308690 2034760 1791600 ...

      1532130 1412640 1299590 1193860 1129210 1076090 1065640 1062720 1009140 1030710 1035220 1032890 ...

      1008320 966348 962262 971034 914654 924607 923892 909457 893802 887063 912653 929578 936967 ...

      902608 907888 901040 892642 885717 917977 918311 918831 873798 877512 921299 934303 934984 933461 ...

      924385 979742 960628 959226 953781 964622 942977 900647 910682 928034 936799 903553 875613 904265 ...

      902749 917475 925572 930765 952904 924550 966399 971443 983909 953276 915223 967565 991125 1011040 ...

      1002180 1037530 1045160 1028670 1074650 1075830 1105140 1064540 1034020 1071040 1082030 1078810 ...

      1036370 1050620 1012450 991786 1015420 1020840 1030420 1007140 1002110 ];

  

PEAKDUR = 10;  %脉冲近似宽度

clear peak

clear wave

x = v;

len = length(x);

pcnt = 1;

avg = mean(x);

WinWidth = PEAKDUR;

trycnt = 0;

     for i = 1:len-1

         if trycnt < WinWidth/2

             if x(i+1) > x(i)

                 trycnt = trycnt+1;

             else

                 trycnt = 0;

             end

         elseif trycnt == WinWidth/2

             if x(i+1) < x(i)

                 trycnt = trycnt + 1;         

             end

        else

            if  x(i+1) < x(i)

                 trycnt = trycnt + 1;

                 if trycnt >= WinWidth

%                     // 找到峰值点

                     peak(pcnt) = x(i-WinWidth/2+1);

                     wave(pcnt) = w(i-WinWidth/2+1);

                     pcnt = pcnt + 1;

                     trycnt = 0;

                 end

            else

                 trycnt = 0;

            end

         end

     end

subplot(2,1,1)

plot(w,v,'-+');


if exist('peak', 'var')   

for i=1:length(peak)

    text(wave(i)+0.5, peak(i)-0.3, ['(' num2str(wave(i)) ', ' num2str(peak(i)) ')'], ...

    'HorizontalAlignment', 'left', 'VerticalAlignment', 'top', 'FontSize', 14);

end

grid on

subplot(2,1,2)

plot(wave,peak,'*')

for i=1:length(peak)

    text(wave(i)+0.5, peak(i)-0.3, ['(' num2str(wave(i)) ', ' num2str(peak(i)) ')'], ...

    'HorizontalAlignment', 'left', 'VerticalAlignment', 'top', 'FontSize', 14);

end

grid on

end


  



作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论1条评论)

登录后参与讨论

开发工匠 2024-1-11 11:34

学习和参考
相关推荐阅读
southcreek 2024-07-08 11:38
接地不良导致的故障分析
这个电路的控制板需要连接显示板和识别板。5V 供电和串行控制连到显示板,显示板再连接到识别板。识别板上电位器使用一个LDO供电,将输入的5V转成3.3V。当电位器滑动时,输出电压在0~3.3V之间。...
southcreek 2024-06-26 09:15
【EMC整改】带辅助加热的滴速控制器辐射抗扰整改
这个滴速式的输液泵使用一个红外线发射和接收装置,当有液滴通过时,会扰动检测信号,识别这个扰动检测到液滴滴下,获得滴壶中的液滴速度,调整阀门大小,实现输液速度控制。控制器还配备一根加热条,用于输液时对药...
southcreek 2024-06-06 08:52
QT 使用QSettings 操作ini文件配合表格操作
这个项目可以演示 使用QSetting 读取或写入 ini文件。并使用tablewidget 显示。Ini文件的格式如下,这个文件可以事先编写。也可以在程序中生成。有一个大类,下面有一个小类使用等号设...
southcreek 2024-05-27 16:18
差分输入ADC的单端到差分转换器驱动设计
单端信号需要转换成差分信号,以便使用ADC进行转换。这个就所谓的ADC驱动电路。需要的结果为Vp = Vcm + Vi/2Vn = Vcm – Vi/2这样 Vp – Vn = Vi使用简单的加法器和...
southcreek 2024-05-10 15:12
QT 使用 customplot实现绘图
从customPlot 官网下载需要的源文件。将qcustomplot类中的源文件加入到工程里。在工程文件中增加greaterThan(QT_MAJOR_VERSION, 4): QT += widg...
southcreek 2024-04-19 12:15
步进电机运动控制
这个项目使用步进电机高速启停并换向。需要在尽可能短时间完成相应的圈数。常用的线性加速启停的时候有很大的噪声。需要做一点运动控制。达到加速度变化连续的效果。7段加减速控制策略分t1~t7 7个阶段,A...
我要评论
1
7
关闭 站长推荐上一条 /2 下一条