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

This image说明了我的信号形式,而this image是我需要做的(开始和结束的两个索引)

编辑:

实际上,我对开头和结尾的宽度没有事先的了解,它是如此可变。
我可以计算零交叉的数量,但是我不知道如何定义它的范围

 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;
    }

最佳答案

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

  • 输入:数据点的 vector {y0,y1,...}
  • 参数:
  • 窗口大小sigma
  • 阈值0<p<1定义何时开始寻找区域。

  • 输出:零交叉
  • 最多的区域的起点和终点{t0,t1}
    我不会提供任何C++代码,但是该方法应该易于实现。作为示例,让我们使用以下功能

    我们希望的是零密度比前面高的大约480至600之间的区域。该算法的第一步是计算零位的位置。您可以按已有的方式执行此操作,但无需计数,而是将i的值存储在遇到零的位置。
    这将为您提供零职位列表

    从该列表(您可以直接在上面的for循环中执行此操作!)创建一个列表,该列表的大小与输入数据的大小相同,类似于{0,0,0,...,1,0,..,1,0,..}。输入数据中的每个零交叉位置都标有1。
    下一步是使用sigma大小的平滑过滤器来平滑此列表。在这里,您可以使用自己喜欢的东西。最简单的情况是moving average或高斯滤波器。您选择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滤镜区域填充)

    结论
    请不要因为我回答的长度而气disc。我试图详细解释一切。实现实际上只是一些循环:
  • 一个循环以创建零交叉列表{0,0,..,1,0,...}
  • 移动平均滤波器的一个嵌套循环(或者您使用一些库斯高斯滤波器)。在这里您可以同时提取最大值
  • 一个循环提取所有区域
  • 如果您在上面的步骤
  • 中尚未提取出最大的区域,则执行一个循环以提取最大的区域

    关于c++ - C++,确定零交叉最高的部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19356030/

    10-08 22:07