12

在此处输入图像描述

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

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

4

3 回答 3

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;

所以前两个峰之间的山谷是索引在firsPointlastPoint之间的点。那么最小值将是

minValue = min(A(firstPoint:lastPoint));

不依赖于图像处理工具箱的解决方案

正如@Nzbuu 指出的那样,两者都依赖于图像处理工具箱函数 bwlabel。所以,这里是为了避免这种情况。首先,我假设数组 P 正确识别了属于峰的点 ( P(i)=1 ) 和属于谷的点 ( P(i)=-1 )。dP = P(i+1)-P(i) = 1如果是这种情况,则可以在或时识别峰谷之间的边界-1

dP = diff(P);

要计算峰值的数量,只需将 1 的数量相加dP

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
于 2012-01-05T21:24:43.713 回答
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

两个峰示例

于 2012-01-06T04:04:47.150 回答
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
于 2012-01-05T22:58:20.590 回答