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;
///
/// 废弃,不用
///
public bool IsPercent
{
get { return ispercent; }
set
{
if (ispercent != value)
{
ispercent = value;
NotifyPropertyChanged("IsPercent");
}
}
}
private double psigma;
///
/// 废弃,不用
///
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");
}
public void DoFrameFilter(int target, int start_grid, double[] _frame)
{
//转为 int[] frame
int[] frame = new int[_frame.Length];
for (int i = 0; i < _frame.Length; i++)
{
if (double.IsNaN(_frame[i]))
frame[i] = Misc.MyBase.NULL_VALUE;
else
frame[i] = (int)(_frame[i] * 100);
}
DoFrameFilter(target, start_grid, frame);
}
#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"
};
}
}
}