在Matlab中定义峰的宽度

时间:2013-07-02 11:16:10

标签: matlab

我试图在Matlab中找到一些峰值,但函数findpeaks.m没有宽度选项。我想要检测的峰值在球中。所有检测到的都在红色方块中。如您所见,它们的宽度较小。有什么帮助吗?

enter image description here

这是我使用的代码:

[pk,lo] = findpeaks(ecg);

lo2 = zeros(size(lo));

for m = 1:length(lo) - 1
    if (ecg(m) - ecg(m+1)) > 0.025
        lo2(m) = lo(m);
    end
end

p = find(lo2 == 0);

lo2(p) = [];

figure, plot(ecg);
hold on
plot(lo, ecg(lo), 'rs');

4 个答案:

答案 0 :(得分:1)

根据它的外观,您希望根据幅度和宽度来表征每个峰值,以便您可以对这些值应用阈值(或类似值),以便仅选择符合您的条件(高和薄)的那些。

你可以这样做的一种方法是将正态分布拟合到每个峰值,将平均值和幅度与已经找到的值相关联,并使用优化函数找到标准偏差(正态分布的宽度)。 / p>

所以,你需要一个根据你所有高斯分布的总和来计算数据表示的函数,以及一个误差函数(也许是均方误差)然后你只需要把它扔进一个matlabs内置优化/最小化功能。

最佳标准偏差参数组将为您提供每个峰的宽度,或至少是一个很好的近似值。

另一种方法,基于Adiel的评论,可能更合适,因为看起来你正在研究ecg数据,也会找到局部最小值(低谷)以及峰值。由此可以通过获取给定峰两侧的槽之间的x轴距离来构建“薄度”的近似度量。

答案 1 :(得分:1)

您需要先定义峰宽,确定您希望峰的宽度,然后相应地选择它们。

例如,您可以将峰的宽度定义为x坐标之间的差异,y坐标等于峰值的一半(参见here)。另一种方法(这似乎更合适)是在距离峰本身固定距离处测量梯度,并相应地选择峰值。在MATLAB中,您可能会使用渐变过滤器:

g = conv(ecg, [-1 0 1], 'same'); %// Gradient filter
idx = g(lo) > thr);              %// Indices of narrow peaks
lo = lo(idx);

其中thr是您需要为自己确定的阈值。阈值越低意味着对更宽峰的容忍度越大。

答案 2 :(得分:1)

务实地思考,我想你可以使用这种简单的蛮力方法:

[peaks  , peakLocations]   = findpeaks(+X);
[troughs, troughLocations] = findpeaks(-X);

width = zeros(size(peaks));
for ii = 1:numel(peaks)

    trough_before = troughLocations( ...
        find(troughLocations < peakLocations(ii), 1,'last') );

    trough_after  = troughLocations( ...
        find(troughLocations > peakLocations(ii), 1,'first') );

    width(ii) = trough_after - trough_before;

end

这将找到围绕感兴趣的峰值的两个波谷之间的距离。

使用'MinPeakHeight'中的findpeaks()选项预先修剪您的数据。从它的外观来看,没有自动方式来提取你想要的峰值(除非你以某种方式对它们有明确的索引)。这意味着,您必须手动选择它们。

现在,当然会有更多细节需要处理,但考虑到数据集的形状,我认为这里的基本想法可以很好地解决您的问题。

答案 3 :(得分:1)

您需要定义感兴趣的峰值意味着什么,以及您对该峰值宽度的含义。一旦你做了这些事情,你就领先一步。

也许您可以使用查找峰找到每个峰。然后找到槽,其中一个应位于每对峰之间。低谷只是-y的高峰。确保您担心第一个和最后一个峰值/谷值。

接下来,将半高点定义为每个峰和谷之间的高度中间位置。这可以使用曲线上的反向线性插值来完成。

最后,半高宽可能只是这两个半高点之间的距离(在x轴上)。