代码之家  ›  专栏  ›  技术社区  ›  Joe Soul-bringer

在Matlab中用噪声数据寻找近似局部最大值

  •  3
  • Joe Soul-bringer  · 技术社区  · 17 年前

    index = find( diff( sign( diff([0; x(:); 0]) ) ) < 0 );
    

    但我相信,只有当数据或多或少地平滑时,这才有效。假设你的数据在小间隔内上下跳跃,但仍然有一些近似的局部最大值。你会如何找到这些点?你可以将向量划分为n个部分,并找到不在每个部分边缘的最大值,但应该有一个更优雅、更快的解决方案。

    4 回复  |  直到 17 年前
        1
  •  2
  •   Mr Fooz    17 年前

    HILBERT , BUTTER ,以及 FILTFILT .

    data = (...the waveform of noisy data...);
    Fs = (...the sampling rate of the data...);
    [b,a] = butter(5,20/(Fs/2),'low');  % Create a low-pass butterworth filter;
                                        %   adjust the values as needed.
    smoothData = filtfilt(b,a,abs(hilbert(data)));  % Apply a hilbert transform
                                                    %   and filter the data.
    

    smoothData

    为了说明这种处理是如何工作的,这里有一些图像显示了录制语音片段的结果。蓝线是原始语音信号,红线是包络(使用HILBERT获得),绿线是低通滤波结果。下图是第一个的放大版本。

    alt text

    index = find(diff(sign(diff([0; x(:); 0]))) < 0);
    maxIndex = index(find(diff(sign(diff([0; x(index); 0]))) < 0));
    

    然而,根据信噪比的不同,尚不清楚需要重复多少次才能得到你感兴趣的局部最大值。这只是一个随机的非滤波选项。 =)

    最大值发现:

    index = find((x > [x(1) x(1:(end-1))]) & (x >= [x(2:end) x(end)]));
    
        2
  •  3
  •   Community Mohan Dere    9 年前

    MEDFILT1 ,或使用 CONV 连同 FSPECIAL 在后一种方法中,您可能希望使用CONV的“相同”参数和FSPECIAL创建的“高斯”滤波器。

    完成过滤后,将其输入最大值查找器。

    编辑: 运行时复杂性

    假设输入向量的长度为X,滤波器核的长度为K。

    中值过滤器可以通过运行插入排序来工作,因此它应该是O(X K

    当K很小时,conv使用直接O(X*K)算法。当X和K几乎相同时,使用快速傅里叶变换会更快。该实现为O(X log X+K log K)。Matlab足够聪明,可以根据输入大小自动选择正确的算法。

        3
  •  1
  •   Matthias Wandel    17 年前

    如果你的数据上下跳很多,那么函数将有许多局部最大值。 所以我假设你不想找到所有的局部最大值。但是,你对当地最大值的标准是什么?如果你有一个标准,那么你可以为此设计一个方案或算法。

    我现在想,也许你应该先对数据应用低通滤波器,然后找到局部最大值。尽管滤波后的局部最大值的位置可能与滤波前的位置不完全对应。

        4
  •  1
  •   user85109    17 年前

    有两种方法可以看待这个问题。人们可以将此视为一个主要的平滑问题,使用滤波工具对数据进行平滑处理,然后使用各种插值方法(可能是插值样条)进行插值。找到插值样条的局部最大值是一件很容易的事情。(请注意,您通常应该在这里使用真样条,而不是pchip插值。当您在interp1中指定“三次”插值时使用的pchip方法,将无法准确定位落在两个数据点之间的局部最小值。)

    解决这个问题的另一种方法是我更喜欢的方法。这里使用最小二乘样条模型来平滑数据,并产生近似值而不是插值值。这种最小二乘样条具有允许用户进行大量控制以将他们对问题的知识引入模型的优点。例如,科学家或工程师通常拥有关于所研究过程的信息,如单调性。这可以内置到最小二乘样条模型中。另一个相关的选项是使用平滑样条线。它们也可以通过内置正则化约束来构建。如果你有样条线工具箱,那么spap2将对拟合样条线模型有用。然后fnmin会找到一个最小化器。(最大化器很容易从最小化代码中获得。)

    当数据点等距时,采用滤波方法的平滑方案通常最简单。不等间距可能会推动最小二乘样条模型。另一方面,在最小二乘样条曲线中,结点位置可能是一个问题。我的观点是,这两种方法都有其优点,可以产生可行的结果。