如何区分双峰和单峰阵列?
此外,如果数组代表双峰,如何找到两个峰之间的最小点?在找到最小点时,不应考虑峰外(左峰和左峰的左侧)的最小点。
答案 0 :(得分:8)
这是一种可能有效的算法,具体取决于信号的噪声程度。在这里,我将峰值定义为大于给定阈值的连接点集。
假设您的原始数据位于数组 A 中。首先,找到一个门槛:
t = (max(A)+min(A))/2;
接下来,找到大于此阈值的所有点 t :
P = A>t;
使用bwlabel
计算大于 t 的连接条目点数L = bwlabel(P);
numberOfPeaks = max(L);
现在 numberOfPeaks 应该告诉您数据中有多少峰值(连接点大于阈值)
现在要找到两个峰之间的最小点,我们需要使用标签矩阵 L 来识别那些分隔两个峰的点。
firstPoint = find(L==1,1,'last')+1;
lastPoint = find(L==2,1,'first')-1;
因此,前两个峰值之间的谷值是 firsPoint 和 lastPoint 之间的索引点。最小值将是
minValue = min(A(firstPoint:lastPoint));
不依赖于图像处理工具箱的解决方案
正如@Nzbuu所说,aboth依赖于图像处理工具箱功能bwlabel。所以,这是避免这种情况。首先,我假设数组P正确识别属于峰值的点( P(i)= 1 )和属于谷值的点( P(i)= - 1 )。如果是这种情况,可以在dP = P(i+1)-P(i) = 1
或-1
时识别峰和谷之间的边界。
dP = diff(P);
要计算峰数,只需将dP
中的1的数量相加:
numberOfPeaks = sum(dP==1);
识别第一个山谷的点位于
之间firstPoint = find(dP==-1,1,'first')+1 %# the -1 represents the last point of the peak so add 1
lastPoint = find(dP==1,2,'first'); #% Find the start of the second peak
lastPoint = lastPoint(end); #% Keep the last value
答案 1 :(得分:8)
我发现PEAKDET函数非常可靠和快速,尽管它是基于循环的。它不需要预先平滑噪声数据,但会发现局部最大和最小极值,其差值大于参数delta
。
由于PEAKDET从左向右运行,有时会错过右侧站点的峰值。为了避免它,我更喜欢运行它两次:
%# some data
n = 100;
x = linspace(0,3*pi,n);
y = sin(x) + rand(1,n)/5;
%# run peakdet twice left-to-right and right-to-left
delta = 0.5;
[ymaxtab, ymintab] = peakdet(y, delta, x);
[ymaxtab2, ymintab2] = peakdet(y(end:-1:1), delta, x(end:-1:1));
ymaxtab = unique([ymaxtab; ymaxtab2],'rows');
ymintab = unique([ymintab; ymintab2],'rows');
%# plot the curve and show extreme points based on number of peaks
plot(x,y)
hold on
if size(ymaxtab,1) == 2 && size(ymintab,1) == 1 %# if double peak
plot(ymintab(:,1),ymintab(:,2),'r.','markersize',30)
elseif size(ymaxtab,1) == 1 && size(ymintab,1) == 0 %# if single peak
plot(ymaxtab(:,1),ymaxtab(:,2),'r.','markersize',30)
else %# if more (or less)
plot(ymintab(:,1),ymintab(:,2),'r.','markersize',30)
plot(ymaxtab(:,1),ymaxtab(:,2),'r.','markersize',30)
end
hold off
答案 2 :(得分:5)
您可以按如下方式找到当地的最小/最大值:
x = 0:.1:4*pi;
y = sin(x);
plot(x,y)
diffy = diff(y);
localMin = find(diffy(1:end-1)<=0 & diffy(2:end) > 0)+1;
localMax = find(diffy(1:end-1)>=0 & diffy(2:end) < 0)+1;
hold on
plot(x(localMin),y(localMin),'dg')
plot(x(localMax),y(localMax),'*r')
导致:
基本上,您正在找到y值之间的差异改变符号的位置。如果您的数据有噪音,这将导致大量本地最小/最大值,您可能需要过滤数据。
要找到两个峰值之间的最小值,您可以执行以下操作:
if numel(localMax) == 1
fprintf('The max value is: %f',y(localMax));
elseif numel(localMax > 1)
betweenPeaksIndex = localMin(localMin > localMax(1) & localMin <localMax(2));
fprintf('The min between the first 2 peaks is: %f',y(betweenPeaksIndex));
else
fprintf('The was no local Max ..???');
end