我试图在Matlab中找到一些峰值,但函数findpeaks.m
没有宽度选项。我想要检测的峰值在球中。所有检测到的都在红色方块中。如您所见,它们的宽度较小。有什么帮助吗?
这是我使用的代码:
[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');
答案 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轴上)。