Main Content

findpeaks

查找局部最大值

说明

示例

pks = findpeaks(data) 返回一个向量,其中包含输入信号向量 data 的局部最大值(峰值)。局部峰值数据样本的值或者大于其两个相邻样本,或者等于 Inf。峰值按出现的顺序输出。非 Inf 信号端点将被排除。如果是平峰,则函数将只返回具有最小索引的点。

示例

[pks,locs] = findpeaks(data) 还返回出现峰值的索引。

示例

[pks,locs,w,p] = findpeaks(data) 还以向量 w 的形式返回峰值的宽度,以向量 p 的形式返回峰的相对高差。

示例

[___] = findpeaks(data,x)x 指定为位置向量,并返回上述语法中的任何输出参量。locswx 的形式表示。

示例

[___] = findpeaks(data,Fs) 指定数据的采样率 Fsdata 的第一个采样假定在时间零处采集。locsw 将转换为时间单位。

示例

[___] = findpeaks(___,Name,Value) 支持上述语法中的任何输入参量,且可使用名称-值参量指定选项。

示例

findpeaks(___) 不带输出参量时用于绘制信号并叠加峰值。

示例

全部折叠

定义一个包含三个峰值的向量并绘制该向量。

data = [25 8 15 5 6 10 10 3 1 20 7];
plot(data)

找出局部最大值。峰值按出现的顺序输出。第一个采样不包括在内,尽管它是最大值。对于平峰,该函数仅返回具有最小索引的点。

pks = findpeaks(data)
pks = 1×3

    15    10    20

使用不带输出参量的 findpeaks 来显示峰值。

findpeaks(data)

创建一个由几条钟形曲线之和组成的信号。指定每条曲线的位置、高度和宽度。

x = linspace(0,1,1000);

Pos = [1 2 3 5 7 8]/10;
Hgt = [3 4 4 2 2 3];
Wdt = [2 6 3 3 4 6]/100;

for n = 1:length(Pos)
    Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end

PeakSig = sum(Gauss);

绘制各单条曲线及其总和。

plot(x,Gauss,'--',x,PeakSig)

使用具有默认设置的 findpeaks 查找信号的峰值及其位置。

[pks,locs] = findpeaks(PeakSig,x);

使用 findpeaks 绘制峰值并标记它们。

findpeaks(PeakSig,x)

text(locs+.02,pks,num2str((1:numel(pks))'))

从最高到最低对峰值进行排序。

[psor,lsor] = findpeaks(PeakSig,x,'SortStr','descend');

findpeaks(PeakSig,x)

text(lsor+.02,psor,num2str((1:numel(psor))'))

创建一个由分布在一个完整余弦周期上的几条钟形曲线之和组成的信号。指定每条曲线的位置、高度和宽度。

x = linspace(0,1,1000);

base = 4*cos(2*pi*x);

Pos = [1 2 3 5 7 8]/10;
Hgt = [3 7 5 5 4 5];
Wdt = [1 3 3 4 2 3]/100;

for n = 1:length(Pos)
    Gauss(n,:) =  Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end

PeakSig = sum(Gauss)+base;

绘制各单条曲线及其总和。

plot(x,Gauss,'--',x,PeakSig,x,base)

使用 findpeaks 定位并绘制相对高差至少为 4 的峰值。

findpeaks(PeakSig,x,'MinPeakProminence',4,'Annotate','extents')

只有最高和最低峰值满足该条件。

显示所有峰值的相对高差以及相对高差一半处的峰宽。

[pks,locs,widths,proms] = findpeaks(PeakSig,x);
widths
widths = 1×6

    0.0154    0.0431    0.0377    0.0625    0.0274    0.0409

proms
proms = 1×6

    2.6816    5.5773    3.1448    4.4171    2.9191    3.6363

太阳黑子是一种周期性出现的现象。已知其数量大约每 11 年达到峰值。

加载文件 sunspot.dat,其中包含从 1700 年到 1987 年每年观测到的太阳黑子的平均数量。查找并绘制最大值。

load sunspot.dat

year = sunspot(:,1);
avSpots = sunspot(:,2);

findpeaks(avSpots,year)

通过忽略间距非常近的峰值来改进对周期持续时间的估计。再次查找并绘制峰值,但现在将可接受的峰间距限制为大于 6 年。

findpeaks(avSpots,year,'MinPeakDistance',6)

使用 findpeaks 返回的峰值位置来计算最大值之间的均值间距。

[pks,locs] = findpeaks(avSpots,year,'MinPeakDistance',6);

meanCycle = mean(diff(locs))
meanCycle = 10.9600

使用年份数据创建一个 datetime 数组。假设太阳黑子是在每年 3 月 20 日(接近春分)统计的。找出太阳黑子的峰值年份。使用 years 函数将最小峰间距指定为 duration

ty = datetime(year,3,20);

[pk,lk] = findpeaks(avSpots,ty,'MinPeakDistance',years(6));

plot(ty,avSpots,lk,pk,'o')

使用 datetime 功能计算太阳黑子的均值周期。

dttmCycle = years(mean(diff(lk)))
dttmCycle = 10.9600

用这些数据创建一个时间表。以年为单位指定时间变量。绘制数据图。显示该时间表的最后五个条目。

TT = timetable(years(year),avSpots);
plot(TT.Time,TT.Variables)

entries = TT(end-4:end,:)
entries=5×1 timetable
      Time      avSpots
    ________    _______

    1983 yrs     66.6  
    1984 yrs     45.9  
    1985 yrs     17.9  
    1986 yrs     13.4  
    1987 yrs     29.3  

加载一段以 7418 Hz 采样的音频信号。选择 200 个采样。

load mtlb
select = mtlb(1001:1200);

找出间隔至少为 5 ms 的峰值。

为了应用此约束,findpeaks 选择信号中最高的峰值,并消除在其 5 ms 范围内的所有峰值。然后,该函数对剩余峰值中的最高峰值重复该过程并进行迭代,直到处理完要考虑的所有峰值。

findpeaks(select,Fs,'MinPeakDistance',0.005)

找出振幅至少为 1 V 的峰值。

findpeaks(select,Fs,'MinPeakHeight',1)

找出比相邻采样至少高 1 V 的峰值。

findpeaks(select,Fs,'Threshold',1)

找出信号在抵达更高峰值前于任一侧下降至少 1 V 的峰值。

findpeaks(select,Fs,'MinPeakProminence',1)

如果数据大于给定的饱和点,传感器可以返回裁剪后的读数。您可以选择忽略这些没有意义的峰值,也可以选择将它们纳入您的分析中。

生成一个由频率为 5 Hz 和 3 Hz 的三角函数的乘积组成的信号,嵌入方差为 0.1² 的高斯白噪声中。信号以 100 Hz 的速率进行采样,持续时间为一秒。重置随机数生成器以获得可重现的结果。

rng default

fs = 1e2;
t = 0:1/fs:1-1/fs;

s = sin(2*pi*5*t).*sin(2*pi*3*t)+randn(size(t))/10;

通过截断大于 0.32 的指定边界的每个读数来模拟经过饱和处理的测量值。绘制经过饱和处理的信号。

bnd = 0.32;
s(s>bnd) = bnd;

plot(t,s)
xlabel('Time (s)')

找到信号的峰值。findpeaks 仅报告每个平峰的上升沿。

[pk,lc] = findpeaks(s,t);

hold on
plot(lc,pk,'x')

使用 'Threshold' 名称-值对组排除平峰。要求峰值与其相邻峰值之间的最小振幅差为 10-4

[pkt,lct] = findpeaks(s,t,'Threshold',1e-4);

plot(lct,pkt,'o','MarkerSize',12)

创建一个由几条钟形曲线之和组成的信号。指定每条曲线的位置、高度和宽度。

x = linspace(0,1,1000);

Pos = [1 2 3 5 7 8]/10;
Hgt = [4 4 2 2 2 3];
Wdt = [3 8 4 3 4 6]/100;

for n = 1:length(Pos)
    Gauss(n,:) =  Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end

PeakSig = sum(Gauss);

绘制各单条曲线及其总和。

plot(x,Gauss,'--',x,PeakSig)
grid

在相对高差的一半处测量波峰的宽度。

findpeaks(PeakSig,x,'Annotate','extents')

再次测量宽度,这次在半高处测量。

findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight')
title('Signal Peak Widths')

输入参数

全部折叠

输入数据,指定为向量。data 必须为实数,并且必须有至少三个元素。

数据类型: double | single

位置,指定为向量或 datetime 数组。x 必须单调递增,并且长度与 data 相同。如果省略 x,则将 data 的索引用作位置。

数据类型: double | single | datetime

采样率,指定为正标量。采样率是单位时间内的采样数。如果时间单位是秒,则采样率的单位是赫兹。

数据类型: double | single

名称-值参数

将可选的参量对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参量名称,Value 是对应的值。名称-值参量必须出现在其他参量后,但对各个参量对组的顺序没有要求。

如果使用的是 R2021a 之前的版本,请使用逗号分隔每个名称和值,并用引号将 Name 引起来。

示例: 'SortStr','descend','NPeaks',3 查找信号的三个最高峰值。

要返回的最大峰值数,指定为正整数标量。findpeaks 从输入数据的第一个元素开始运算,并在峰值数量达到值 'NPeaks' 时终止。

数据类型: double | single

峰值排序,指定为以下值之一:

  • 'none' 按照峰值在输入数据中出现的顺序返回峰值。

  • 'ascend' 按升序或递增顺序(从最小值到最大值)返回峰值。

  • 'descend' 按降序(从最大值到最小值)返回峰值。

最小峰值高度,指定为实数标量。使用此参量可使 findpeaks 仅返回高于 'MinPeakHeight' 的峰值。指定最小峰值高度可以减少处理时间。

数据类型: double | single

最小峰值相对高差,指定为实数标量。使用此参量可使 findpeaks 仅返回那些相对高差至少为 'MinPeakProminence' 的峰值。有关详细信息,请参阅相对高差

数据类型: double | single

峰值与其邻点之间的最小高度差,指定为非负实数标量。使用此参量可使 findpeaks 仅返回与紧邻峰值的高度差至少为 'Threshold' 值的那些峰值。

数据类型: double | single

最小峰间距,指定为正实数标量。当您为 'MinPeakDistance' 指定值时,算法会选择信号中最高的峰值,并忽略在其 'MinPeakDistance' 范围内的所有峰值。然后,该函数对剩余峰值中的最高峰值重复该过程并进行迭代,直到处理完要考虑的所有峰值。

  • 如果指定位置向量 x,则 'MinPeakDistance' 必须以 x 的形式表示。如果 xdatetime 数组,则将 'MinPeakDistance' 指定为 duration 标量或以天表示的数值标量。

  • 如果指定采样率 Fs,则 'MinPeakDistance' 必须以时间单位表示。

  • 如果既未指定 x,也未指定 Fs,则 'MinPeakDistance' 必须以采样单位表示。

使用此参量可以让 findpeaks 忽略在较大峰值的邻域中出现的小峰值。

数据类型: double | single | duration

宽度测量值的参考高度,指定为 'halfprom''halfheight'findpeaks 将峰宽估计为下降信号与水平参考线相交点(截距点)之间的距离。使用在 'WidthReference' 中指定的标准选择参考线的高度:

  • 'halfprom' 将参考线定位在峰值下方,垂直距离等于峰值相对高差的一半。有关详细信息,请参阅相对高差

  • 'halfheight' 将参考线定位在峰值高度的一半处。如果参考线的任何截距点落在了 'MinPeakHeight''MinPeakProminence''Threshold' 设置所确定的峰值的边界之外,则该参考线将被截断。峰值之间的边界由峰值之间最低波谷的水平位置确定。高度小于零的峰值将被丢弃。

截距点的位置通过线性插值计算得出。

最小峰宽,指定为正实数标量。使用此参量可仅选择宽度至少为 'MinPeakWidth' 的峰值。

  • 如果指定位置向量 x,则 'MinPeakWidth' 必须以 x 的形式表示。如果 xdatetime 数组,则将 'MinPeakWidth' 指定为 duration 标量或以天表示的数值标量。

  • 如果指定采样率 Fs,则 'MinPeakWidth' 必须以时间单位表示。

  • 如果既未指定 x,也未指定 Fs,则 'MinPeakWidth' 必须以采样单位表示。

数据类型: double | single | duration

最大峰宽,指定为正实数标量。使用此参量可仅选择宽度不超出 'MaxPeakWidth' 的峰值。

  • 如果指定位置向量 x,则 'MaxPeakWidth' 必须以 x 的形式表示。如果 xdatetime 数组,则将 'MaxPeakWidth' 指定为 duration 标量或以天表示的数值标量。

  • 如果指定采样率 Fs,则 'MaxPeakWidth' 必须以时间单位表示。

  • 如果既未指定 x,也未指定 Fs,则 'MaxPeakWidth' 必须以采样单位表示。

数据类型: double | single | duration

绘图样式,指定为以下值之一:

  • 'peaks' 绘制信号并注释每个峰值的位置和数值。

  • 'extents' 绘制信号并注释每个峰值的位置、数值、宽度和相对高差。

如果带输出参量调用 findpeaks,则此参量将被忽略。

输出参量

全部折叠

局部最大值,以信号值的向量形式返回。如果没有局部最大值,则 pks 为空。

峰值位置,以向量形式返回。

  • 如果指定位置向量 x,则 locs 将包含峰值索引处 x 的值。

  • 如果指定采样率 Fs,则 locs 是由间隔为 1/Fs 的连续采样时间组成的数值向量。

  • 如果既未指定 x,也未指定 Fs,则 locs 是由整数索引组成的向量。

峰宽,以实数向量形式返回。每个峰值的宽度计算为峰值左右两侧与参考线相交的两点之间的距离,参考线的高度由 WidthReference 指定。交点本身通过线性插值求得。

  • 如果指定位置向量 x,则宽度以 x 的形式表示。

  • 如果指定采样率 Fs,则宽度以时间单位表示。

  • 如果既未指定 x,也未指定 Fs,则宽度以采样单位表示。

峰值相对高差,以实数向量形式返回。峰值的相对高差是信号在峰值两侧必须至少下降多少垂直距离,才会再次上升到比该峰值更高的峰值或达到两侧端点(无更高峰值时)。有关详细信息,请参阅相对高差

详细信息

全部折叠

相对高差

峰值的相对高差根据峰值本身高度及其相对于其他峰值的位置衡量其突出程度。较矮的孤立峰值可能会比虽然较高但在高峰范围中并不显著的一员更加突出。

要测量峰值的相对高差,请执行以下步骤:

  1. 在峰值上放一个标记。

  2. 从峰值向左右延伸一条水平线,直到该线出现以下情况之一:

    • 穿过信号,因为出现更高的峰值

    • 到达信号的左端或右端

  3. 找出步骤 2 中定义的两个区间中每个区间内的信号最小值。此点是波谷或信号端点之一。

  4. 在两个区间的最小值中,较高者即为参考水平。在此水平以上的峰值高度就是其相对高差。

findpeaks 对端点之外的信号行为不做假设,无论其高度如何。因此,步骤 2 和 4 会忽略端点以外的信号行为,该行为通常会影响参考水平的值。例如,假设此信号的峰值如下:

Signal with nine peaks, numbered 1 through 9 from left to right. The valleys between each pair of peaks are labeled from left to right with the letters a through i. In decreasing order of height, the peaks are 2, 6, 1, 8, 4, which is equal to 8, 7, 3, 9, and 5. In decreasing order of height, the valleys are a, g, c, i, f, b, which is equal to f, e, d, and h. For this signal, peak 6 has the highest prominence, even though it is lower than peak 2.

峰值编号左区间位于峰值和以下值之间右区间位于峰值和以下值之间左区间内的最低点右区间内的最低点参考水平(最高最小值)
1左端因峰值 2 产生的交叉点左端点aa
2左端右端左端点h左端点
3因峰值 2 产生的交叉点因峰值 4 产生的交叉点bcc
4因峰值 2 产生的交叉点因峰值 6 产生的交叉点bdb
5因峰值 4 产生的交叉点因峰值 6 产生的交叉点dee
6因峰值 2 产生的交叉点右端dhd
7因峰值 6 产生的交叉点因峰值 8 产生的交叉点fgg
8因峰值 6 产生的交叉点右端fhf
9因峰值 8 产生的交叉点穿过信号(由于存在右端点)hii

扩展功能

C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。

版本历史记录

在 R2007b 中推出