【问题标题】:Code for peak detection峰值检测代码
【发布时间】:2015-09-29 05:10:52
【问题描述】:

我想在第一步中计算实时信号是否通过了某些阈值。在第一步中,我想检测真实信号是否低于这些阈值(以便检测信号中的峰值)。我的 Matlab 代码:

k=1;  
t = 1;
l=1;

for i =1:length(sm) //sm my signal.

    if (sm(i) > 0.25)
        first(k) = i;
        k = k+1;
        if (sm(i) > 0.5)

            second(t) = i;
            t =t +1;
            if (sm(i) > 0.75)

                third(l) = i;
                l = l+1;
            end
        end
    end
end

例子:

![在此处输入图片描述][1]

我想计算信号通过和低于三个阈值0.250.50.75 的时间并返回这些窗口。基本上我的例子中的三个主要山峰。

基本上我想做的是使用 fastsmooth 功能和 findpeaks。

signalSmoothed = fastsmooth(sm,50); plot(signalSmoothed)
[max_pk1 max_pk2] = findpeaks(signalSmoothed);
find(max_pk1 >0.5)
inversex = 1.01*max(signalSmoothed) - signalSmoothed;
[min_pk1 min_pk2]  = findpeaks(inversex);
find(min_pk1 >0.5) 

为了只取所需的峰值,有哪些启发式方法?此外,depticted 图像是一个离线示例。一般来说,我想在线执行该技术。

编辑:我错误地将我想要的曲线结果定义为峰值,它是整个波,而不仅仅是最大值。

【问题讨论】:

  • 您想单独检测它们还是必须满足所有条件才能将其定义为峰值?你也看过findpeaks吗?如果您手工绘制样本曲线并标记您有​​兴趣找到的峰,这将是有帮助的
  • 必须满足所有条件。在我的示例中,我只有通过条件,我正在尝试计算通过条件。是的,但是 findpeaks 返回许多值,因为信号包含很多局部最大值。
  • 如果您的问题根本不清楚,请提供示例输入和输出数据,手动计算(例如手动)
  • 在图表上用不同的颜色标记您要查找的点。
  • 你的图表和你的代码有什么关系?例如,这些0.250.50.75 点在哪里?

标签: matlab signal-processing


【解决方案1】:

这里是获取信号sm 通过阈值0.250.500.75 的点的解决方案。这些点可以转换为数据范围内的窗口并存储在W 中。最后,我们可以轻松地将它们绘制在同一张图中。请注意,我们需要在本地函数getwindows 中进行一些检查以处理特殊情况,例如当窗口在数据范围之外启动时。另一个窗口内的窗口检测是在getwindowsspecial-函数中完成的。

代码如下:

function peakwindow
% generate sample data
rng(7);
sm = 2*rand(1,25)-0.5;
sm = interp1(1:length(sm),sm,1:0.01:100*length(sm));

% get points
firstup    = find(diff(sm > 0.25)==1);
secondup   = find(diff(sm > 0.50)==1);
thirdup    = find(diff(sm > 0.75)==1);
firstdown  = find(diff(sm < 0.25)==1);
seconddown = find(diff(sm < 0.50)==1);
thirddown  = find(diff(sm < 0.75)==1);

% plot the result
figure; hold on;
plot(sm,'k')
plot(firstup,sm(firstup),'*')
plot(firstdown,sm(firstdown),'*')
plot(secondup,sm(secondup),'*')
plot(seconddown,sm(seconddown),'*')
plot(thirdup,sm(thirdup),'*')
plot(thirddown,sm(thirddown),'*')

% get windows
W1 = getwindows(firstup,firstdown);
W2 = getwindows(secondup,seconddown);
W3 = getwindows(thirdup,thirddown);

% get special window
WS = getwindowsspecial(W1,W3);

% plot windows
plotwindow(W1,0.25,'r');
plotwindow(W2,0.50,'r');
plotwindow(W3,0.75,'r');
plotwindow(WS,0,'b-');


function W = getwindows(up,down)
if length(up)>1 && length(down)>1 && up(1)>down(1)
    down(1)=[]; % handle case when window begins out of bounds left
end
if length(up)<1 || length(down)<1;
    W = []; % handle if no complete window present
else
    % concatenate and handle case when a window ends out of bounds right
    W = [up(1:length(down));down]';
end


function plotwindow(W,y,lspec)
for i = 1:size(W,1)
    plot(W(i,:),[y,y],lspec)
end


% get windows of U where there is a window of H inside
function W = getwindowsspecial(U,H)
W = []; % empty matrix to begin with
for i = 1:size(U,1) % for all windows in U
    if any(H(:,1)>=U(i,1) & H(:,1)<=U(i,2))
        W = [W;U(i,:)]; % add window
    end
end

这是结果:


要查看处理是否正常,我们可以绘制使用rng(3) 初始化时的结果:

请注意,0.250.50 的窗口将从左侧开始,因此不会出现在绘制的窗口中。

【讨论】:

  • 最后我想保持窗口与我更新过的图像一样。我该怎么做?
  • @Matt 你在这里不需要for循环。尝试类似firstup = diff(sm &gt; 0.25)==1 等和firstdown = diff(sm &gt; 0.25)==-1
  • @Matt 现在如果你想添加“获取窗口”,这是一个非常不明确的概念,但无论如何,你可以尝试arrayfun(@(x)(sm(firstup(x):min(firstdown(x), end)), 1:numel(firstup), 'uni', 0)
  • @Dan 感谢您的提议。我首先认为这就像将它们放在一起一样简单,但我看到需要一些检查来处理特殊情况。这就是我使用本地函数生成窗口的原因。如果您有任何改进,请告诉我。
  • 如何找到同时满足三个条件的x轴窗口?
猜你喜欢
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
相关资源
最近更新 更多