Bladeren bron

线段筛选算法部分调整

ZIM 1 jaar geleden
bovenliggende
commit
bdcaf7c9e0

+ 25 - 11
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/ScreenIdentification.cs

@@ -684,7 +684,7 @@ namespace o0.Project
                 var locateTex = ToLocateTex(PixelsMultipleBatches[batch]);
                 LocateTexTemp.Add(locateTex);
                 var ScreenLocateMat = locateTex.Too0Mat();        // 用于获取Lines的Matrix
-                var lineCount = ZIMIdentifyQuadLSD(ref allLines, batch, ScreenLocateMat.zimIdentifyEdgeGradientAny(conSize));
+                var lineCount = ZIMIdentifyQuadLSD(ref allLines, batch, ScreenLocateMat.zimIdentifyEdgeGradientAny(conSize), minLength);
                 log += $"\r\n识别图片{batch}, 识别到的线段数量为: {lineCount}";
                 ScreenLocateMatList.Add(ScreenLocateMat);
             }
@@ -773,7 +773,7 @@ namespace o0.Project
             if (ScreenLocate.Main.SaveToggle.isOn && ScreenLocate.Main.DebugOnZIMDemo)
             {
                 var FileDirectory = $"Debug_屏幕定位/";
-                SaveImages(FileDirectory, log, ScreenLocateTexture, allLinesTex, ScreenQuadTex);
+                SaveImages(FileDirectory, log, ScreenLocateTexture, allLinesTex, ChoosableLineTex, ScreenQuadTex);
             }
 
             //times.Add(watch.ElapsedMilliseconds);
@@ -867,7 +867,7 @@ namespace o0.Project
                     lg.Add(screenLocateMatList[line.Batch][(int)ga.x, (int)ga.y] - screenLocateMatList[line.Batch][(int)gb.x, (int)gb.y]);
                 }
 
-                float e = (float)Math.Sqrt(Math.Max(1, line.Line.Length / minLength / 3));       // 长度系数,筛选时梯度更大、长度更长的线段更优
+                float e = (float)Math.Pow(Math.Ceiling(line.Line.Length / minLength), 0.2f);       // 长度系数,筛选时梯度更大、长度更长的线段更优
                 float d = (3 - distanceRatio) / 2;            // 距离系数,距离越近,系数越大
                 return e * d * Math.Abs(lg.Mean());
             }
@@ -886,7 +886,7 @@ namespace o0.Project
                 var calibration = ScreenLocate.Main.ReDoLocateCalibrationRatio * Size.y;
                 oldLines = screen.QuadInCamera.GetLines();
 
-                var pedals = oldLines.Select((i) => o0Extension.PointPedal(i, avgPoint)).ToArray();     // 当前定位的垂足,下、右、上、左
+                var pedals = oldLines.Select((i) => o0Extension.PointPedal(i, avgPoint, out _)).ToArray();     // 当前定位的垂足,下、右、上、左
 
                 foreach (var i in allLines)
                 {
@@ -894,7 +894,7 @@ namespace o0.Project
                     int index = -1;
                     foreach (var j in pedals.Index())
                     {
-                        var d = (o0Extension.PointPedal(i.Line, avgPoint) - pedals[j]).Length;
+                        var d = (o0Extension.PointPedal(i.Line, avgPoint, out _) - pedals[j]).Length;
                         if (d < minDistance)
                         {
                             minDistance = d;
@@ -904,8 +904,13 @@ namespace o0.Project
                     //Debug.Log(minDistance +", -----------"+ calibration);
                     if (minDistance < calibration)      // 垂足的距离足够近
                     {
-                        quadLines[index].Add((estimateGradient(i, minDistance / calibration), i.Line));
-                        possibleLines.Add(i.Line);
+                        // 另外满足,新的线段的中点,到旧线段的垂足,要在旧线段内
+                        var middleToOldLine = o0Extension.PointPedal(oldLines[index], (i.Line.A + i.Line.B) / 2, out bool inLineSegment);
+                        if (inLineSegment)
+                        {
+                            quadLines[index].Add((estimateGradient(i, minDistance / calibration), i.Line));
+                            possibleLines.Add(i.Line);
+                        }
                     }
                 }
             }
@@ -969,7 +974,7 @@ namespace o0.Project
             return result.ToList();
         }
 
-        void SaveImages(string FileDirectory, string log, Texture2D ScreenLocateTex, Texture2D allLinesTex, Texture2D ScreenQuadTex)
+        void SaveImages(string FileDirectory, string log, Texture2D ScreenLocateTex, Texture2D allLinesTex, Texture2D ChoosableLineTex, Texture2D ScreenQuadTex)
         {
             if (!Directory.Exists(FileDirectory))
                 Directory.CreateDirectory(FileDirectory);
@@ -984,12 +989,21 @@ namespace o0.Project
             var pngData2 = allLinesTex.EncodeToPNG();
             if (pngData2 != null)
                 File.WriteAllBytes($"{FileDirectory}{time}C全部识别线段.png", pngData2);
-            var pngData3 = ScreenQuadTex.EncodeToPNG();
+            var pngData3 = ChoosableLineTex.EncodeToPNG();
             if (pngData3 != null)
-                File.WriteAllBytes($"{FileDirectory}{time}D识别结果.png", pngData3);
+                File.WriteAllBytes($"{FileDirectory}{time}D备选线段.png", pngData3);
+            var pngData4 = ScreenQuadTex.EncodeToPNG();
+            if (pngData4 != null)
+                File.WriteAllBytes($"{FileDirectory}{time}E识别结果.png", pngData4);
+
 
             Debug.Log($"<color=aqua>({time}) 屏幕识别图片保存至:程序根目录/{FileDirectory}</color>");
-            log += $"\r\n屏幕原图保存{pngData != null}, \r\n黑白色差保存{pngData1 != null}, \r\n全部识别线段保存{pngData2 != null}, \r\n识别结果保存{pngData3 != null}, ";
+            log += 
+                $"\r\n屏幕原图保存{pngData != null}, " +
+                $"\r\n黑白色差保存{pngData1 != null}, " +
+                $"\r\n全部识别线段保存{pngData2 != null}, " +
+                $"\r\n备选线段保存{pngData3 != null}, " +
+                $"\r\n识别结果保存{pngData4 != null}, ";
             File.WriteAllText($"{FileDirectory}{time}屏幕自动定位_日志.log", log);
         }
 

+ 1 - 1
Assets/InfraredProject/WebCamera/Script/ZIM/ScreenLocate.cs

@@ -118,7 +118,7 @@ public partial class ScreenLocate : MonoBehaviour
     //是否单点显示
     public bool bSinglePoint = true;//默认单点识别
 
-    [NonSerialized] public float ReDoLocateCalibrationRatio = 0.04f;  // 重复定位时校准的距离比例,例如先手动定位,再自动定位,会以手动的结果来校准
+    [NonSerialized] public float ReDoLocateCalibrationRatio = 0.08f;  // 重复定位时校准的距离比例,例如先手动定位,再自动定位,会以手动的结果来校准
 
     [NonSerialized] public InfraredCount infraredCount = InfraredCount.Single;
 

+ 5 - 3
Assets/InfraredProject/WebCamera/Script/ZIM/o0Extension/o0Extension.cs

@@ -82,15 +82,17 @@ namespace o0.Project
                     _draw(x, y);
         }
 
-        /// <summary>计算点到直线的垂足,垂足坐标可能在Line的延长线上</summary>
-        public static Vector PointPedal(Line l, in Vector v)
+        /// <summary>计算点到直线的垂足,垂足坐标可能在Line的延长线上,可通过inLineSegment判断垂足是否在线段上</summary>
+        public static Vector PointPedal(Line l, in Vector v, out bool inLineSegment)
         {
             Vector d = l.B - l.A;
             float dotD = d.Dot(d);
             if (dotD == 0)
                 throw new DivideByZeroException();
             float dotL = (v - l.A).Dot(d);
-            Vector proj = d * (dotL / dotD);
+            var factor = dotL / dotD;
+            Vector proj = d * factor;
+            inLineSegment = factor >= 0 && factor <= 1;
             return l.A + proj;
         }
 

+ 0 - 114
Assets/InfraredProject/WebCamera/zimWebCamera.unity

@@ -1661,43 +1661,6 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 641569779}
   m_CullTransparentMesh: 1
---- !u!1 &670543264
-GameObject:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  serializedVersion: 6
-  m_Component:
-  - component: {fileID: 670543265}
-  m_Layer: 5
-  m_Name: CameraMask
-  m_TagString: Untagged
-  m_Icon: {fileID: 0}
-  m_NavMeshLayer: 0
-  m_StaticEditorFlags: 0
-  m_IsActive: 1
---- !u!224 &670543265
-RectTransform:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 670543264}
-  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
-  m_LocalPosition: {x: 0, y: 0, z: 0}
-  m_LocalScale: {x: 1, y: 1, z: 1}
-  m_ConstrainProportionsScale: 0
-  m_Children:
-  - {fileID: 1594629634}
-  m_Father: {fileID: 922494663}
-  m_RootOrder: 4
-  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 1, y: 1}
-  m_AnchoredPosition: {x: 0, y: 0}
-  m_SizeDelta: {x: 0, y: 0}
-  m_Pivot: {x: 0.5, y: 0.5}
 --- !u!1 &681002956
 GameObject:
   m_ObjectHideFlags: 0
@@ -2218,7 +2181,6 @@ RectTransform:
   - {fileID: 382975161}
   - {fileID: 1092870242}
   - {fileID: 1728164016}
-  - {fileID: 670543265}
   m_Father: {fileID: 1867793102}
   m_RootOrder: 15
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -3756,82 +3718,6 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1588263170}
   m_CullTransparentMesh: 1
---- !u!1 &1594629633
-GameObject:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  serializedVersion: 6
-  m_Component:
-  - component: {fileID: 1594629634}
-  - component: {fileID: 1594629636}
-  - component: {fileID: 1594629635}
-  m_Layer: 5
-  m_Name: PixelCheaker
-  m_TagString: Untagged
-  m_Icon: {fileID: 0}
-  m_NavMeshLayer: 0
-  m_StaticEditorFlags: 0
-  m_IsActive: 1
---- !u!224 &1594629634
-RectTransform:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 1594629633}
-  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
-  m_LocalPosition: {x: 0, y: 0, z: 0}
-  m_LocalScale: {x: 1, y: 1, z: 1}
-  m_ConstrainProportionsScale: 0
-  m_Children: []
-  m_Father: {fileID: 670543265}
-  m_RootOrder: 0
-  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0, y: 0}
-  m_AnchorMax: {x: 1, y: 1}
-  m_AnchoredPosition: {x: 0, y: 0}
-  m_SizeDelta: {x: 0, y: 0}
-  m_Pivot: {x: 0.5, y: 0.5}
---- !u!114 &1594629635
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 1594629633}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
-  m_Material: {fileID: 0}
-  m_Color: {r: 1, g: 1, b: 1, a: 1}
-  m_RaycastTarget: 0
-  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
-  m_Maskable: 1
-  m_OnCullStateChanged:
-    m_PersistentCalls:
-      m_Calls: []
-  m_Sprite: {fileID: 21300000, guid: f3b60078f3450d1459d9642ca6404c7d, type: 3}
-  m_Type: 0
-  m_PreserveAspect: 0
-  m_FillCenter: 1
-  m_FillMethod: 0
-  m_FillAmount: 1
-  m_FillClockwise: 1
-  m_FillOrigin: 0
-  m_UseSpriteMesh: 0
-  m_PixelsPerUnitMultiplier: 1
---- !u!222 &1594629636
-CanvasRenderer:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 1594629633}
-  m_CullTransparentMesh: 1
 --- !u!1 &1650142577
 GameObject:
   m_ObjectHideFlags: 0

+ 2 - 2
Assets/InfraredProject/o0/zimIdentifyLineLSD.cs

@@ -159,7 +159,7 @@ namespace o0.Project
                 var calibration = ScreenLocate.Main.ReDoLocateCalibrationRatio * screenLocateMat.Size.y;
                 oldLines = screen.QuadInCamera.GetLines();
 
-                var pedals = oldLines.Select((i) => o0Extension.PointPedal(i, avgPoint)).ToArray();     // 当前定位的垂足,下、右、上、左
+                var pedals = oldLines.Select((i) => o0Extension.PointPedal(i, avgPoint, out _)).ToArray();     // 当前定位的垂足,下、右、上、左
 
                 foreach (var i in allLines)
                 {
@@ -167,7 +167,7 @@ namespace o0.Project
                     int index = -1;
                     foreach (var j in pedals.Index())
                     {
-                        var d = (o0Extension.PointPedal(i.Item1, avgPoint) - pedals[j]).Length;
+                        var d = (o0Extension.PointPedal(i.Item1, avgPoint, out _) - pedals[j]).Length;
                         if (d < minDistance)
                         {
                             minDistance = d;