3

我不是信号处理方面的专家。我正在使用 c++ 对一维信号进行简单处理。我真的很想知道如何确定具有最高过零率(最高频率!)的部分。有没有简单的方法或方法来告诉这部分的开始和结束。

这张图说明了我的信号的形式, 这张图就是我需要做的(开始和结束两个索引)

编辑:

其实我对开头和结尾的宽度一无所知,它是如此多变。我可以计算过零的数量,但我不知道如何定义它的范围

 double calculateZC(vector<double> signals){
        int ZC_counter=0;
        int size=signals.size();

        for (int i=0; i<size-1; i++){
                if((signals[i]>=0 && signals[i+1]<0) || (signals[i]<0 && signals[i+1]>=0)){
                    ZC_counter++;
                }
        }                       

        return ZC_counter;
    }
4

1 回答 1

3

这是一个相当简单的策略,可能会给您一些起点。算法大纲如下

  • 输入:数据点的向量{y0,y1,...}
  • 参数:
    1. 窗口大小sigma
    2. 0<p<1定义何时开始寻找区域的阈值。
  • {t0,t1}输出:过零次数最多的区域的起点和终点

我不会给出任何 C++ 代码,但该方法应该易于实现。例如,让我们使用以下函数

数学图形

我们想要的是大约 480 到 600 之间的区域,其中零密度高于前面。算法的第一步是计算零点的位置。你可以通过你已经拥有的东西来做到这一点,但不是计算,而是存储i你遇到零的地方的值。

这将为您提供零位置列表

数学图形

从这个列表(您可以直接在上面的 for 循环中执行此操作!)您创建一个与输入数据大小相同的列表,看起来像{0,0,0,...,1,0,..,1,0,..}. 输入数据中的每个过零位置都有 1。

下一步是使用 size 的平滑过滤器对该列表进行平滑处理sigma。在这里,你可以用你喜欢的;在最简单的情况下,移动平均线或高斯滤波器。您选择的越高,您的环视sigma窗口就越大,该窗口测量某个点周围有多少过零。让我给出这个滤波器的输出以及原始的零位置。请注意,我在这里使用了大小为 10 的高斯滤波器

数学图形

在下一步中,您将通过过滤后的数据找到最大值。在这种情况下,它约为 0.15。现在您选择第二个参数,它是该最大值的某个百分比。让我们说p=0.6

最后一步是遍历过滤后的数据,当值大于p您开始记住一个新区域时。只要该值低于p,您就结束此区域并记住开始和结束点。完成数据浏览后,您会看到一个区域列表,每个区域都由起点和终点定义。现在您选择具有最大扩展的区域,您就完成了。

(或者,您可以将过滤器大小添加到最终区域的每一端)

对于上面的例子,我得到了 11 个区域如下

{{164,173},{196,205},{220,230},{241,252},{259,271},{278,290},
{297,309},{318,327},{341,350},{458,468},{476,590}}

其中扩展最大的是最后一个{476,590}。最终结果看起来(使用 1/2 过滤器区域填充)

数学图形

结论

请不要因为我的回答太长而气馁。我试图详细解释一切。实现实际上只是一些循环:

  • 一个循环来创建过零列表{0,0,..,1,0,...}
  • 移动平均滤波器的一个嵌套循环(或者您使用一些库高斯滤波器)。这里可以同时提取最大值
  • 一个循环提取所有区域
  • 如果您尚未在上述步骤中提取最大区域,则循环提取最大区域
于 2013-10-16T01:17:18.227 回答