查找序列中的脉冲峰值点位置。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
版权声明:本文为博主原创,未经本人允许,禁止转载!
开发工匠 2024-1-11 11:34