| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 | 
							- using o0;
 
- using o0.Num;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Linq;
 
- using System.Threading.Tasks;
 
- using UnityEngine;
 
- using ZIM.Unity;
 
- using Color = UnityEngine.Color;
 
- namespace ZIM
 
- {
 
-     // 亮区的点用来定位(计算center),泛光区域的点用来计算radius
 
-     public class PixelSpotArea
 
-     {
 
-         //public static float gridRatio0 = 6f / 1280;
 
-         //public static float gridRatio1 = 20f / 720;
 
-         public static int gridLength0 = 2;      // 亮区
 
-         public static int gridLength1 = 10;     // 边缘泛光
 
-         public static (int x, int y) GetGrid0(Vector2 v)
 
-         {
 
-             var m = (int)(v.x / gridLength0);
 
-             var n = (int)(v.y / gridLength0);
 
-             return (m, n);
 
-         }
 
-         public static (int x, int y) GetGrid1(Vector2 v)
 
-         {
 
-             var m = (int)(v.x / gridLength1);
 
-             var n = (int)(v.y / gridLength1);
 
-             return (m, n);
 
-         }
 
-         // 亮点聚类到区域
 
-         public static List<PixelSpotArea> Cluster(List<Vector2> spotPoint, List<Vector2> brightPoint, Func<Vector2, bool> PointFilter = null)
 
-         {
 
-             var spotArea = new List<PixelSpotArea>();
 
-             for (int i = 0; i < spotPoint.Count; i++)
 
-             {
 
-                 var p = spotPoint[i];
 
-                 if (PointFilter != null && !PointFilter(p))        // 筛选是否在屏幕内
 
-                     continue;
 
-                 var grid = PixelSpotArea.GetGrid0(p);
 
-                 var join = new SortedList<int, PixelSpotArea>();
 
-                 for (int j = 0; j < spotArea.Count; j++)
 
-                 {
 
-                     var area = spotArea[j];
 
-                     if (area.Include0(grid))
 
-                         join.Add(j, area);
 
-                 }
 
-                 if (join.Count == 0)
 
-                     spotArea.Add(new PixelSpotArea(p, grid, PixelSpotArea.GetGrid1(p)));
 
-                 else if (join.Count == 1)
 
-                     join.First().Value.Join(p, grid, PixelSpotArea.GetGrid1(p));
 
-                 else
 
-                 {
 
-                     var combine = new PixelSpotArea(join.Values);
 
-                     combine.Join(p, grid, PixelSpotArea.GetGrid1(p));
 
-                     spotArea.Add(combine);
 
-                     for (int j = join.Count - 1; j >= 0; j--)
 
-                         spotArea.RemoveAt(join.ElementAt(j).Key);
 
-                 }
 
-             }
 
-             if (spotArea.Count != 0)
 
-             {
 
-                 // brightPoint合并到区域中
 
-                 for (int i = 0; i < brightPoint.Count; i++)
 
-                 {
 
-                     var p = brightPoint[i];
 
-                     var grid = PixelSpotArea.GetGrid1(p);
 
-                     for (int j = 0; j < spotArea.Count; j++)
 
-                     {
 
-                         var area = spotArea[j];
 
-                         if (area.Include1(grid))
 
-                             area.Add(p);
 
-                     }
 
-                 }
 
-             }
 
-             return spotArea;
 
-         }
 
-         Vector2 centroid = default;       // 该项目里center不可能等于0,0
 
-         public Vector2 Centroid
 
-         {
 
-             get
 
-             {
 
-                 if (centroid != default)
 
-                     return centroid;
 
-                 foreach (var p in Pixels0)
 
-                 {
 
-                     centroid += p;
 
-                 }
 
-                 return centroid /= Pixels0.Count;
 
-             }
 
-         }
 
-         float radius = 0;
 
-         public float Radius
 
-         {
 
-             set
 
-             {
 
-                 radius = value;
 
-             }
 
-             get
 
-             {
 
-                 if (radius != 0)
 
-                     return radius;
 
-                 //var radiusDic = new Dictionary<int, float>() { { 0, 0 }, { 45, 0 }, { 90, 0 }, { 135, 0 }, { 180, 0 }, { 225, 0 }, { 270, 0 }, { 315, 0 } };
 
-                 var radiusDic = new float[8];
 
-                 foreach (var p in Pixels0)
 
-                 {
 
-                     var dir = p - Centroid;
 
-                     var radius = dir.magnitude;
 
-                     var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
 
-                     if (degreeI > 7) degreeI = 0;       // 防止正好360度
 
-                     if (radius > radiusDic[degreeI])
 
-                         radiusDic[degreeI] = radius;
 
-                 }
 
-                 foreach (var p in Pixels1)
 
-                 {
 
-                     var dir = p - Centroid;
 
-                     var radius = dir.magnitude;
 
-                     var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
 
-                     if (degreeI > 7) degreeI = 0;
 
-                     if (radius > radiusDic[degreeI])
 
-                         radiusDic[degreeI] = radius;
 
-                 }
 
-                 return radius = radiusDic.Mean();
 
-             }
 
-         }
 
-         public List<Vector2> Pixels0;
 
-         public List<Vector2> Pixels1;
 
-         HashSet<(int, int)> grids0;
 
-         HashSet<(int, int)> grids1;
 
-         public PixelSpotArea(Vector2 location, (int, int) grid0, (int, int) grid1)
 
-         {
 
-             Pixels0 = new List<Vector2>(1000);       // 预估的初始容量
 
-             Pixels1 = new List<Vector2>(5000);
 
-             this.grids0 = new HashSet<(int, int)>();        // hashset如果设置了太大的容量会降低效率
 
-             this.grids1 = new HashSet<(int, int)>();
 
-             Join(location, grid0, grid1);
 
-         }
 
-         public PixelSpotArea(IList<PixelSpotArea> areas)
 
-         {
 
-             Pixels0 = new List<Vector2>(1000);
 
-             Pixels1 = new List<Vector2>(5000);
 
-             grids0 = new HashSet<(int, int)>();
 
-             grids1 = new HashSet<(int, int)>();
 
-             foreach (var a in areas)
 
-             {
 
-                 Pixels0.AddRange(a.Pixels0);
 
-                 grids0.AddRange(a.grids0);
 
-                 grids1.AddRange(a.grids1);
 
-                 //Center += a.Center * a.SpotPointCount;
 
-                 //SpotPointCount += a.SpotPointCount;
 
-             }
 
-             //Center /= SpotPointCount;
 
-         }
 
-         public bool Include0((int, int) grid) => grids0.Contains(grid);
 
-         public bool Include1((int, int) grid) => grids1.Contains(grid);
 
-         public void Join(Vector2 point) => Join(point, GetGrid0(point), GetGrid1(point));
 
-         public void Join(Vector2 point, (int x, int y) grid0, (int x, int y) grid1)
 
-         {
 
-             Pixels0.Add(point);
 
-             //SpotPointCount++;
 
-             //Center += (point - Center) / SpotPointCount;
 
-             grids0.AddRange(new (int, int)[]
 
-             {
 
-                     (grid0.x + -1, grid0.y +  0) , (grid0.x + 1 , grid0.y + 0),
 
-                     (grid0.x + 1,  grid0.y + -1) , (grid0.x + -1, grid0.y + 1),
 
-                     (grid0.x + 0,  grid0.y + -1) , (grid0.x + 0 , grid0.y + 1),
 
-                     (grid0.x + -1, grid0.y + -1) , (grid0.x + 1 , grid0.y + 1),
 
-                     grid0
 
-             });
 
-             grids1.AddRange(new (int, int)[]
 
-             {
 
-                     (grid1.x + -1, grid1.y +  0) , (grid1.x + 1 , grid1.y + 0),
 
-                     (grid1.x + 1,  grid1.y + -1) , (grid1.x + -1, grid1.y + 1),
 
-                     (grid1.x + 0,  grid1.y + -1) , (grid1.x + 0 , grid1.y + 1),
 
-                     (grid1.x + -1, grid1.y + -1) , (grid1.x + 1 , grid1.y + 1),
 
-                     grid1
 
-             });
 
-         }
 
-         // 不再join之后,才可以用add添加周围泛光
 
-         public void Add(Vector2 point)
 
-         {
 
-             //var radius = (point - Center).LengthManhattan();
 
-             //if (radius > MaxRadius)
 
-             //    MaxRadius = radius;
 
-             Pixels1.Add(point);
 
-             //var radius = (point - Center).LengthManhattan();
 
-             //if (radius > MaxRadius)
 
-             //    MaxRadius = radius;
 
-         }
 
-         public float TotalBrightness(Color[] pixels, Func<int, int, int> Vector2ToIndex, int outer_size = 3)
 
-         {
 
-             (int x, int y) rectMin = ((int)(Centroid.x - Radius - outer_size), (int)(Centroid.y - Radius - outer_size));
 
-             (int x, int y) rectMax = ((int)(Centroid.x + Radius + outer_size), (int)(Centroid.y + Radius + outer_size));
 
-             var total = 0f;
 
-             Parallel.For(rectMin.x, rectMax.x, (i) =>
 
-             {
 
-                 var t = 0;
 
-                 for (int j = rectMin.y; j < rectMax.y; j++)
 
-                 {
 
-                     var index = Vector2ToIndex(i, j);
 
-                     var b = pixels[index].Brightness(64);
 
-                     t += b;
 
-                 }
 
-                 lock (InfraredLocate.locker)
 
-                 {
 
-                     total += t;
 
-                 }
 
-             });
 
-             //total /= (rectMax.y - rectMin.y) * (rectMax.x - rectMin.x);
 
-             return total;
 
-         }
 
-     }
 
- }
 
 
  |