将峰值检测算法应用于实时数据



我有一个检测实时数据峰值的功能。这个线程中提到了算法。它看起来像这样:

std::vector<int> smoothedZScore(std::vector<float> input)
{
//lag 5 for the smoothing functions
int lag = 5;
//3.5 standard deviations for signal
float threshold = 3.5;
//between 0 and 1, where 1 is normal influence, 0.5 is half
float influence = .5;
if (input.size() <= lag + 2)
{
std::vector<int> emptyVec;
return emptyVec;
}
//Initialise variables
std::vector<int> signal(input.size(), 0.0);
std::vector<float> filteredY(input.size(), 0.0);
std::vector<float> avgFilter(input.size(), 0.0);
std::vector<float> stdFilter(input.size(), 0.0);
std::vector<float> subVecStart(input.begin(), input.begin() + lag);
double sum = std::accumulate(std::begin(subVecStart), std::end(subVecStart), 0.0);
double mean =  sum / subVecStart.size();
double accum = 0.0;
std::for_each (std::begin(subVecStart), std::end(subVecStart), [&](const double d) {
accum += (d - mean) * (d - mean);
});
double stdev = sqrt(accum / (subVecStart.size()-1));
//avgFilter[lag] = mean(subVecStart);
avgFilter[lag] = mean;
//stdFilter[lag] = stdDev(subVecStart);
stdFilter[lag] = stdev;
for (size_t i = lag + 1; i < input.size(); i++)
{
if (std::abs(input[i] - avgFilter[i - 1]) > threshold * stdFilter[i - 1])
{
if (input[i] > avgFilter[i - 1])
{
signal[i] = 1; //# Positive signal
}
else
{
signal[i] = -1; //# Negative signal
}
//Make influence lower
filteredY[i] = influence* input[i] + (1 - influence) * filteredY[i - 1];
}
else
{
signal[i] = 0; //# No signal
filteredY[i] = input[i];
}
//Adjust the filters
std::vector<float> subVec(filteredY.begin() + i - lag, filteredY.begin() + i);
//        avgFilter[i] = mean(subVec);
//        stdFilter[i] = stdDev(subVec);
}
return signal;
}

在我的代码中,我从IMU传感器读取实时3轴加速度计值,并将其显示为图形。我需要使用上述算法来检测信号的峰值。我在代码中添加了函数。假设实时值如下:

double x = sample->acceleration_g[0];
double y = sample->acceleration_g[1];
double z = sample->acceleration_g[2];

如何将此值传递给上述函数并检测峰值。

我试着这样称呼:smoothedZScore(x)

但给了我一个错误:

settings.cpp:230:40: error: no matching function for call to 'smoothedZScore'
settings.cpp:92:18: note: candidate function not viable: no known conversion from 'double' to 'std::vector<float>' for 1st argument

编辑

该算法至少需要7个样本才能输入。所以我想我可能需要将实时数据存储在缓冲区中。

但我很难理解如何将样本存储在缓冲区中并应用于峰值检测算法。

你能给我看一个可能的解决方案吗?

您需要重写算法。你的问题不仅仅是一个实时问题,你还需要一个因果解决方案。你的功能不是因果关系。

实际上,您需要一个类,并且该类需要增量计算标准偏差。

最新更新