You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

209 lines
5.7 KiB

#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
namespace opt_algo {
using namespace std;
typedef enum {
k250,
k1000,
} ProcessPointNumType_t;
typedef enum {
k_ecode_ok = 0,
k_ecode_can_not_find_peak = 1,
k_ecode_can_not_find_peak_start = 2,
k_ecode_can_not_find_peak_end = 3,
} Error_t;
class LineContext {
public:
vector<float> raw; //
vector<float> avg; //
vector<float> diff; //
float agvline; //
float baseline_slope; //
float baseline_intercept; //
vector<float> raw250; //
vector<float> avg250; //
vector<float> diff250; //
};
class PeakInfo {
public:
bool find_peak;
float peak_full_area;
float peak_base_line_area;
float area;
int peak_pos;
int peak_start_pos;
int peak_end_pos;
};
class AlgoResult {
public:
/**
* @brief
* 原始数据处理逻辑:
* 1) 1200点中值滤波
* 2) 1200点线性填充到6000点
* 3) 6000点窗口平滑滤波
* 4) 6000点均值压缩到1000点
*
* 5) 1000点 13点滑动均值滤波
* 6) 1000点 20点最小二乘法求斜率
*
* 7) 找峰
* 8)找峰起始位
* 9) 找峰结束位
*
*/
AlgoResult() {
error_code = k_ecode_ok;
lineContext = make_shared<LineContext>();
for (int i = 0; i < 5; i++) {
peakInfo[i] = make_shared<PeakInfo>();
}
}
vector<float> ogigin_val; // 1200
vector<float> supper_val; // 原始数据,线性填充,1200*5=6000
vector<float> supper_median_val; // supper_val 窗口平滑滤波,6000
vector<float> supper_smooth_sub_val; // supper_smooth_val 均值压缩,6000/6=1000
shared_ptr<LineContext> lineContext; // supper_smooth_sub_val 13点滑动均值滤波,1000
Error_t error_code; // 错误码
// result
shared_ptr<PeakInfo> peakInfo[5];
int peakNum;
};
class OptAlgo {
public:
/**
* @brief
*
* @param context
* @param pconfig
* @param ogigin_val expect 1200
*/
static shared_ptr<AlgoResult> calculate(vector<float> ogigin_val, int peaknum);
static int calculate_peak_num(vector<float>& ogigin_val);
static int getAlgoVersion();
private:
static Error_t findpeak(shared_ptr<LineContext> lineContext, int32_t search_start, int32_t peakwindth, shared_ptr<PeakInfo> retpeak);
static int sub_find_peak(shared_ptr<LineContext> lineContext, int start_off, int windos_size, int judge_win_size);
static int find_peak_endpoint(shared_ptr<LineContext> lineContext, int peakpos, int search_direction, int search_windows);
private:
/*******************************************************************************
* 基础方法 *
*******************************************************************************/
/**
* @brief 过采样原始数据
*
* @param inputRaw
* @param nInputLength
* @param nUpSampleRate
* @return vector<float>
*/
static vector<float> super_sampling(vector<float>& inputRaw, int32_t nInputLength, int32_t nUpSampleRate);
/**
* @brief 均值压缩数据
*
* @param inputRaw
* @param nSubSampleRate
* @return vector<float>
*/
static vector<float> sub_sampling(vector<float>& inputRaw, int nSubSampleRate);
/**
* @brief 移动窗口平滑数据
*
* @param inputRaw
* @param windows_size
* @return vector<float>
*/
static vector<float> smooth_windows(vector<float>& inputRaw, int windows_size);
/**
* @brief 移动窗口平滑数据
*
* @param inputRaw
* @param windows_size
* @return vector<float>
*/
static vector<float> median_filtering(vector<float>& inputRaw, int windows_size);
/**
* @brief 计算均值线
*
* @param inputRaw
* @return float
*/
static float find_avg_line(vector<float>& inputRaw);
/**
* @brief 简单曲线求导
*
* @param inputRaw 原始数据
* @return vector<float> 和原始数据等长导数曲线
*/
static vector<float> differentiate(vector<float>& inputRaw);
/**
* @brief 最小二乘法求导
*
* @param inputRaw 原始数据
* @param windows_size 窗口大小
* @return vector<float> 和原始数据等长导数曲线
*/
static vector<float> least_square_method_differentiate(vector<float>& inputRaw, int windows_size);
/**
* @brief 当前数值是否是窗口内最大值(往前windsize/2,往后windowsize/2)
*
* @param val 当前数值指针
* @param windows_size 窗口大小,必须是奇数
* @return true
* @return false
*/
static bool is_maxval_in_windows(float* val, int windows_size);
/**
* @brief 比较两个浮点数是否相等
*
* @param a
* @param b
* @param epsilon
* @return true
* @return false
*/
static bool feq(float a, float b, float epsilon = 0.00001);
/**
* @brief 最小二乘法 求一次函数斜率
*
* @param val
* @param size
* @return float
*/
static void linear_least_squares(vector<float>& x, vector<float>& y, float& slope, float& intercept);
static void linear_least_squares(float* y, int size, float& slope, float& intercept);
static void linear_least_squares_muti_windos(float* y, int size, vector<int> startx, int windowssize, float& slope, float& intercept);
static float get_avg_in_windows(vector<float>& src, int off, int windows);
static void sort_vector(vector<float>& src);
static vector<float> getwindowspoint(vector<float>& src, int off, int windows);
};
} // namespace opt_algo