using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using FLY.Thick.Base.Common; using FLY.Thick.Base.IService; namespace FLY.Thick.Base.Server { //1.剔除 偏离平均值 大于 设定值 //2.权重 滤波 public class Reject : IRejectService, INotifyPropertyChanged, Misc.ISaveToXml { private bool enable; public bool Enable { get { return enable; } set { if (enable != value) { enable = value; NotifyPropertyChanged("Enable"); } } } private int number; public int Number { get { return number; } set { if (number != value) { number = value; NotifyPropertyChanged("Number"); } } } private double threshold_ratio; public double ThresholdRatio { get { return threshold_ratio; } set { if (threshold_ratio != value) { threshold_ratio = value; NotifyPropertyChanged("ThresholdRatio"); } } } private bool ispercent; /// <summary> /// 废弃,不用 /// </summary> public bool IsPercent { get { return ispercent; } set { if (ispercent != value) { ispercent = value; NotifyPropertyChanged("IsPercent"); } } } private double psigma; /// <summary> /// 废弃,不用 /// </summary> public double PSigma { get { return psigma; } set { if (psigma != value) { psigma = value; NotifyPropertyChanged("PSigma"); } } } private int sigma; public int Sigma { get { return sigma; } set { if (sigma != value) { sigma = value; NotifyPropertyChanged("Sigma"); } } } private int range1; public int Range1 { get { return range1; } set { if (range1 != value) { range1 = value; NotifyPropertyChanged("Range1"); } } } private int range2; public int Range2 { get { return range2; } set { if (range2 != value) { range2 = value; NotifyPropertyChanged("Range2"); } } } private int target; public int Target { get { return target; } private set { if (target != value) { target = value; NotifyPropertyChanged("Target"); } } } private bool[] bfilterdats;//该数据是否需要剔除 private int[] filterdats;//滤波后的数据 private int[] rejectdats;//剔除后的数据 private int[] sigmadats;//剔除用sigma数据 public int dats_len;//上面三个的数据长度 private int poslen = 8900; public int PosLen { get { return poslen; } set { if (poslen != value) { poslen = value; NotifyPropertyChanged("PosLen"); } } } private int posofgrid = 10; public int PosOfGrid { get { return posofgrid; } set { if (posofgrid != value) { posofgrid = value; NotifyPropertyChanged("PosOfGrid"); } } } public int[] FilterDatas { get { return filterdats; } } public int[] RejectDatas { get { return rejectdats; } } public int[] SigmaDatas { get { return sigmadats; } } public void Clear() { for (int i = 0; i < dats_len; i++) filterdats[i] = Misc.MyBase.NULL_VALUE; for (int i = 0; i < dats_len; i++) rejectdats[i] = Misc.MyBase.NULL_VALUE; for (int i = 0; i < dats_len; i++) sigmadats[i] = Misc.MyBase.NULL_VALUE; for (int i = 0; i < dats_len; i++) bfilterdats[i] = false; } public void Test() { int[] buf = new int[dats_len]; for (int i = 0; i < buf.Length; i++) { buf[i] = 6000; } for (int i = 200; i < 300; i++) { buf[i] += (i - 200); } DoFrameFilter(6100, 0, buf); } private string param_path = "reject.xml"; public Reject() { SetDefault(); this.PropertyChanged += new PropertyChangedEventHandler(Reject_PropertyChanged); } public Reject(string param_path) { if (!string.IsNullOrEmpty(param_path)) this.param_path = param_path; SetDefault(); Load(); this.PropertyChanged += new PropertyChangedEventHandler(Reject_PropertyChanged); } void SetDefault() { Enable = false; Number = 1; ThresholdRatio = 0.93; Range1 = 10; Range2 = Range1; Sigma = 80; int len = PosLen / PosOfGrid; Resize(len); } void Resize(int size) { dats_len = size; filterdats = new int[dats_len]; rejectdats = new int[dats_len]; sigmadats = new int[dats_len]; bfilterdats = new bool[dats_len]; Clear(); } void Reject_PropertyChanged(object sender, PropertyChangedEventArgs e) { //if (GetSavePropertyNames().Contains(e.PropertyName)) //{ // FObjBase.PollModule.Current.Poll_JustOnce(new FObjBase.PollModule.PollHandler(delegate() // { // Save(); // }), this, 2); //} if ((e.PropertyName == "PosLen") || (e.PropertyName == "PosOfGrid")) { int len = PosLen / PosOfGrid; Resize(len); } } public void Load() { Misc.SaveToXmlHepler.Load(param_path, this); } public void Save() { Misc.SaveToXmlHepler.Save(param_path, this); } public void Apply() { Save(); } public void DoFrameFilter(int target, int start_grid, int[] frame) { //if (!Enable) // return; Clear(); int len = frame.Length; if ((start_grid + len) > dats_len) { len = dats_len - start_grid; } Array.Copy(frame, 0, rejectdats, start_grid, len); int range1 = Range1 / PosOfGrid; //滤波 for (int i = start_grid; i < (len + start_grid); i++) { int b = i - range1; int e = i + range1; if (b < 0) b = 0; if (e >= dats_len) e = dats_len - 1; filterdats[i] = Misc.MyMath.Avg(rejectdats, b, e); } //sigma for (int i = start_grid; i < (len + start_grid); i++) { int b = i - Number; int e = i + Number; if (b < 0) b = 0; if (e >= dats_len) e = dats_len - 1; sigmadats[i] = Misc.MyMath.Sigma(filterdats, b, e); } int threshold = (int)(target * ThresholdRatio); //阀值剔除 for (int i = start_grid; i < (len + start_grid); i++) { if (Misc.MyBase.ISVALIDATA(rejectdats[i]) && (rejectdats[i] < threshold)) { bfilterdats[i] = true; } } int sigma; sigma = Sigma; //sigma剔除 for (int i = start_grid; i < (len + start_grid); i++) { if ((!Misc.MyBase.ISVALIDATA(sigmadats[i])) || (sigmadats[i] > sigma)) { bfilterdats[i] = true; } } int reject_b_idx= -1; int reject_e_idx = -1; //半径内全部删除 int range2 = Range2 / PosOfGrid; for (int i = start_grid; i < (start_grid+len); i++) { if (!bfilterdats[i]) { //之前有需要剔除的 if (reject_b_idx != -1) { int b = reject_b_idx - range2; int e = reject_e_idx + range2; if (b < 0) b = 0; if (e >= dats_len) e = dats_len - 1; for (int j = b; j <= e; j++) { rejectdats[j] = Misc.MyBase.NULL_VALUE; } reject_b_idx = -1; i = e; } } else { if (reject_b_idx == -1) { reject_b_idx = i; } reject_e_idx = i; } } if (reject_b_idx != -1) { int b = reject_b_idx - range2; int e = reject_e_idx + range2; if (b < 0) b = 0; if (e >= dats_len) e = dats_len - 1; for (int j = b; j <= e; j++) { rejectdats[j] = Misc.MyBase.NULL_VALUE; } reject_b_idx = -1; } if (Enable) { Array.Copy(rejectdats, start_grid, frame, 0, len); //剩下的全部剔除 for (int i = len; i < frame.Length; i++) { frame[i] = Misc.MyBase.NULL_VALUE; } } Target = target; NotifyPropertyChanged("FilterDatas"); NotifyPropertyChanged("RejectDatas"); NotifyPropertyChanged("SigmaDatas"); } int ToThick(double thk) { if (double.IsNaN(thk)) return Misc.MyBase.NULL_VALUE; else return (int)(thk * 100); } public void DoFrameFilter(double _target, int start_grid, double[] _thks) { int[] frame = _thks.Select(d => ToThick(d)).ToArray(); DoFrameFilter(ToThick(_target), start_grid, frame); for (int i = 0; i < frame.Count(); i++) { if (!Misc.MyBase.ISVALIDATA(frame[i])) { _thks[i] = double.NaN; } } } #region INotifyPropertyChanged 成员 protected void NotifyPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; #endregion public string[] GetSavePropertyNames() { return new string[]{ "Enable", "ThresholdRatio", "Range1", "Range2", "Sigma" }; } } }