我不是信号处理专家。我正在使用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;
}
最佳答案
这是一个相当简单的策略,可能会给您一些起点。算法概述如下
{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/