如何在MATLAB中区分双峰值和单峰值阵列?

时间:2012-01-05 20:59:03

标签: matlab

enter image description here

如何区分双峰和单峰阵列?

此外,如果数组代表双峰,如何找到两个峰之间的最小点?在找到最小点时,不应考虑峰外(左峰和左峰的左侧)的最小点。

3 个答案:

答案 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

Two peaks example

答案 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')

导致: enter image description here

基本上,您正在找到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