/// <summary> /// 构造一个和平台宽度相同的窗口; /// 看窗口内的数据是否相等; /// 如果相等,看两边的数据是否满足上升和下降条件; /// 如果满足则记录位置; /// 否则窗口滑动 /// </summary> /// <param name="srclist"></param> /// <param name="faltwidth"></param> /// <returns></returns> private List <FlatInfo> FindFlat(List <double> input_data, int flat_width) { if (input_data == null) { return(null); } if (input_data.Count == 0) { return(null); } if (flat_width < 2) { return(null); } if (input_data.Count <= flat_width) { return(null); } List <FlatInfo> flist = new List <FlatInfo>(); List <double> window = input_data.GetRange(0, flat_width); for (int i = flat_width - 1; i < input_data.Count; i++) { //取平台窗口大小的数据 if (i > flat_width - 1) { window.RemoveAt(0); window.Add(input_data[i]); } FlatInfo _flat = MakeFlat(window, input_data, i); if (_flat != null) { flist.Add(_flat); } //FlatInfo _positive_flat = MakeFlat(window, input_data, i, true); //if (_positive_flat != null) flist.Add(_positive_flat); //FlatInfo _negative_flat = MakeFlat(window, input_data, i, false); //if (_negative_flat != null) flist.Add(_negative_flat); } if (flist.Count <= 0) { return(null); } return(flist); }
/// <summary> /// midpoint filter /// </summary> /// <param name="srcData"></param> /// <param name="FrameSize"></param> /// <returns></returns> protected virtual double[] Process(double[] input_data, MedianFilterArgs args) { if (input_data == null) { return(null); } if (args == null) { return(null); } if (input_data.Length <= args.FrameSize) { return(input_data); } int _half_window_size = args.FrameSize / 2; int _flat_width = _half_window_size + 1; //一次滤波过程中总有半窗口长度的数据未被滤波 //组织用于恢复平台的原始数据 List <double> _input_data_list = input_data.ToList(); _input_data_list.InsertRange(0, this._his_input_nofilting); _his_input_nofilting = _input_data_list.GetRange(_input_data_list.Count - _half_window_size, _half_window_size);//更新数据偏移 _input_data_list.RemoveRange(_input_data_list.Count - _half_window_size, _half_window_size); _input_data_list.InsertRange(0, this._his_input_list); //中值滤波 double[] _mid_data_buf = _midFilter.Process(input_data, args); if (_mid_data_buf == null) { return(null); } if (_mid_data_buf.Length <= _flat_width) { return(_mid_data_buf); } //组织滤波后的数据,数量应该与input_data_list数据一致 List <double> _mid_data_list = _mid_data_buf.ToList(); _mid_data_list.InsertRange(0, this._his_mid_list); if (_mid_data_list.Count != _input_data_list.Count) { return(null); } //寻找并处理平台 List <FlatInfo> _flat_list = _flatPro.Process(_mid_data_list.ToArray(), args); if (_flat_list != null && _flat_list.Count != 0) { //用原始数据恢复平台 foreach (FlatInfo fi in _flat_list) { _mid_data_list.RemoveRange(fi.StartIndex, fi.FlatWidth); _mid_data_list.InsertRange(fi.StartIndex, _input_data_list.GetRange(fi.StartIndex, fi.FlatWidth)); } } //处理历史数据 _his_mid_list.Clear(); _his_input_list.Clear(); if ((_flat_list == null) || (_flat_list.Count == 0)) { _his_mid_list.AddRange(_mid_data_list.GetRange(_mid_data_list.Count - (_half_window_size + 2), _half_window_size + 2)); _his_input_list.AddRange(_input_data_list.GetRange(_input_data_list.Count - (_half_window_size + 2), _half_window_size + 2)); _mid_data_list.RemoveRange(_mid_data_list.Count - (_half_window_size + 2), _half_window_size + 2); } else { FlatInfo _flat_info = _flat_list[_flat_list.Count - 1]; int _end_index = _flat_info.StopIndex + 1; _his_mid_list.AddRange(_mid_data_list.GetRange(_end_index, _mid_data_list.Count - _end_index)); _his_input_list.AddRange(_input_data_list.GetRange(_end_index, _input_data_list.Count - _end_index)); _mid_data_list.RemoveRange(_end_index, _mid_data_list.Count - _end_index); } //for (int i = _mid_data_list.Count - 1; i >= _mid_data_list.Count - _flat_width; i--) //{ // if (_mid_data_list[i - 1] == _mid_data_list[i]) // { // this._his_mid_list.Clear(); // this._his_input_list.Clear(); // } // else // { // this._his_mid_list.Clear(); // int count = _mid_data_list.Count - i + 1; // this._his_mid_list.AddRange(_mid_data_list.GetRange(i - 1, count)); // _mid_data_list.RemoveRange(i - 1, count); // this._his_input_list.Clear(); // this._his_input_list.AddRange(_input_data_list.GetRange(i - 1, count)); // break; // } //} return(_mid_data_list.ToArray()); }
/// <summary> /// 查找平台 /// </summary> /// <param name="window">平台窗口</param> /// <param name="srclist">源数据</param> /// <param name="endIndex">源数据中平台窗口最后数据的索引</param> /// <param name="bPositiveFlat">查找平台类型:正峰平台,负峰平台</param> /// <returns>平台信息,如果没有则返回null</returns> //private FlatInfo MakeFlat(List<double> window, List<double> input_data_list, int endIndex, bool bPositiveFlat) private FlatInfo MakeFlat(List <double> window, List <double> input_data_list, int endIndex) { if (window == null) { return(null); } if (input_data_list == null) { return(null); } if (input_data_list.Count == 0) { return(null); } if (window.Count == 0) { return(null); } if (endIndex >= input_data_list.Count) { return(null); } if (endIndex < window.Count) { return(null); } IEnumerable <double> var = from v in window where v == window[0] select v; if (var == null) { return(null); } if (var.Count() != window.Count) { return(null); } //检查平台数据是不是比两端的数据大(正平台)或者小(负平台) double _flat_value = input_data_list[endIndex]; int _left_endpoint_index = endIndex - window.Count; if (_left_endpoint_index < 0) { return(null); } int _right_endpoint_index = endIndex + 1; if (_right_endpoint_index >= input_data_list.Count) { return(null); } double _left_endpoint_value = input_data_list[_left_endpoint_index]; double _right_endpoint_value = input_data_list[_right_endpoint_index]; if (((_left_endpoint_value > _flat_value) && (_right_endpoint_value > _flat_value)) || ((_left_endpoint_value < _flat_value) && (_right_endpoint_value < _flat_value))) { FlatInfo midflat = new FlatInfo(); midflat.StartIndex = endIndex - window.Count + 1; midflat.StopIndex = endIndex; midflat.FlatWidth = window.Count; return(midflat); } else { return(null); } #region OLD_CODE //int index = endIndex - window.Count; //if (index < 0) return null; //if (bPositiveFlat) //{ // if (input_data_list[index] >= input_data_list[endIndex]) return null; //} //else //{ // if (input_data_list[index] <= input_data_list[endIndex]) return null; //} //index = endIndex + 1; //if (index >= input_data_list.Count) return null; //if (bPositiveFlat) //{ // if (input_data_list[index] >= input_data_list[endIndex]) return null; //} //else //{ // if (input_data_list[index] <= input_data_list[endIndex]) return null; //} //FlatInfo midflat = new FlatInfo(); //midflat.StartIndex = endIndex - window.Count + 1; //midflat.StopIndex = endIndex; //midflat.FlatWidth = window.Count; //return midflat; #endregion }