فهرست منبع

Merge branch 'master' of https://gitee.com/slambb/smart-bow-infrared

slambb 1 سال پیش
والد
کامیت
71cc580341

BIN
Assets/InfraredProject/WebCamera/Image/20240927_152451B黑白色差.png


+ 123 - 0
Assets/InfraredProject/WebCamera/Image/20240927_152451B黑白色差.png.meta

@@ -0,0 +1,123 @@
+fileFormatVersion: 2
+guid: 703a84ad918ec7c41b9586d9e10ef2a3
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 12
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 1
+  streamingMipmaps: 0
+  streamingMipmapsPriority: 0
+  vTOnly: 0
+  ignoreMasterTextureLimit: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: 1
+    aniso: 1
+    mipBias: 0
+    wrapU: 1
+    wrapV: 1
+    wrapW: 0
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 1
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spritePixelsToUnits: 100
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spriteGenerateFallbackPhysicsShape: 1
+  alphaUsage: 1
+  alphaIsTransparency: 1
+  spriteTessellationDetail: -1
+  textureType: 8
+  textureShape: 1
+  singleChannelComponent: 0
+  flipbookRows: 1
+  flipbookColumns: 1
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  ignorePngGamma: 0
+  applyGammaDecoding: 0
+  cookieLightType: 0
+  platformSettings:
+  - serializedVersion: 3
+    buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Standalone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Android
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+    bones: []
+    spriteID: 5e97eb03825dee720800000000000000
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+    nameFileIdTable: {}
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7 - 0
Assets/InfraredProject/WebCamera/Script/ZIM/DebugOnDemo.cs

@@ -14,6 +14,13 @@ public class DebugOnDemo : MonoBehaviour
         yield return null;
         ScreenLocate.Main.DebugOnZIMDemo = true;
         ScreenLocate.Main.SaveToggle.isOn = true;
+
+        ScreenLocate.Main.FullScreenToggle.gameObject.SetActive(true);
+        ScreenLocate.Main.FullScreenToggle.onValueChanged.AddListener((i) =>
+        {
+            Screen.fullScreen = i;
+        });
+        Application.targetFrameRate = 60;
     }
 
     void Update()

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

@@ -145,7 +145,7 @@ namespace ZIM
                     int ip = i * samplingScale;
                     int jp = j * samplingScale;
 
-                    if (ScreenPixelCheaker.OutCollider2D(new Vector2(ip, jp)))
+                    if (!screenIdentification.Screen.Active && ScreenPixelCheaker.OutCollider2D(new Vector2(ip, jp)))
                         continue;
 
                     var index = mCameraInfo.CoordToIndex(ip, jp);

+ 52 - 27
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/ScreenIdentification.cs

@@ -77,8 +77,8 @@ namespace o0.Project
         public ScreenIdentification()
         {
             Screen = new ScreenMap();
-            //OnLocateScreenEnter += () => Debug.Log("OnLocateScreenEnter");
-            //OnLocateScreenEnd += () => Debug.Log("OnLocateScreenEnd");
+            OnLocateScreenEnter += () => Application.targetFrameRate = 30;      // 固定识别的帧率,确保摄像机拍到正确的画面
+            OnLocateScreenEnd += () => Application.targetFrameRate = 60;
         }
 
         public void SetScreenQuad(QuadrilateralInCamera quad) => Screen.QuadInCamera = quad;
@@ -88,7 +88,7 @@ namespace o0.Project
         public bool bStartLocateScreen { get; set; } = false;//是否进行捕获
 
         // 自动识别开始的入口
-        public void LocateScreen(int Capture = 45, int Delay = 45)  //数值单位是frame
+        public void LocateScreen(int Capture = 30, int Delay = 30)  //数值单位是frame
         {
             if (ScreenLocate.Main.DebugScreenImages.Count != 0 && ScreenLocate.Main.DebugOnZIMDemo)     // 这段仅用于测试图片
             {
@@ -631,11 +631,8 @@ namespace o0.Project
             //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>
+        /// <param name="debugImages">这个参数如果不为null且数量大于0,则执行debug操作</param>
         void QuadrilateralFit(List<Texture2D> debugImages = null, float lineWidth = 10)
         {
             // 屏幕黑白差值,存放多批次的图像用于识别, 该List数量不能等于 0 
@@ -653,14 +650,23 @@ namespace o0.Project
             }
             else    // 获得屏幕差值
             {
-                PixelsMultipleBatches.Add(ScreenWhiteTexture.Select((i) => new UnityEngine.Color(i.x, i.y, i.z)).ToArray());
+                var maxWhite = 0f;
+                foreach (var i in ScreenWhiteTexture)
+                {
+                    var m = i.x > i.y ? (i.x > i.z ? i.x : i.z) : (i.y > i.z ? i.y : i.z);
+                    if (maxWhite < m)
+                        maxWhite = m;
+                }
+                var scale = 1.0f / maxWhite;        // 放大对比度
+
                 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);
+                    differPixel[i] = new UnityEngine.Color(pi.x, pi.y, pi.z) * scale;
                 });
                 PixelsMultipleBatches.Add(differPixel);
+                PixelsMultipleBatches.Add(ScreenWhiteTexture.Select((i) => new UnityEngine.Color(i.x, i.y, i.z) * scale).ToArray());
             }
 
             int conSize = (int)Math.Ceiling(0.007f * Size.y) * 2 + 1;
@@ -671,20 +677,20 @@ namespace o0.Project
             string log = $"[ScreenLocate Auto] Size: ({Size.x},{Size.y}), 卷积核Size: {conSize}, 最小线段长度: {minLength}";
 
             var allLines = new List<LineIdentified>();
-            Texture2D ScreenLocateTexture = null;
+            List<Texture2D> LocateTexTemp = new List<Texture2D>();
             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));
+                var locateTex = ToLocateTex(PixelsMultipleBatches[batch]);
+                LocateTexTemp.Add(locateTex);
+                var ScreenLocateMat = locateTex.Too0Mat();        // 用于获取Lines的Matrix
+                var lineCount = ZIMIdentifyQuadLSD(ref allLines, batch, ScreenLocateMat.zimIdentifyEdgeGradientAny(conSize), minLength);
                 log += $"\r\n识别图片{batch}, 识别到的线段数量为: {lineCount}";
                 ScreenLocateMatList.Add(ScreenLocateMat);
             }
+            Texture2D ScreenLocateTexture = LocateTexTemp[0];       // for output
 
-
-
-            // 过滤得到四边形的四条边
+            // 过滤得到四边形的四条边, ScreenLocateMatList[0]默认是屏幕的黑白色差
             var quadLines = FilterLines(ScreenLocateMatList, allLines, GetAvgPoint(ScreenLocateMatList[0]),
                 out Line[] oldLines, out List<Line> possibleLines,
                 Screen, conSize, conSize, minLength);
@@ -767,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);
@@ -790,6 +796,11 @@ namespace o0.Project
                 ScreenLocate.DebugTexture(4, ScreenLocateTexture.Merge(ScreenQuadTex));
                 ScreenLocate.DebugTexture(5, ChoosableLineTex);
             }
+            foreach (var i in LocateTexTemp)
+            {
+                if (i != ScreenLocateTexture)       // ScreenLocateTexture 由 ScreenLocate.DebugTexture 释放
+                    GameObject.Destroy(i);
+            }
         }
 
         Vector GetAvgPoint(Matrix screenLocateMat)
@@ -822,7 +833,7 @@ namespace o0.Project
         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));
+            var l = edgeGradient.edgeMat.IdentifyLineLSD(edgeGradient.edgeDirMat, minLength, 50, LineCaptureSize: new Vector(10, 6));
             if (l == null || l.Count == 0)
                 return 0;
             allLines.AddRange(l.Select((i) => new LineIdentified(batch, i)));
@@ -856,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());
             }
@@ -875,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)
                 {
@@ -883,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;
@@ -893,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);
+                        }
                     }
                 }
             }
@@ -958,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);
@@ -973,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);
         }
 

+ 9 - 16
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;
 
@@ -174,13 +174,16 @@ public partial class ScreenLocate : MonoBehaviour
 
     static public void AutoLightPixels(Color[] pixels, int width, int height)
     {
-        var newTex = pixels.zimAutoLightSimple(width, height);
-        DebugTexture(7, newTex);
-        try
+        if (Main.DebugOnZIMDemo)
         {
-            Main.FullScreenImage.texture = newTex;
+            var newTex = pixels.zimAutoLightSimple(width, height);
+            DebugTexture(7, newTex);
+            try
+            {
+                Main.FullScreenImage.texture = newTex;
+            }
+            catch { }
         }
-        catch { }
     }
 
     static public void DebugTexture(int index, Texture texture)
@@ -278,8 +281,6 @@ public partial class ScreenLocate : MonoBehaviour
     {
         //mainContext = SynchronizationContext.Current;
 
-        // 设置目标帧率为60
-        Application.targetFrameRate = 60;
         canvas = transform.GetComponent<RectTransform>();
 
         mode = Mode.InfraredLocate;
@@ -289,14 +290,6 @@ public partial class ScreenLocate : MonoBehaviour
             screenIdentification = new o0.Project.ScreenIdentification();
             screenIdentification.LocateScreen();
         }
-        if (DebugOnZIMDemo) {
-
-            FullScreenToggle.onValueChanged.AddListener((i) =>
-            {
-                Screen.fullScreen = i;
-            });
-
-        }
 
         infraredCount = InfraredCount.Single;
 

+ 3 - 1
Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/ZIMWebCamera.cs

@@ -182,7 +182,9 @@ public class ZIMWebCamera : MonoBehaviour
     private void AdjustTexture()
     {
         Color32[] pixels = _webCamTexture.GetPixels32();
-        AdjustBrightnessContrast(pixels, ScreenLocate.Main.pcBrightness, ScreenLocate.Main.pcContrast);
+
+        if (!ScreenLocate.Main.DebugOnZIMDemo)
+            AdjustBrightnessContrast(pixels, ScreenLocate.Main.pcBrightness, ScreenLocate.Main.pcContrast);
 
         if (adjustedTexture == null || adjustedTexture.width != _webCamTexture.width || adjustedTexture.height != _webCamTexture.height)
         {

+ 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;
         }
 

+ 116 - 2
Assets/InfraredProject/WebCamera/zimWebCamera.unity

@@ -1049,7 +1049,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 1
+  m_IsActive: 0
 --- !u!224 &517576268
 RectTransform:
   m_ObjectHideFlags: 0
@@ -4735,7 +4735,7 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   cameraIndex: 2
-  width: 1280
+  width: 1080
   height: 720
   fps: 30
   rawImage: {fileID: 2101632897}
@@ -5110,6 +5110,7 @@ RectTransform:
   - {fileID: 1793996698}
   - {fileID: 681002957}
   - {fileID: 1922585532}
+  - {fileID: 1740452459998223283}
   m_Father: {fileID: 1867793102}
   m_RootOrder: 5
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -5153,6 +5154,43 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 2101632895}
   m_CullTransparentMesh: 1
+--- !u!1 &1740452459998223282
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1740452459998223283}
+  m_Layer: 5
+  m_Name: CameraMask
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1740452459998223283
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1740452459998223282}
+  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: 4444241363306702546}
+  m_Father: {fileID: 2101632896}
+  m_RootOrder: 5
+  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 &2452220216917731427
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -5211,6 +5249,82 @@ RectTransform:
   m_AnchoredPosition: {x: 15, y: -922}
   m_SizeDelta: {x: 720, y: 420}
   m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &4444241363306702544
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4444241363306702547}
+  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!224 &4444241363306702546
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4444241363306702547}
+  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: 1740452459998223283}
+  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!1 &4444241363306702547
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4444241363306702546}
+  - component: {fileID: 4444241363306702551}
+  - component: {fileID: 4444241363306702544}
+  m_Layer: 5
+  m_Name: PixelCheaker
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!222 &4444241363306702551
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4444241363306702547}
+  m_CullTransparentMesh: 1
 --- !u!1001 &7518895721673355532
 PrefabInstance:
   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;