【Harvest源码分析】GetFourZeroCrossingIntervals函数

背景

一个完整的正弦波存在如下性质,

波峰间隔,波谷间隔,向上过零间隔,向下过零间隔这四者的值理论上应该一致的。
一个正弦波的四段区间值
那么该函数,顾名思义,就是取这四段值的

代码

数据结构

用来保存这四段值得结构 ZeroCrossings

typedef struct {
  double *negative_interval_locations; //向下过零x值
  double *negative_intervals;          //向下过零y值
  int number_of_negatives;             //向下过零个数
  double *positive_interval_locations; //向上过零x值
  double *positive_intervals;          //向上过零y值
  int number_of_positives;             //向上过零个数
  double *peak_interval_locations;     //峰值x值
  double *peak_intervals;              //峰值y值
  int number_of_peaks;                 //峰值个数
  double *dip_interval_locations;      //谷值x值
  double *dip_intervals;               //谷值y值
  int number_of_dips;                  //谷值个数
} ZeroCrossings;

初始化

  int maximum_number = y_length;
  zero_crossings->negative_interval_locations = new double[maximum_number];
  zero_crossings->positive_interval_locations = new double[maximum_number];
  zero_crossings->peak_interval_locations = new double[maximum_number];
  zero_crossings->dip_interval_locations = new double[maximum_number];
  zero_crossings->negative_intervals = new double[maximum_number];
  zero_crossings->positive_intervals = new double[maximum_number];
  zero_crossings->peak_intervals = new double[maximum_number];
  zero_crossings->dip_intervals = new double[maximum_number];

函数ZeroCrossingEngine

计算这四个值都是一个函数,ZeroCrossingEngine.

举个例子(向下过零)

信号如下:

信号

信号时域图如下:

红线部分为两次向下过零点
向下过零

向下过零统计

for (int i = 0; i < y_length - 1; ++i)
    negative_going_points[i] =
      0.0 < filtered_signal[i] && filtered_signal[i + 1] <= 0.0 ? i + 1 : 0;
negative_going_points[y_length - 1] = 0;
// 实际值为 negative_going_points = 
// [0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0]
//

  int *edges = new int[y_length]; // 这里长度实际用不了那么长
  int count = 0;
  for (int i = 0; i < y_length; ++i)
    if (negative_going_points[i] > 0)
      edges[count++] = negative_going_points[i];

// edges 值为
// edges = [5,15,0 .... 0 ]
  if (count < 2) {
    delete[] edges;
    delete[] negative_going_points;
    return 0;
  }
fine edges?

这个含义不是很理解,总体上是将整形的edge数组转成了double型的

  double *fine_edges = new double[count];
  for (int i = 0; i < count; ++i)
    fine_edges[i] = edges[i] - filtered_signal[edges[i] - 1] /
      (filtered_signal[edges[i]] - filtered_signal[edges[i] - 1]);
  // fine_edges = [5.0, 15.0]
输出intervals和locations
  for (int i = 0; i < count - 1; ++i) {
    intervals[i] = fs / (fine_edges[i + 1] - fine_edges[i]);
    interval_locations[i] = (fine_edges[i] + fine_edges[i + 1]) / 2.0 / fs;
  }

其他三种类型计算

向上过零计算就是把原信号反转,然后调用ZeroCrossingEngine计算

  for (int i = 0; i < y_length; ++i) filtered_signal[i] = -filtered_signal[i];
  zero_crossings->number_of_positives = ZeroCrossingEngine(filtered_signal,
      y_length, actual_fs, zero_crossings->positive_interval_locations,
      zero_crossings->positive_intervals);

峰值/谷值是通过计算连续两个点是差值,如果差值最小,则为峰值/谷值

  for (int i = 0; i < y_length - 1; ++i) filtered_signal[i] =
    filtered_signal[i] - filtered_signal[i + 1];
  zero_crossings->number_of_peaks = ZeroCrossingEngine(filtered_signal,
      y_length - 1, actual_fs, zero_crossings->peak_interval_locations,
      zero_crossings->peak_intervals);

  for (int i = 0; i < y_length - 1; ++i)
    filtered_signal[i] = -filtered_signal[i];
  zero_crossings->number_of_dips = ZeroCrossingEngine(filtered_signal,
      y_length - 1, actual_fs, zero_crossings->dip_interval_locations,
      zero_crossings->dip_intervals);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值