| 
					
				 | 
			
			
				@@ -1,13 +1,13 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define ENABLE_LOG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using o0.Geometry2D.Float; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using o0.Num; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using System.Collections; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Collections.Generic; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.IO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using System.Linq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Threading.Tasks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using UnityEngine; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using UnityStandardAssets.ImageEffects; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using ZIM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using ZIM.Unity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -90,11 +90,11 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 自动识别开始的入口 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public void LocateScreen(int Capture = 45, int Delay = 45)  //数值单位是frame 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (ScreenLocate.Main.DebugScreenImage != null && ScreenLocate.Main.DebugOnZIMDemo)     // 这段仅用于测试图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (ScreenLocate.Main.DebugScreenImages.Count != 0 && ScreenLocate.Main.DebugOnZIMDemo)     // 这段仅用于测试图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScreenLocate.Main.CameraSize = new Geometry2D.Vector<int>(ScreenLocate.Main.DebugScreenImage.width, ScreenLocate.Main.DebugScreenImage.height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                DebugImage(ScreenLocate.Main.DebugScreenImage); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Screen.QuadInCamera = new QuadrilateralInCamera(quadTemp[0], new Vector(ScreenLocate.Main.DebugScreenImage.width, ScreenLocate.Main.DebugScreenImage.height)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.Main.CameraSize = new Geometry2D.Vector<int>(ScreenLocate.Main.DebugScreenImages[0].width, ScreenLocate.Main.DebugScreenImages[0].height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                DebugImage(ScreenLocate.Main.DebugScreenImages); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Screen.QuadInCamera = new QuadrilateralInCamera(quadTemp[0], new Vector(ScreenLocate.Main.DebugScreenImages[0].width, ScreenLocate.Main.DebugScreenImages[0].height)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ScreenLocate.SetScreen(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ScreenLocate.Main.ShowScreen(ScreenLocate.Main.ScreenQuad, Screen.QuadInCamera); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 delay = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -105,6 +105,7 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 areaSelected = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 quadTemp.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 sumTemp.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.Main.DebugScreenImages.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -129,14 +130,9 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return capture != 0 && delay != 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        void DebugImage(Texture2D image) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        void DebugImage(List<Texture2D> images) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            QuadrilateralFit(out Texture2D LocateLightedRedTex,out Texture2D ChoosableLineTex, out Texture2D ScreenQuadTex, 5, image); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ScreenLocate.DebugTexture(2, LocateLightedRedTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ScreenLocate.DebugTexture(3, ScreenQuadTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 融合线段和原图 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ScreenLocate.DebugTexture(4, image.Merge(ScreenQuadTex)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ScreenLocate.DebugTexture(5, ChoosableLineTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            QuadrilateralFit(images, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //var watch = new System.Diagnostics.Stopwatch(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //watch.Start(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -147,32 +143,32 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (quadTemp.Count > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 var quad = quadTemp[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScreenLocate.Main.ShowScreen(ScreenLocate.Main.outputRawImages[4].transform.GetChild(0) as RectTransform,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    new QuadrilateralInCamera(quad, image.Size().o0Vector())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.Main.ShowScreen(ScreenLocate.Main.outputRawImages[4].transform.GetChild(0) as RectTransform, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    new QuadrilateralInCamera(quad, images[0].Size().o0Vector())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // 透视变换 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var srcWidth = LocateLightedRedTex.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var transformWidth = (int)((quad.B.x - quad.A.x + quad.D.x - quad.C.x) / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var transformHeight = (int)((quad.C.y - quad.A.y + quad.D.y - quad.B.y) / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var transformTex = new Texture2D(transformWidth, transformHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var pt = new ZIMPerspectiveTransform(new OrdinalQuadrilateral(new Vector(0, 0), new Vector(transformWidth, 0), new Vector(0, transformHeight), new Vector(transformWidth, transformHeight)), quad); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var dstPixel = new UnityEngine.Color[transformWidth * transformHeight]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var srcPixel = LocateLightedRedTex.GetPixels(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Parallel.For(0, transformWidth, (x) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    for (int y = 0; y < transformHeight; y++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        var index = y * transformWidth + x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        var sampleCoord = pt.TransformRound(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        dstPixel[index] = srcPixel[sampleCoord.y * srcWidth + sampleCoord.x]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                transformTex.SetPixels(dstPixel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                transformTex.Apply(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //ScreenLocate.DebugTexture(1, transformTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#if (!NDEBUG && DEBUG && ENABLE_LOG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Console.WriteLine($"{TAG} ScreenLocate.DebugTexture 1:{transformTex.GetNativeTexturePtr()}"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var srcWidth = LocateLightedRedTex.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var transformWidth = (int)((quad.B.x - quad.A.x + quad.D.x - quad.C.x) / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var transformHeight = (int)((quad.C.y - quad.A.y + quad.D.y - quad.B.y) / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var transformTex = new Texture2D(transformWidth, transformHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var pt = new ZIMPerspectiveTransform(new OrdinalQuadrilateral(new Vector(0, 0), new Vector(transformWidth, 0), new Vector(0, transformHeight), new Vector(transformWidth, transformHeight)), quad); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var dstPixel = new UnityEngine.Color[transformWidth * transformHeight]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                var srcPixel = LocateLightedRedTex.GetPixels(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                Parallel.For(0, transformWidth, (x) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                    for (int y = 0; y < transformHeight; y++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                        var index = y * transformWidth + x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                        var sampleCoord = pt.TransformRound(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                        dstPixel[index] = srcPixel[sampleCoord.y * srcWidth + sampleCoord.x]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                transformTex.SetPixels(dstPixel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                transformTex.Apply(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                //ScreenLocate.DebugTexture(1, transformTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//#if (!NDEBUG && DEBUG && ENABLE_LOG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                Console.WriteLine($"{TAG} ScreenLocate.DebugTexture 1:{transformTex.GetNativeTexturePtr()}"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //times.Add(watch.ElapsedMilliseconds); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -208,7 +204,7 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         void Reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           // bStartLocateScreen = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // bStartLocateScreen = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             delay = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             capture = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ScreenWhiteTexture = null; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -276,17 +272,12 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else if (locateIndex >= 4 && locateIndex < locateArea.Count - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                QuadrilateralFit(out _, out _, out _); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                QuadrilateralFit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ScreenWhiteTexture = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                QuadrilateralFit(out Texture2D LocateLightedRedTex,out Texture2D ChoosableLineTex, out Texture2D ScreenQuadTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScreenLocate.DebugTexture(2, LocateLightedRedTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScreenLocate.DebugTexture(3, ScreenQuadTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // 融合线段和原图 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScreenLocate.DebugTexture(4, LocateLightedRedTex.Merge(ScreenQuadTex)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ScreenLocate.DebugTexture(5, ChoosableLineTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                QuadrilateralFit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (quadTemp.Count != LocateAreaData[0].Length) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -612,38 +603,22 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return sum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        void QuadrilateralFit(out Texture2D LocateLightedRedTex,out Texture2D ChoosableLineTex, out Texture2D ScreenQuadTex, float lineWidth = 10, Texture2D debugImage = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 转换成屏幕定位所需的纹理图像 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Texture2D ToLocateTex(UnityEngine.Color[] pixels) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            UnityEngine.Color[] differPixel = new UnityEngine.Color[Size.x * Size.y]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //读取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (debugImage != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Debug.Log($"<color=aqua>Debug {debugImage.name}</color>"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                differPixel = debugImage.GetPixels(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else    // 获得屏幕差值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Parallel.For(0, Size.x * Size.y, i => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var pi = ScreenWhiteTexture[i] - ScreenBlackTexture[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    differPixel[i] = new UnityEngine.Color(pi.x, pi.y, pi.z); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var ScreenLocateTex = new Texture2D(Size.x, Size.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ScreenLocateTex.SetPixels(differPixel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ScreenLocateTex.SetPixels(pixels); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ScreenLocateTex.Apply(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //ScreenLocate.DebugTexture(2, ScreenLocateTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var ScreenLocateTexLighted = ScreenLocateTex.AutoLight(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return ScreenLocateTex.AutoLight(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //ScreenLocate.DebugTexture(2, ScreenLocateTexLighted); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var ScreenLocateTexR = ScreenLocateTexLighted.ToRGB(ColorChannel.Red); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var ScreenLocateTexG = ScreenLocateTexLighted.ToRGB(ColorChannel.Green); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var ScreenLocateTexB = ScreenLocateTexLighted.ToRGB(ColorChannel.Blue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //var ScreenLocateTexR = ToLocateTex.ToRGB(ColorChannel.Red); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //var ScreenLocateTexG = ToLocateTex.ToRGB(ColorChannel.Green); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //var ScreenLocateTexB = ToLocateTex.ToRGB(ColorChannel.Blue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            LocateLightedRedTex = ScreenLocateTexR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //LocateLightedRedTex = ScreenLocateTexR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //ScreenLocate.DebugTexture(2, ScreenLocateTexR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //ScreenLocate.DebugTexture(4, ScreenLocateTexG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //ScreenLocate.DebugTexture(5, ScreenLocateTexB); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -653,33 +628,74 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //watch.Start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //var times = new List<double>() { 0.0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //var ScreenLocateTexLightedMat = texture.Too0Mat(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <param name="ScreenLocateTexture">用于算法检测线段的图片</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <param name="ChoosableLineTex">输出备选线段</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <param name="ScreenQuadTex">输出最终结果</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <param name="lineWidth">识别的最小线段长度</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <param name="debugImage">这个参数如果不为null,则执行debug操作</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        void QuadrilateralFit(List<Texture2D> debugImages = null, float lineWidth = 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 屏幕黑白差值,存放多批次的图像用于识别, 该List数量不能等于 0  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<UnityEngine.Color[]> PixelsMultipleBatches = new List<UnityEngine.Color[]>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var ScreenLocateTexLightedMat = ScreenLocateTexLighted.Too0Mat(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //var ScreenLocateTexLightedMat = texture.Too0Mat(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //读取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (debugImages != null && debugImages.Count != 0)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                foreach (var i in debugImages) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Debug.Log($"<color=aqua>Debug {i.name}</color>"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    PixelsMultipleBatches.Add(i.GetPixels()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else    // 获得屏幕差值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                PixelsMultipleBatches.Add(ScreenWhiteTexture.Select((i) => new UnityEngine.Color(i.x, i.y, i.z)).ToArray()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var differPixel = new UnityEngine.Color[Size.x * Size.y]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Parallel.For(0, Size.x * Size.y, i => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var pi = ScreenWhiteTexture[i] - ScreenBlackTexture[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    differPixel[i] = new UnityEngine.Color(pi.x, pi.y, pi.z); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                PixelsMultipleBatches.Add(differPixel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //var (edge, edgeDir) = ScreenLocateTexLightedMat.IdentifyEdge(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             int conSize = (int)Math.Ceiling(0.007f * Size.y) * 2 + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             conSize = Math.Max(conSize, 7);     // 设置最小为7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             float minLength = conSize * 7.7f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             minLength = locateIndex == -1 ? minLength : minLength * areaPercent;    // minLength需要按比例缩小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Debug.Log($"[ScreenIdentification] Size: ({Size.x},{Size.y}), 卷积核Size: {conSize}, 最小线段长度: {minLength}"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var (edge, edgeDir) = ScreenLocateTexLightedMat.zimIdentifyEdgeGradientAny(conSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string log = $"[ScreenLocate Auto] Size: ({Size.x},{Size.y}), 卷积核Size: {conSize}, 最小线段长度: {minLength}"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var allLines = new List<LineIdentified>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Texture2D ScreenLocateTexture = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<Matrix> ScreenLocateMatList = new List<Matrix>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            foreach (var batch in PixelsMultipleBatches.Index()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocateTexture = ToLocateTex(PixelsMultipleBatches[batch]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var ScreenLocateMat = ScreenLocateTexture.Too0Mat();        // 用于获取Lines的Matrix 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var lineCount = ZIMIdentifyQuadLSD(ref allLines, batch, ScreenLocateMat.zimIdentifyEdgeGradientAny(conSize)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log += $"\r\n识别图片{batch}, 识别到的线段数量为: {lineCount}"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocateMatList.Add(ScreenLocateMat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var quadLines = ScreenLocateTexLightedMat.ZIMIdentifyQuadLSD( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                edge, edgeDir,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                out Line[] oldLines, out List<Line> possibleLines,out List<(Line, float, float)> allLines,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Screen, conSize, conSize, minLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 过滤得到四边形的四条边 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var quadLines = FilterLines(ScreenLocateMatList, allLines, GetAvgPoint(ScreenLocateMatList[0]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                out Line[] oldLines, out List<Line> possibleLines, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Screen, conSize, conSize, minLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // 将 allLines 输出一张图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var allLinesMap = new Matrix(ScreenLocateTexLightedMat.Size, Tiling: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var allLinesMap = new Matrix(Size, Tiling: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             foreach (var l in allLines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (l.Item1 != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    o0Extension.DrawLine(allLinesMap, l.Item1, (x, y) => 3, new Geometry2D.Float.Vector(0, 2), true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (l.Line != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    o0Extension.DrawLine(allLinesMap, l.Line, (x, y) => 3, new Geometry2D.Float.Vector(0, 2), true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var allLinesTex = allLinesMap.ToTexRGBA(FloatValueToColor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ScreenLocate.DebugTexture(1, allLinesTex); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -697,10 +713,10 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     LineIdentified.Add(oldLines[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var drawScreenMap = new Matrix(ScreenLocateTexLightedMat.Size, Tiling: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var drawScreenMap = new Matrix(Size, Tiling: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             foreach (var l in LineIdentified) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 o0Extension.DrawLine(drawScreenMap, l, (x, y) => 1, new Geometry2D.Float.Vector(0, lineWidth)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ScreenQuadTex = drawScreenMap.ToTex();      // out ScreenQuadTex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Texture2D ScreenQuadTex = drawScreenMap.ToTex();      // out ScreenQuadTex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             QuadrilateralInCamera screenQuad = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (LineIdentified.Count == 4) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -727,7 +743,7 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // 还需要输出一张识别结果图,包含干扰线段 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var LSDLineMap = new Matrix(ScreenLocateTexLightedMat.Size, Tiling: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var LSDLineMap = new Matrix(Size, Tiling: true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             foreach (var l in possibleLines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (l != null && !quadLines.Contains(l)) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -743,17 +759,15 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 foreach (var l in oldLines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     o0Extension.DrawLine(LSDLineMap, l, (x, y) => 1, new Geometry2D.Float.Vector(0, 2), true);     // 旧的屏幕线段(例如上次手动识别的) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ChoosableLineTex = LSDLineMap.ToTexRGBA(FloatValueToColor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Texture2D ChoosableLineTex = LSDLineMap.ToTexRGBA(FloatValueToColor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Debug.Log(log); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // 是否将图片保存到本地 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (ScreenLocate.Main.SaveToggle.isOn && ScreenLocate.Main.DebugOnZIMDemo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 var FileDirectory = $"Debug_屏幕定位/"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                SaveImages(FileDirectory, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    $"[ScreenLocate Auto] Size: ({Size.x},{Size.y}), 卷积核Size: {conSize}, 最小线段长度: {minLength}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ScreenLocateTex, allLinesTex, ScreenQuadTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                SaveImages(FileDirectory, log, ScreenLocateTexture, allLinesTex, ScreenQuadTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             //times.Add(watch.ElapsedMilliseconds); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -769,7 +783,179 @@ namespace o0.Project 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 //ScreenLocate.DebugTexture(5, cvLines); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            UnityEngine.Object.Destroy(ScreenLocateTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.DebugTexture(2, ScreenLocateTexture); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.DebugTexture(3, ScreenQuadTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 融合线段和原图 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.DebugTexture(4, ScreenLocateTexture.Merge(ScreenQuadTex)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ScreenLocate.DebugTexture(5, ChoosableLineTex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Vector GetAvgPoint(Matrix screenLocateMat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 加权平均 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Vector[] avgPointsColumn = new Vector[screenLocateMat.Size.x]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            float[] valueSumsColumn = new float[screenLocateMat.Size.x]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Parallel.For(0, screenLocateMat.Size.x, i => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (int j = 0; j < screenLocateMat.Size.y; j++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var value = screenLocateMat[i, j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    valueSumsColumn[i] += value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    avgPointsColumn[i] += new Vector(i, j) * value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Vector avgPoint = Vector.Zero; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var valueSum = 0f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 0; i < screenLocateMat.Size.x; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                avgPoint += avgPointsColumn[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                valueSum += valueSumsColumn[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            avgPoint /= valueSum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return avgPoint; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 返回查找到的线段数量,0是查找失败 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int ZIMIdentifyQuadLSD(ref List<LineIdentified> allLines, int batch, (Matrix edgeMat, Matrix edgeDirMat) edgeGradient, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            float minLength = 100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var l = edgeGradient.edgeMat.IdentifyLineLSD(edgeGradient.edgeDirMat, minLength, 20, LineCaptureSize: new Vector(0, 5)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (l == null || l.Count == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            allLines.AddRange(l.Select((i) => new LineIdentified(batch, i))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return l.Count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 返回四边形的四条边,List长度一定是4 (如果没有识别到就是null),且线段顺序是: 下、右、上、左 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Line> FilterLines(List<Matrix> screenLocateMatList, List<LineIdentified> allLines, Vector avgPoint, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            out Line[] oldLines, out List<Line> possibleLines,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ScreenMap screen, float conSize, float gradientLength, float minLength = 100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //Debug.Log("[IdentifyLineLSD] lines.Count: " + lines.Count); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // LSD计算得到的矩阵尺寸较小(因为卷积),这里必须进行位移 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var offset = new Vector((conSize - 1) / 2, (conSize - 1) / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 0; i < allLines.Count; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                allLines[i].Offset(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 沿直线计算综合梯度(梯度乘以长度系数,再乘以距离系数), distanceRatio是实际距离除以最大距离 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            float estimateGradient(LineIdentified line, float distanceRatio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var dir = (line.Line.B - line.Line.A).Normalized; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var vertical = new Vector(-dir.y, dir.x) * (gradientLength / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var step = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var ll = line.Line.Length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var lg = new List<float>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (int i = 0; i <= ll; i += step) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var point = line.Line.A + dir * i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var ga = point + vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var gb = point - vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    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 d = (3 - distanceRatio) / 2;            // 距离系数,距离越近,系数越大 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return e * d * Math.Abs(lg.Mean()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 下、右、上、左 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var quadLines = new List<(float, Line)>[4] { new List<(float, Line)>(), new List<(float, Line)>(), new List<(float, Line)>(), new List<(float, Line)>() }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            possibleLines = new List<Line>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            oldLines = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 如果已有定位数据,根据现有数据筛选线条 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (screen.QuadInCamera != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Debug.Log("[IdentifyLineLSD] 根据已有定位数据做筛选"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                screen.RefreshCameraSize(new Vector2(Size.x, Size.y)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var calibration = ScreenLocate.Main.ReDoLocateCalibrationRatio * Size.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                oldLines = screen.QuadInCamera.GetLines(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var pedals = oldLines.Select((i) => o0Extension.PointPedal(i, avgPoint)).ToArray();     // 当前定位的垂足,下、右、上、左 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                foreach (var i in allLines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    float minDistance = float.MaxValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    int index = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    foreach (var j in pedals.Index()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var d = (o0Extension.PointPedal(i.Line, avgPoint) - pedals[j]).Length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (d < minDistance) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            minDistance = d; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            index = j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    //Debug.Log(minDistance +", -----------"+ calibration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (minDistance < calibration)      // 垂足的距离足够近 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        quadLines[index].Add((estimateGradient(i, minDistance / calibration), i.Line)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        possibleLines.Add(i.Line); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var avaAngleHalf = 75f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                foreach (var line in allLines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    possibleLines.Add(line.Line); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var a = (avgPoint - (line.Line.A + line.Line.B) / 2).DegreeToXAxis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    //Debug.Log(a + ", " + gradient + ", " + sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    int index = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (Math.Abs(a - line.GradientDegree) < avaAngleHalf || Math.Abs(a - 360 - line.GradientDegree) < avaAngleHalf || Math.Abs(a + 360 - line.GradientDegree) < avaAngleHalf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (line.GradientDegree > 45 && line.GradientDegree < 135)     // 下 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        else if (line.GradientDegree > 135 && line.GradientDegree < 225) // 右 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            index = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        else if (line.GradientDegree > 225 && line.GradientDegree < 315)  // 上 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            index = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            index = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //var g = Math.Abs(lg.Mean()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //Debug.Log(gradient + ", " + g); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //List<float> lp1 = new List<float>(), lp2 = new List<float>();    // 线两侧的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //for (float i = 0; i <= ll; i += step) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //    var point = line.A + dir * i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //    var ga = point + vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //    var gb = point - vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //    lp1.Add(screenLocateMat[(int)ga.x, (int)ga.y]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //    lp2.Add(screenLocateMat[(int)gb.x, (int)gb.y]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //var avg1 = lp1.Mean(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //var avg2 = lp2.Mean(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //var v1 = lp1.Variance(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //var v2 = lp2.Variance(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //var lineGradient = Math.Abs(avg1 - avg2) / (v1 + v2 + 0.2f);       // 方差越小,梯度的价值越高 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ////var g = Math.Abs(lg.Mean()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ////Debug.Log(gradient + ", " + g); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //Debug.Log(v1 + ", " + v2 + ", " + lineGradient); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        //quadLines[index].Add((lineGradient, line)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        quadLines[index].Add((estimateGradient(line, 1), line.Line)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var result = new Line[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 0; i < 4; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (quadLines[i].Count > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    result[i] = quadLines[i].Max((a, b) => a.Item1.CompareTo(b.Item1)).Item2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return result.ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         void SaveImages(string FileDirectory, string log, Texture2D ScreenLocateTex, Texture2D allLinesTex, Texture2D ScreenQuadTex) 
			 |