一维信号峰值检测Matlab实现

参考论文:https://pdfs.semanticscholar.org/56f1/49e51aa9fb9b0b46412b864839f34701d421.pdf
先使用3点运动均值滤波器处理一维信号,先前向再后向处理。作为例子,这里先生成正弦信号波形图,然后执行3点前向运动均值滤波,再3点均值后向运动滤波。信号S(n)={s1,s2,s3,s4,…,sn}.

x = 0:0.05:50*pi;
row_acc = sin(x);
m = length(row_acc);
row_acc1 = linspace(0,0,m);
row_acc1(1) = row_acc(1);
row_acc1(m) = row_acc(m);
for i=2:m-1
   row_acc1(i)=(row_acc(i-1) + row_acc(i)+row_acc(i+1))/3;
end
figure;
plot(row_acc1);

for i=m-1:-1:2
    row_acc(i) = (row_acc1(i-1) + row_acc1(i)+row_acc1(i+1))/3;
end

找到局部最小值和局部最大值及其对应的位置,波峰点、波谷点满足:
这里写图片描述

peaks = linspace(0,0,m);
valleys = linspace(0,0,m);
peakindexs = linspace(0,0,m);
valleyindexs = linspace(0,0,m);
peakindex = 1;
valleyindex = 1;
for i = 2:m-1
    if row_acc(i) >row_acc(i-1) && row_acc(i)>=row_acc(i+1)
        peaks(peakindex)=row_acc(i);
        peakindexs(peakindex)=i;
        peakindex = peakindex+1;
    end
    if row_acc(i) < row_acc(i-1) && row_acc(i)<row_acc(i+1)
        valleys(valleyindex)=row_acc(i);
        valleyindexs(valleyindex)=i;
        valleyindex=valleyindex+1;
    end
end

计算VPD,VPD(n)表示第n个波谷点的值与第n个波峰点的值的差,VPD用来去掉那些假的波峰点,
这里写图片描述
计算了VPD之后,搜索VPD,如果满足:
这里写图片描述,则这个波峰点是假的,移除。

程序流程如下:
这里写图片描述
matlab代码:

pcount = peakindex-1;
vcount = valleyindex-1;
peakindices = linspace(0,0,pcount);
for i = 1:pcount
    peakindices(i) = peakindexs(i);
end

valleyindices = linspace(0,0,vcount);
for i = 1:vcount
    valleyindices(i) = valleyindexs(i);
end

figure;
plot(x, row_acc,'-o', 'MarkerIndices',peakindices,'MarkerFaceColor','red','MarkerSize',5);

figure;
plot(x, row_acc,'-s', 'MarkerIndices',valleyindices,'MarkerFaceColor','red','MarkerSize',5);

if pcount>2 && vcount>2
    if peakindexs(1) < valleyindexs(1)
        peakindex=2;
    else
        peakindex=1;
    end
    vindex=1;
end

if peakindex == 2
    for i = 1:m-1
        peaks(i)=peaks(i+1);
    end
    pcount = pcount-1;
    pindex=1;
end

vpd = linspace(0,0,m);
vpd1 = linspace(0,0,m);
for i=1:pcount
    vpd(i) = peaks(i) - valleys(i);
end

dels = linspace(0,0, pcount);
peakindexs1 = linspace(0,0,pcount);
if pcount > 2
    lastcount=pcount;
    curcount = 1;
    while lastcount ~= curcount
        lastcount = curcount;
        del_count = 0;
        for i = 2:pcount-1
            if vpd(i) <= 0.7 * (vpd(i-1) + vpd(i)+vpd(i+1)) / 3
                dels(i)=1;
            end
        end

        count = 1;
        for i = 1:pcount
          if dels(i) ~= 1
              vpd1(count) = vpd(i); 
              peakindexs1(count) = peakindexs(i);
              count = count+1;
          else
               del_count = del_count + 1;
               dels(i) = 0;
           end
        end

        pcount = pcount - del_count;
        for i = 1:pcount
            vpd(i) = vpd1(i); 
            peakindexs(i) = peakindexs1(i);
        end
        peakindexs(pcount+1) = 0;
        vpd(pcount+1) = 0;

        indices = linspace(0,0,pcount);
        for i = 1:pcount
            indices(i) = peakindexs1(i);
        end
        figure;
        plot(x, row_acc,'-o', 'MarkerIndices',indices,'MarkerFaceColor','red','MarkerSize',10);
        curcount = pcount;
    end
end
  • 5
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值