Reject.cs 6.94 KB
Newer Older
1
using AutoMapper;
潘栩锋's avatar
潘栩锋 committed
2
using FLY.Thick.Base.IService;
3 4
using FObjBase;
using Misc;
5
using Newtonsoft.Json;
6 7 8
using System;
using System.Collections.Generic;
using System.ComponentModel;
9
using System.IO;
10
using System.Linq;
潘栩锋's avatar
潘栩锋 committed
11 12 13 14
namespace FLY.Thick.Base.Server
{
    //1.剔除 偏离平均值 大于 设定值
    //2.权重 滤波
15
    public class Reject : IRejectService, INotifyPropertyChanged
潘栩锋's avatar
潘栩锋 committed
16
    {
17 18 19

        public bool Enable { get; set; }

20 21 22 23
        /// <summary>
        /// 规格范围, (value - Target)/Target > LimitRangeRatio 就会被剔除
        /// </summary>
        public double LimitRangeRatio { get; set; }
24

25
        public double ThresholdRatio { get; set; }
潘栩锋's avatar
潘栩锋 committed
26

27

28
        public int SmoothRange { get; set; }
29

30
        public int RejectRange { get; set; }
31

32 33 34 35
        /// <summary>
        /// 调试数据更新时间,用于让客户端 决定什么时候 下载调试数据
        /// </summary>
        public DateTime DebugUpdateTime { get; private set; }
潘栩锋's avatar
潘栩锋 committed
36

37
        private RejectDebugData rejectDebug;
潘栩锋's avatar
潘栩锋 committed
38

39
        private string param_path = "reject.json";
潘栩锋's avatar
潘栩锋 committed
40 41 42 43 44
        public Reject()
        {
            SetDefault();

        }
45 46

        public Reject(string param_path)
潘栩锋's avatar
潘栩锋 committed
47 48 49 50 51 52 53 54
        {
            if (!string.IsNullOrEmpty(param_path))
                this.param_path = param_path;

            SetDefault();
            Load();
        }

55
        void SetDefault()
潘栩锋's avatar
潘栩锋 committed
56 57
        {
            Enable = false;
58
            LimitRangeRatio = 0.3;
潘栩锋's avatar
潘栩锋 committed
59 60
            ThresholdRatio = 0.93;

61 62
            SmoothRange = 10;
            RejectRange = 300;
潘栩锋's avatar
潘栩锋 committed
63
        }
64

65
        public bool Load()
潘栩锋's avatar
潘栩锋 committed
66
        {
67
            return RejectJsonDb.Load(param_path, this);
潘栩锋's avatar
潘栩锋 committed
68
        }
69
        public bool Save()
潘栩锋's avatar
潘栩锋 committed
70
        {
71 72
            return RejectJsonDb.Save(param_path, this);

潘栩锋's avatar
潘栩锋 committed
73
        }
74
        public void Apply()
潘栩锋's avatar
潘栩锋 committed
75 76 77
        {
            Save();
        }
78 79

        public void DoFrameFilter(double target, int posOfGrid, int start_grid, double[] frame)
潘栩锋's avatar
潘栩锋 committed
80 81
        {

82 83
            var rejectDatas = (double[])frame.Clone();

潘栩锋's avatar
潘栩锋 committed
84 85 86



87 88 89 90 91 92 93
            int smoothRange = SmoothRange / posOfGrid;
            if (smoothRange <= 0) smoothRange = 1;
            int len = frame.Count();

            var filterDatas = new double[len];
            //滤波
            for (int i = 0; i < len; i++)
潘栩锋's avatar
潘栩锋 committed
94
            {
95 96
                int b = i - smoothRange;
                int e = i + smoothRange;
潘栩锋's avatar
潘栩锋 committed
97 98

                if (b < 0) b = 0;
99 100 101 102
                if (e >= len) e = len - 1;
                List<double> datas = new List<double>();
                for (int j = b; j <= e; j++)
                    datas.Add(rejectDatas[j]);
潘栩锋's avatar
潘栩锋 committed
103

104
                filterDatas[i] = datas.AverageNoNull();
潘栩锋's avatar
潘栩锋 committed
105 106 107
            }


108 109
            double threshold = target * ThresholdRatio;
            double limitRange = LimitRangeRatio * target;
潘栩锋's avatar
潘栩锋 committed
110

111
            bool[] bfilterdats = new bool[len];
潘栩锋's avatar
潘栩锋 committed
112
            //阀值剔除
113
            for (int i = 0; i < len; i++)
潘栩锋's avatar
潘栩锋 committed
114
            {
115
                if (!double.IsNaN(rejectDatas[i]))
潘栩锋's avatar
潘栩锋 committed
116
                {
117 118 119 120 121 122 123 124
                    if (rejectDatas[i] < threshold)
                    {
                        bfilterdats[i] = true;
                    }
                    else if (Math.Abs(target - rejectDatas[i]) > limitRange)
                    {
                        bfilterdats[i] = true;
                    }
潘栩锋's avatar
潘栩锋 committed
125 126 127 128
                }
            }


129 130
            int reject_b_idx = -1;
            int reject_e_idx = -1;
潘栩锋's avatar
潘栩锋 committed
131
            //半径内全部删除
132 133 134 135 136
            int reject_range = RejectRange / posOfGrid;
            if (reject_range < 0)
                reject_range = 0;

            for (int i = 0; i < len; i++)
潘栩锋's avatar
潘栩锋 committed
137 138 139 140 141 142
            {
                if (!bfilterdats[i])
                {
                    //之前有需要剔除的
                    if (reject_b_idx != -1)
                    {
143 144
                        int b = reject_b_idx - reject_range;
                        int e = reject_e_idx + reject_range;
潘栩锋's avatar
潘栩锋 committed
145
                        if (b < 0) b = 0;
146
                        if (e >= len) e = len - 1;
潘栩锋's avatar
潘栩锋 committed
147 148
                        for (int j = b; j <= e; j++)
                        {
149
                            rejectDatas[j] = double.NaN;
潘栩锋's avatar
潘栩锋 committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
                        }
                        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)
            {
166 167
                int b = reject_b_idx - reject_range;
                int e = reject_e_idx + reject_range;
潘栩锋's avatar
潘栩锋 committed
168
                if (b < 0) b = 0;
169
                if (e >= len) e = len - 1;
潘栩锋's avatar
潘栩锋 committed
170 171
                for (int j = b; j <= e; j++)
                {
172
                    rejectDatas[j] = double.NaN;
潘栩锋's avatar
潘栩锋 committed
173 174 175 176
                }
                reject_b_idx = -1;
            }

177
            if (Enable)
潘栩锋's avatar
潘栩锋 committed
178
            {
179
                Array.Copy(rejectDatas, 0, frame, 0, len);
潘栩锋's avatar
潘栩锋 committed
180 181
            }

182 183 184 185 186 187 188 189 190 191 192 193
            var rejectDebug = new RejectDebugData
            {
                posOfGrid = posOfGrid,
                start_grid = start_grid,
                target = target,
                filterDatas = filterDatas,
                rejectDatas = rejectDatas,
            };

            this.rejectDebug = rejectDebug;
            this.DebugUpdateTime = DateTime.Now;

潘栩锋's avatar
潘栩锋 committed
194

潘栩锋's avatar
潘栩锋 committed
195
        }
196
        public void GetDebugData(AsyncCBHandler asyncDelegate, object asyncContext)
潘栩锋's avatar
潘栩锋 committed
197
        {
198
            asyncDelegate?.Invoke(asyncContext, rejectDebug);
潘栩锋's avatar
潘栩锋 committed
199 200
        }

潘栩锋's avatar
潘栩锋 committed
201
        #region INotifyPropertyChanged 成员
202

潘栩锋's avatar
潘栩锋 committed
203 204 205 206
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

207 208 209 210 211 212 213 214 215 216
    }

    public class RejectJsonDb
    {
        static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
        {
            c.CreateMap<Reject, RejectJsonDb>().ReverseMap();
        }));

        public static bool Save(string file_path, Reject src)
潘栩锋's avatar
潘栩锋 committed
217
        {
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
            try
            {
                var p = Mapper.Map<RejectJsonDb>(src);
                File.WriteAllText(file_path, JsonConvert.SerializeObject(p, Formatting.Indented));
                return true;
            }
            catch
            {
                //异常,没有json 编码失败

            }
            return false;
        }
        public static bool Load(string file_path, Reject src)
        {
            try
            {
                if (File.Exists(file_path))
                {
                    string json = File.ReadAllText(file_path);
                    var p = JsonConvert.DeserializeObject<RejectJsonDb>(json);
                    Mapper.Map(p, src);
                }
            }
            catch
            {
                //异常,没有json 解码失败

            }
            return false;
潘栩锋's avatar
潘栩锋 committed
248
        }
249 250 251 252 253



        public bool Enable { get; set; }

254
        public double LimitRangeRatio { get; set; }
255

256
        public double ThresholdRatio { get; set; }
257

258
        public int SmoothRange { get; set; }
259

260
        public int RejectRange { get; set; }
261

潘栩锋's avatar
潘栩锋 committed
262 263
    }
}