ZIM пре 1 година
родитељ
комит
d0d7b04bef

+ 1 - 1
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/Dbscan/DbscanPoint.cs

@@ -7,7 +7,7 @@ namespace DbscanImplementation
     /// Algorithm point definition
     /// </summary>
     /// <typeparam name="TF">Feature data contribute into algorithm</typeparam>
-    public class DbscanPoint<TF> : IPixel<TF>
+    public class DbscanPoint<TF>
     {
         public TF Feature { get; internal set; }
 

+ 42 - 44
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredLocate.cs

@@ -14,14 +14,6 @@ using Debug = UnityEngine.Debug;
 
 namespace ZIM
 {
-    //class DescendingComparer<T> : IComparer<T>
-    //{
-    //    public int Compare(T x, T y)
-    //    {
-    //        return Comparer<T>.Default.Compare(y, x);
-    //    }
-    //}
-
     public enum InfraredMatch
     {
         Nomatch = 0,
@@ -112,7 +104,7 @@ namespace ZIM
         }
 
         // New, 返回由大到小排序的点
-        public List<PixelSpotArea> LocateToScreen(Color[] pixels, Rect rect)
+        public List<ISpotArea> LocateToScreen(Color[] pixels, Rect rect)
         {
             if (!screenIdentification.Screen.Active)
                 rect = new Rect(0, 0, screenIdentification.Size.x, screenIdentification.Size.y);
@@ -172,12 +164,12 @@ namespace ZIM
             //    if (spotPoint.Count > 400)     // 如果亮点太多,控制亮点数量在200左右
             //    {
             //        samplingScale = (int)Math.Ceiling(samplingScale * Math.Sqrt(spotPoint.Count / 400.0));
-            //        return new List<PixelSpotArea>();
+            //        return new List<ISpotArea>();
             //    }
             //    else if (samplingScale > 1 && spotPoint.Count < 100)
             //    {
             //        samplingScale = Math.Max((int)Math.Ceiling(samplingScale * Math.Sqrt(spotPoint.Count / 200.0)), 1);
-            //        return new List<PixelSpotArea>();
+            //        return new List<ISpotArea>();
             //    }
             //}
 
@@ -230,29 +222,30 @@ namespace ZIM
                 return spotArea;
 
                 //半径再按透视修正一遍,降低一点常规角度下反射的影响
-                foreach (var i in spotArea)
-                {
-                    var r0 = i.Radius / 2 / mCameraInfo.CurrentWidth;
-                    var center = i.Centroid;
-                    var offset1 = center + new Vector2(i.Radius / 2, 0);
-                    var offset2 = center - new Vector2(i.Radius / 2, 0);
-                    var offset3 = center + new Vector2(0, i.Radius / 2);
-                    var offset4 = center - new Vector2(0, i.Radius / 2);
-                    var transR = ((screenIdentification.Screen.TransformToScreen(offset1) - screenIdentification.Screen.TransformToScreen(offset2)).magnitude +
-                        (screenIdentification.Screen.TransformToScreen(offset3) - screenIdentification.Screen.TransformToScreen(offset4)).magnitude) / 4;
-                    var r1 = transR / screenIdentification.Screen.UVSize.x;
-                    //Debug.Log(r1 / r0);
-                    i.Radius *= (float)Math.Pow(r1 / r0, 2);      // 摄像机位置不同参数也可能不同
-                }
+                //foreach (var i in spotArea)
+                //{
+                //    var r0 = i.Radius / 2 / mCameraInfo.CurrentWidth;
+                //    var center = i.Centroid;
+                //    var offset1 = center + new Vector2(i.Radius / 2, 0);
+                //    var offset2 = center - new Vector2(i.Radius / 2, 0);
+                //    var offset3 = center + new Vector2(0, i.Radius / 2);
+                //    var offset4 = center - new Vector2(0, i.Radius / 2);
+                //    var transR = ((screenIdentification.Screen.TransformToScreen(offset1) - screenIdentification.Screen.TransformToScreen(offset2)).magnitude +
+                //        (screenIdentification.Screen.TransformToScreen(offset3) - screenIdentification.Screen.TransformToScreen(offset4)).magnitude) / 4;
+                //    var r1 = transR / screenIdentification.Screen.UVSize.x;
+                //    //Debug.Log(r1 / r0);
+                //    i.Radius *= (float)Math.Pow(r1 / r0, 2);      // 摄像机位置不同参数也可能不同
+                //}
 
                 //if (spotArea.Count == 1)
                 //Debug.Log($"{spotArea[0].MaxRadius}");
 
-                return spotArea;
+                //return spotArea;
+
 
                 //// 排序亮区
                 //spotArea.Sort((a, b) => b.MaxRadius.CompareTo(a.MaxRadius));
-                ////var areas = new SortedList<float, PixelSpotArea>(new DescendingComparer<float>());
+                ////var areas = new SortedList<float, ISpotArea>(new DescendingComparer<float>());
                 ////foreach (var i in spotArea)
                 ////    areas.Add(i.MaxRadius, i);
 
@@ -266,14 +259,16 @@ namespace ZIM
                 //return result;
             }
 
-            return new List<PixelSpotArea>();
+            return new List<ISpotArea>();
         }
 
-        private void DebugAreas(List<PixelSpotArea> areas)
+        private void DebugAreas(List<ISpotArea> areas)
         {
-            ScreenLocate.Main.Info.transform.GetChild(0).GetComponent<Text>().text = $"areas.Count: {areas.Count}";
-            PixelSpotArea a0 = null;  // 表示最大半径的区域
-            PixelSpotArea a1 = null;  // 表示第二大半径的区域
+            var debugText = $"当前相机分辨率: {ScreenLocate.Main.CameraSize}";
+            debugText += $"\r\nareas.Count: {areas.Count}";
+
+            ISpotArea a0 = null;  // 表示最大半径的区域
+            ISpotArea a1 = null;  // 表示第二大半径的区域
 
             foreach (var a in areas)
             {
@@ -300,6 +295,7 @@ namespace ZIM
                     texture.SetPixel((int)p.x, (int)p.y, Color.yellow);
                 foreach (var p in a0.Pixels1)
                     texture.SetPixel((int)p.x, (int)p.y, Color.white);
+                debugText += $"\r\n最大的区域半径: {a0.Radius}";
             }
             if (a1 != null)
             {
@@ -307,19 +303,21 @@ namespace ZIM
                     texture.SetPixel((int)p.x, (int)p.y, Color.green);
                 foreach (var p in a1.Pixels1)
                     texture.SetPixel((int)p.x, (int)p.y, Color.blue);
+                debugText += $"\r\n第二大的区域半径: {a1.Radius}";
             }
 
             texture.Apply();
             ScreenLocate.DebugTexture(6, texture);
+            ScreenLocate.Main.Info.transform.GetChild(0).GetComponent<Text>().text = debugText;
         }
 
-        private List<PixelSpotArea_DbScan> DbscanToSpotAreas(DbscanResult<Vector2> db, List<Vector2> brightPoint)
+        private List<ISpotArea> DbscanToSpotAreas(DbscanResult<Vector2> db, List<Vector2> brightPoint)
         {
             if (db.Clusters.Count == 0)
-                return new List<PixelSpotArea_DbScan>();
+                return new List<ISpotArea>();
 
             // 用dbscan的结果创建SpotArea,先用高亮区算一遍半径
-            var clusters = new List<PixelSpotArea_DbScan>();
+            var clusters = new List<ISpotArea>();
             var areaIncludeRadius = new List<(Vector2, float)>();
             foreach (var i in db.Clusters.Values)
             {
@@ -335,11 +333,11 @@ namespace ZIM
             {
                 var index = FindNearestAreaIndex(i, areaIncludeRadius);
                 if (index < clusters.Count)
-                    clusters[index].Add1(i);
+                    clusters[index].Pixels1.Add(i);
             }
             // 添加了泛光点后,重新计算半径
             foreach (var i in clusters)
-                i.Radius = i.CalculateRadius();
+                i.CalculateRadius();
 
             return clusters;
         }
@@ -364,9 +362,9 @@ namespace ZIM
             return nearestIndex;
         }
 
-        InfraredSpot[] MatchInfraredRaySingle(List<PixelSpotArea> spotArea)
+        InfraredSpot[] MatchInfraredRaySingle(List<ISpotArea> spotArea)
         {
-            var matchedArea = new Dictionary<InfraredMatch, PixelSpotArea>() { { InfraredMatch.Match0, null } };
+            var matchedArea = new Dictionary<InfraredMatch, ISpotArea>() { { InfraredMatch.Match0, null } };
             var v0 = InfraredSpots[0].Verify(spotArea, matchedArea);
 
             if (v0)
@@ -396,9 +394,9 @@ namespace ZIM
             return InfraredSpots;
         }
 
-        InfraredSpot[] MatchInfraredRay(List<PixelSpotArea> spotArea)
+        InfraredSpot[] MatchInfraredRay(List<ISpotArea> spotArea)
         {
-            var matchedArea = new Dictionary<InfraredMatch, PixelSpotArea>() { { InfraredMatch.Match0, null }, { InfraredMatch.Match1, null } };
+            var matchedArea = new Dictionary<InfraredMatch, ISpotArea>() { { InfraredMatch.Match0, null }, { InfraredMatch.Match1, null } };
             var v0 = InfraredSpots[0].Verify(spotArea, matchedArea);
             var v1 = InfraredSpots[1].Verify(spotArea, matchedArea);
 
@@ -446,8 +444,8 @@ namespace ZIM
                 }
                 else
                 {
-                    PixelSpotArea select = null;
-                    PixelSpotArea selectOther = null;
+                    ISpotArea select = null;
+                    ISpotArea selectOther = null;
                     InfraredMatch oneFailed = InfraredMatch.Nomatch;
                     if (!v0)
                     {
@@ -538,7 +536,7 @@ namespace ZIM
                 if (v0)
                 {
                     var overlapAera = matchedArea[InfraredMatch.Match0];
-                    (PixelSpotArea, float) split = (null, float.MaxValue);
+                    (ISpotArea, float) split = (null, float.MaxValue);
                     foreach (var i in spotArea)
                     {
                         if (i != overlapAera)

+ 12 - 0
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredSpot/ISpotArea.cs

@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public interface ISpotArea
+{
+    float Radius { get; }
+    public List<Vector2> Pixels0 { get; }
+    public List<Vector2> Pixels1 { get; }
+    Vector2 Centroid { get; }
+
+    float CalculateRadius();
+}

+ 11 - 0
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredSpot/ISpotArea.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a63edb7c871183942bfeb85252618371
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 5
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredSpot/InfraredSpot.cs

@@ -54,7 +54,7 @@ namespace ZIM
         //PixelSpotArea verifyArea;
         int verifyFailLimit;
 
-        List<PixelSpotArea> spots;
+        List<ISpotArea> spots;
         SimpleLocationEstimation estimation;
         Vector2? ScreenLocation;
         ScreenMap screenMap;
@@ -63,7 +63,7 @@ namespace ZIM
         {
             this.screenMap = screenMap;
             Match = match;
-            spots = new List<PixelSpotArea>();
+            spots = new List<ISpotArea>();
             Reset();
         }
 
@@ -78,12 +78,12 @@ namespace ZIM
             verifyFailLimit = MaxVerifyFailLimit;
         }
 
-        public bool Verify(List<PixelSpotArea> areas, Dictionary<InfraredMatch, PixelSpotArea> matchedArea)
+        public bool Verify(List<ISpotArea> areas, Dictionary<InfraredMatch, ISpotArea> matchedArea)
         {
             if (Predict == null)    // 未初始化
                 return false;
 
-            PixelSpotArea select = null;
+            ISpotArea select = null;
             var minLength = float.MaxValue;
             var predict = Predict.Value;
             var refPoint = (predict + spots.Last().Centroid) / 2;       // 用预测点和最后一个点的中点来判断是否追踪到
@@ -120,7 +120,7 @@ namespace ZIM
         //}
 
         // 为null时采用预测点
-        public void Update(PixelSpotArea area)
+        public void Update(ISpotArea area)
         {
             if (area == null)
             {

+ 36 - 37
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredSpot/PixelSpotArea.cs

@@ -11,7 +11,7 @@ using Color = UnityEngine.Color;
 namespace ZIM
 {
     // 亮区的点用来定位(计算center),泛光区域的点用来计算radius
-    public class PixelSpotArea
+    public class PixelSpotArea: ISpotArea
     {
         //public static float gridRatio0 = 6f / 1280;
         //public static float gridRatio1 = 20f / 720;
@@ -34,7 +34,7 @@ namespace ZIM
         }
 
         // 亮点聚类到区域
-        public static List<PixelSpotArea> Cluster(List<Vector2> spotPoint, List<Vector2> brightPoint, Func<Vector2, bool> PointFilter = null)
+        public static List<ISpotArea> 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++)
@@ -76,12 +76,12 @@ namespace ZIM
                     {
                         var area = spotArea[j];
                         if (area.Include1(grid))
-                            area.Add(p);
+                            area.Pixels1.Add(p);
                     }
                 }
             }
 
-            return spotArea;
+            return spotArea.Select(i => i as ISpotArea).ToList();
         }
 
         Vector2 centroid = default;       // 该项目里center不可能等于0,0
@@ -111,35 +111,40 @@ namespace ZIM
                 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度
+                return CalculateRadius();
+            }
+        }
 
-                    if (radius > radiusDic[degreeI])
-                        radiusDic[degreeI] = radius;
-                }
+        public float CalculateRadius()
+        {
+            //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度
 
-                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;
+            }
 
-                    if (radius > radiusDic[degreeI])
-                        radiusDic[degreeI] = radius;
-                }
-                return radius = radiusDic.Mean();
+            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;
+        public List<Vector2> Pixels0 { get; set; }
+        public List<Vector2> Pixels1 { get; set; }
 
         HashSet<(int, int)> grids0;
         HashSet<(int, int)> grids1;
@@ -198,16 +203,10 @@ namespace ZIM
         }
 
         // 不再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 void Add(Vector2 point)
+        //{
+        //    Pixels1.Add(point);
+        //}
 
         public float TotalBrightness(Color[] pixels, Func<int, int, int> Vector2ToIndex, int outer_size = 3)
         {

+ 23 - 18
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredSpot/PixelSpotArea_DbScan.cs

@@ -1,9 +1,11 @@
-using o0;
+using DbscanImplementation;
+using o0;
 using o0.Num;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
+using Unity.VisualScripting;
 using UnityEngine;
 using ZIM.Unity;
 using static ScreenLocate;
@@ -11,14 +13,8 @@ using Color = UnityEngine.Color;
 
 namespace ZIM
 {
-    public interface IPixel<T>
-    {
-        // 像素坐标点
-        T Point { get;}
-    }
-
     // 亮区的点用来定位(计算center),泛光区域的点用来计算radius
-    public class PixelSpotArea_DbScan
+    public class PixelSpotArea_DbScan : ISpotArea
     {
         // 中心
         Vector2 centroid = default;       // 该项目里center不可能等于0,0
@@ -30,7 +26,7 @@ namespace ZIM
                     return centroid;
 
                 foreach (var p in Pixels0)
-                    centroid += p.Point;
+                    centroid += p;
                 return centroid /= Pixels0.Count;
             }
         }
@@ -47,8 +43,8 @@ namespace ZIM
             {
                 if (radius != 0)
                     return radius;
-
-                return radius = CalculateRadius();
+                
+                return CalculateRadius();       // 函数里会赋值 radius
             }
         }
         public float CalculateRadius()
@@ -57,7 +53,7 @@ namespace ZIM
             var radiusDic = new float[8];
             foreach (var p in Pixels0)
             {
-                var dir = p.Point - Centroid;
+                var dir = p - Centroid;
                 var radius = dir.magnitude;
                 var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
                 if (degreeI > 7) degreeI = 0;       // 防止正好360度
@@ -76,21 +72,30 @@ namespace ZIM
                 if (radius > radiusDic[degreeI])
                     radiusDic[degreeI] = radius;
             }
-            return radiusDic.Mean();
+            return radius = radiusDic.Mean();
         }
 
         // 中心亮点
-        public List<IPixel<Vector2>> Pixels0 = new List<IPixel<Vector2>>();
+        public List<Vector2> Pixels0 { get; set; }
         // 泛光
-        public List<Vector2> Pixels1 = new List<Vector2>();
+        public List<Vector2> Pixels1 { get; set; }
+
+        public PixelSpotArea_DbScan(IEnumerable<Vector2> points)        // kmeans中用随机点初始化,作为中心
+        {
+            Pixels0 = new List<Vector2>();
+            Pixels1 = new List<Vector2>();
+            Pixels0.AddRange(points);
+        }
 
-        public PixelSpotArea_DbScan(IEnumerable<IPixel<Vector2>> p)        // kmeans中用随机点初始化,作为中心
+        public PixelSpotArea_DbScan(List<DbscanPoint<Vector2>> points)
         {
-            Pixels0.AddRange(p);
+            Pixels0 = new List<Vector2>();
+            Pixels1 = new List<Vector2>();
+            Pixels0.AddRange(points.Select((i) => i.Point));
         }
 
         // 中心亮点
-        public void Add0(IPixel<Vector2> p)
+        public void Add0(Vector2 p)
         {
             Pixels0.Add(p);
         }

+ 3 - 3
Assets/InfraredProject/WebCamera/zimWebCamera.unity

@@ -5504,8 +5504,8 @@ RectTransform:
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0, y: 0.5}
   m_AnchorMax: {x: 0, y: 0.5}
-  m_AnchoredPosition: {x: -214.62286, y: -1448.3071}
-  m_SizeDelta: {x: 286.5011, y: 416.2088}
+  m_AnchoredPosition: {x: -185.47559, y: -1448.3071}
+  m_SizeDelta: {x: 228.2065, y: 416.2088}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!114 &1821259943
 MonoBehaviour:
@@ -6444,7 +6444,7 @@ PrefabInstance:
       objectReference: {fileID: 0}
     - target: {fileID: 7518895720462305555, guid: 742f117969807f147b562a0be2d52864, type: 3}
       propertyPath: m_RootOrder
-      value: 22
+      value: 20
       objectReference: {fileID: 0}
     - target: {fileID: 7518895720462305555, guid: 742f117969807f147b562a0be2d52864, type: 3}
       propertyPath: m_AnchorMax.x