这是一种可能有效的算法,具体取决于信号的嘈杂程度.在这里,我将峰值定义为连接点集合大于给定阈值.
假设您的原始数据在阵列A中.首先,找到一个门槛:
t = (max(A)+min(A))/2;
Run Code Online (Sandbox Code Playgroud)
接下来,找到大于此阈值t的所有点:
P = A>t;
Run Code Online (Sandbox Code Playgroud)
使用bwlabel计算大于t的连接条目点数
L = bwlabel(P);
numberOfPeaks = max(L);
Run Code Online (Sandbox Code Playgroud)
现在numberOfPeaks应该告诉您数据中有多少峰(连接点大于阈值)
现在要找到两个峰之间的最小点,我们需要使用标签矩阵L识别那些分离两个峰的点.
firstPoint = find(L==1,1,'last')+1;
lastPoint = find(L==2,1,'first')-1;
Run Code Online (Sandbox Code Playgroud)
因此,前两个峰之间的谷是firsPoint和lastPoint之间的索引点.那么最低限度就是
minValue = min(A(firstPoint:lastPoint));
Run Code Online (Sandbox Code Playgroud)
不依赖于图像处理工具箱的解决方案
正如@Nzbuu所说,aboth依赖于图像处理工具箱功能bwlabel.所以,这是避免这种情况.首先,假设阵列P正确地识别属于峰值(P(i)= 1)的点和属于谷值(P(i)= - 1)的点.如果是这种情况,可以在dP = P(i+1)-P(i) = 1
或时识别峰和谷之间的边界-1
.
dP = diff(P);
Run Code Online (Sandbox Code Playgroud)
要计算峰值数,只需将1的数量相加dP
:
numberOfPeaks = sum(dP==1);
Run Code Online (Sandbox Code Playgroud)
识别第一个山谷的点位于两者之间
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
Run Code Online (Sandbox Code Playgroud)
虽然它是基于循环的,但我发现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
Run Code Online (Sandbox Code Playgroud)
小智 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')
Run Code Online (Sandbox Code Playgroud)
导致:
基本上,您正在找到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
Run Code Online (Sandbox Code Playgroud)