编辑:其实这不是意料之外的行为,但我仍然需要一个解决方案。
findpeaks compares each element of data to its neighboring values.
我的数据包含我使用信号处理工具箱中的函数findpeaks检测到的峰值。有时,当我有两次相同的值时,函数似乎没有正确检测到峰值。这在我的数据中非常简单,但这里有一个示例来说明我的问题:
>> values
values =
-0.0324
-0.0371
-0.0393
-0.0387
-0.0331
-0.0280
-0.0216
-0.0134
-0.0011
0.0098
0.0217
0.0352
0.0467
0.0548
0.0639
0.0740
0.0813
0.0858 <-- here should be another peak
0.0858 <--
0.0812
0.0719
0.0600
0.0473
0.0353
0.0239
0.0151
0.0083
0.0034
-0.0001
-0.0025
-0.0043
-0.0057
-0.0048
-0.0038
-0.0026
0.0007
0.0043
0.0062
0.0083
0.0106
0.0111
0.0116
0.0102
0.0089
0.0057
0.0025
-0.0025
-0.0056
现在,findpeaks函数只找到一个峰值:
>> [pks loc] = findpeaks(values)
pks =
0.0116
loc =
42
如果我绘制数据,很明显,findpeaks错过了18/19
位置的其中一个峰值,因为它们都具有值0.08579
。
找到失踪峰的最佳方法是什么?
答案 0 :(得分:1)
如果您有图像处理工具箱,可以使用IMREGIONALMAX找到峰值,之后您可以使用regionprops找到区域的中心(如果这是您需要的),即
bw = imregionalmax(signal);
peakLocations = find(bw); %# returns n peaks for an n-tuple of max-values
stats = regionprops(bw,'Centroid');
peakLocations = cat(1,stats.Centroid); %# returns the center of the n-tuple of max-values
答案 1 :(得分:1)
这是一个古老的话题,但也许有些人仍然在寻找一个更简单的解决方案(就像我今天所做的那样):
除了第一个值之外,您还可以从高原上的所有值中减去一些非常小的固定值。这导致高原上的每个第一个值始终在相应的平台上最高,导致它们被包括为峰值。
只需创建类似代码的部分内容:
peaks = yourdata;
verysmallvalue = .001;
plateauvalue = peaks(1);
for i = 2:size(peaks,1)
if peaks(i) == plateauvalue
peaks(i) = peaks(i) - verysmallvalue;
else
plateauvalue = peaks(i);
end
end
[PKS,LOCS] = findpeaks(peaks);
plot(yourdata);
hold on;
plot(LOCS, yourdata(LOCS), 'Color', 'Red', 'Line', 'None', 'Marker', 'o');
希望这有帮助!
答案 2 :(得分:0)
答案 3 :(得分:0)
我最终编写了自己更简单的findpeaks版本,这似乎符合我的目的。
function [pks,locs] = my_findpeaks(X)
M = numel(X);
pks = [];
locs = [];
if (M < 4)
datamsgid = generatemsgid('emptyDataSet');
error(datamsgid,'Data set must contain at least 4 samples.');
else
for idx=1:M-3
if X(idx)< X(idx+1) && X(idx+1)>=X(idx+2) && X(idx+2)> X(idx+3)
pks = [pks X(idx)];
locs = [locs idx];
end
end
end
end
编辑:为了澄清,问题出现了,当我的峰值正好在两个采样点之间时,这两个采样点的值恰好相同。在超过10,000个案例中,它只发生了几次。
答案 4 :(得分:0)
您描述的行为是R2010b之前的MATLAB版本中的一个已知错误。最小的例子是
findpeaks([0 1 1 0])
返回[]
,而
findpeaks([0 1 0])
返回峰的(位置)。
该错误已在R2010b和更高版本中修复,请参见官方Bug Report。使用该修复程序,findpeaks
返回“具有重复值的峰值”(我称为高原)的上升沿。