Browse Source

屏幕识别算法修改

ZIM 1 năm trước cách đây
mục cha
commit
86fba98129
31 tập tin đã thay đổi với 482 bổ sung389 xóa
  1. 6 6
      Assets/BowArrow/Scripts/Bluetooth/New/o0663Axis.cs
  2. 3 3
      Assets/BowArrow/Scripts/Bluetooth/New/o09AxisAfterXiaMenFromDll.cs
  3. 1 1
      Assets/BowArrow/Scripts/Bluetooth/o09AxisCS.cs
  4. 3 3
      Assets/BowArrow/Scripts/Bluetooth/o0DistanceToAxis.cs
  5. BIN
      Assets/BowArrow/Scripts/Bluetooth/o0Lib/SixLabors.ImageSharp.dll
  6. 0 33
      Assets/BowArrow/Scripts/Bluetooth/o0Lib/SixLabors.ImageSharp.dll.meta
  7. BIN
      Assets/BowArrow/Scripts/Bluetooth/o0Lib/System.Text.Encoding.CodePages.dll
  8. 0 33
      Assets/BowArrow/Scripts/Bluetooth/o0Lib/System.Text.Encoding.CodePages.dll.meta
  9. BIN
      Assets/BowArrow/Scripts/Bluetooth/o0Lib/o0NetLib.dll
  10. 1 54
      Assets/BowArrow/Scripts/Bluetooth/o0Lib/o0NetLib.dll.meta
  11. 5 7
      Assets/InfraredProject/Resources/WebCameraView_Zim.prefab
  12. 1 2
      Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/InfraredLocate.cs
  13. 94 87
      Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/ScreenIdentification.cs
  14. 7 1
      Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/ScreenMap.cs
  15. 14 15
      Assets/InfraredProject/WebCamera/Script/ZIM/Other/FindLines.cs
  16. 10 1
      Assets/InfraredProject/WebCamera/Script/ZIM/Other/QuadrilateralInCamera.cs
  17. 1 2
      Assets/InfraredProject/WebCamera/Script/ZIM/Other/TextureZIM.cs
  18. 16 9
      Assets/InfraredProject/WebCamera/Script/ZIM/ScreenLocate.cs
  19. 0 16
      Assets/InfraredProject/WebCamera/Script/ZIM/ZIMMath.cs
  20. 15 7
      Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/Extension.cs
  21. 32 0
      Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/ZIMMath.cs
  22. 0 0
      Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/ZIMMath.cs.meta
  23. 96 0
      Assets/InfraredProject/WebCamera/zimWebCamera.unity
  24. 12 0
      Assets/InfraredProject/o0/o0Extension.cs
  25. 15 4
      Assets/InfraredProject/o0/o0IdentifyLineLSD.cs
  26. 1 1
      Assets/InfraredProject/o0/o0InfraredIdentification.cs
  27. 113 63
      Assets/InfraredProject/o0/zimIdentifyLineLSD.cs
  28. 13 28
      Assets/SmartBow/Resources/SmartBow/Prefabs/Views/Home/InfraredScreenPositioningView.prefab
  29. 6 0
      Assets/SmartBow/Resources/SmartBow/Prefabs/ZIM/BtnRecordInfrared.cs
  30. 7 3
      Assets/SmartBow/Scripts/Views/InfraredViewParts/InfraredScreenPositioningView.cs
  31. 10 10
      ProjectSettings/EditorBuildSettings.asset

+ 6 - 6
Assets/BowArrow/Scripts/Bluetooth/New/o0663Axis.cs

@@ -68,7 +68,7 @@ namespace o0.Bow
             var (Gyr, Acc, Mag, TimeGap) = Attitude.Update(gyr1Byte, gyr2Byte, acc1Byte, acc2Byte, magByte, min, sec, ms1, ms2);
 
 
-            var GyrOperator = Geometry.Quaternion.Euler((Gyr * TimeGap).To<float>());
+            var GyrOperator = Geometry.Quaternion.Euler((Gyr * TimeGap));
 
 
             var Last = States.LastOrDefault() ?? new State();
@@ -124,15 +124,15 @@ namespace o0.Bow
 
 
 
-            var GyrOperator = Geometry.Quaternion.Euler((Gyr * TimeGap).To<float>());
+            var GyrOperator = Geometry.Quaternion.Euler((Gyr * TimeGap));
             var quaGyr = LastQuaternion * GyrOperator;
 
 
             //TestVector.Update9AxisRotation(GyrOperator, 1);
             //TestVector.SetAcc(Acc / 10, 1);
             //TestVector.SetMag(Mag, 1);
-            var accTest = Geometry.Quaternion.FromToRotation(Last.Acc.To<float>(), Acc.To<float>()).Inversed;
-            var magTest = Geometry.Quaternion.FromToRotation(Last.Mag.To<float>(), Mag.To<float>()).Inversed;
+            var accTest = Geometry.Quaternion.FromToRotation(Last.Acc, Acc).Inversed;
+            var magTest = Geometry.Quaternion.FromToRotation(Last.Mag, Mag).Inversed;
             //TestVector.Set9AxisRotation(Last.Qua, 3);
 
             double AccLengthToAngle = 5;//1倍引力差相当于多少度方差
@@ -163,7 +163,7 @@ namespace o0.Bow
             if (double.IsNaN(state.Variance))
                 state.Variance = 0.0000001;
 
-            var quaAccMag = Geometry.Quaternion.FormQuaternion(AccIdentity.To<float>(), MagIdentity.To<float>(), state.Acc.To<float>(), state.Mag.To<float>(), (float)(AccVariance / (AccVariance + MagVariance)));
+            var quaAccMag = Geometry.Quaternion.FormQuaternion(AccIdentity, MagIdentity, state.Acc, state.Mag, (float)(AccVariance / (AccVariance + MagVariance)));
             var quaMinRate = GyrVariance / (GyrVariance + Math.Max(AccVariance, MagVariance));
             var quaMaxRate = GyrVariance / (GyrVariance + Math.Min(AccVariance, MagVariance));
             Geometry.Quaternion quaFirst = Geometry.Quaternion.SLerp(quaGyr, quaAccMag, (float)quaMinRate);
@@ -172,7 +172,7 @@ namespace o0.Bow
 
             var quaSecondRate = (quaMaxRate - quaMinRate) / (1 - quaMinRate);
 
-            state.Qua = AccVariance < MagVariance ? Geometry.Quaternion.FormQuaternion(quaFirst, AccIdentity.To<float>(), state.Acc.To<float>(), (float)quaSecondRate) : Geometry.Quaternion.FormQuaternion(quaFirst, MagIdentity.To<float>(), state.Mag.To<float>(), (float)quaSecondRate);
+            state.Qua = AccVariance < MagVariance ? Geometry.Quaternion.FormQuaternion(quaFirst, AccIdentity, state.Acc, (float)quaSecondRate) : Geometry.Quaternion.FormQuaternion(quaFirst, MagIdentity, state.Mag, (float)quaSecondRate);
 
 
 

+ 3 - 3
Assets/BowArrow/Scripts/Bluetooth/New/o09AxisAfterXiaMenFromDll.cs

@@ -213,7 +213,7 @@ namespace o0.Bow
 
 
 
-            var GyrOperator = Geometry.Quaternion.Euler((Gyr * TimeGap).To<float>());
+            var GyrOperator = Geometry.Quaternion.Euler(Gyr * TimeGap);
             var quaGyr = LastQuaternion * GyrOperator;
 
 
@@ -227,7 +227,7 @@ namespace o0.Bow
 
             var (GyrVariance, AccVariance, MagVariance) = CalVariance(Last, state);
 
-            var quaAccMag = Geometry.Quaternion.FormQuaternion(AccIdentity.To<float>(), MagIdentity.To<float>(), Acc.To<float>(), Mag.To<float>(), (float)(AccVariance / (AccVariance + MagVariance)));
+            var quaAccMag = Geometry.Quaternion.FormQuaternion(AccIdentity, MagIdentity, Acc, Mag, (float)(AccVariance / (AccVariance + MagVariance)));
             var quaMinRate = GyrVariance / (GyrVariance + Math.Max(AccVariance, MagVariance));//静止时约0.01效果最好
             var quaMaxRate = GyrVariance / (GyrVariance + Math.Min(AccVariance, MagVariance));
             Geometry.Quaternion quaFirst = Geometry.Quaternion.SLerp(quaGyr, quaAccMag, (float)quaMinRate);//运算到这里如果视角校准有漂移,说明需要重新校准陀螺仪//不是代码问题
@@ -237,7 +237,7 @@ namespace o0.Bow
 
             // Debug.Log((quaMinRate, AccVariance, quaSecondRate));
 
-            state.Qua = AccVariance < MagVariance ? Geometry.Quaternion.FormQuaternion(quaFirst, AccIdentity.To<float>(), Acc.To<float>(), (float)quaSecondRate) : Geometry.Quaternion.FormQuaternion(quaFirst, MagIdentity.To<float>(), Mag.To<float>(), (float)quaSecondRate);/**/
+            state.Qua = AccVariance < MagVariance ? Geometry.Quaternion.FormQuaternion(quaFirst, AccIdentity, Acc, (float)quaSecondRate) : Geometry.Quaternion.FormQuaternion(quaFirst, MagIdentity, Mag, (float)quaSecondRate);/**/
             //state.Qua = quaFirst;
 
             QuaCheck(ref state.Qua, LastQuaternion);//防止数值溢出

+ 1 - 1
Assets/BowArrow/Scripts/Bluetooth/o09AxisCS.cs

@@ -62,7 +62,7 @@ namespace o0.Bow
         {
 
             //var GyrOperator = Geometry.Quaternion.Euler(Gyr * GapMS);
-            var GyrOperator = Geometry.Quaternion.Euler((Gyr * GapMS).To<float>());
+            var GyrOperator = Geometry.Quaternion.Euler(Gyr * GapMS);
             //Debug.Log(Acc +" | "+ Acc.Length);
             //var GyrOperator = new UnityEngine.Quaternion();
             //GyrOperator.eulerAngles = (Gyr * GapMS).ToUnityVector();

+ 3 - 3
Assets/BowArrow/Scripts/Bluetooth/o0DistanceToAxis.cs

@@ -52,7 +52,7 @@ namespace o0.Bow
             }
             if(LockAcc != default)
             {
-                var GyrOperator = -Geometry.Quaternion.Euler((Gyr * GapMS).To<float>());
+                var GyrOperator = -Geometry.Quaternion.Euler((Gyr * GapMS));
                 LockAcc = (GyrOperator * LockAcc.To<float>()).To<double>();
                 Speed = (GyrOperator * Speed.To<float>()).To<double>();
                 Speed += (Acc - LockAcc) * 9.8 * (LastGapMS + GapMS) / 1000 / 2;
@@ -94,7 +94,7 @@ namespace o0.Bow
         //////// 米/秒                      度/毫秒
         public Vector<double> GyrToSpeed(Vector<double> Gyr, double GapMS)
         {
-            var GyrOperator = Geometry.Quaternion.Euler((Gyr * GapMS).To<float>()).Inversed;
+            var GyrOperator = Geometry.Quaternion.Euler(Gyr * GapMS).Inversed;
             var axis = Vector<double>.Back * Distance;
             axis = (GyrOperator * axis.To<float>() - axis.To<float>()).To<double>() / GapMS * 1000;
             // TestVector.SetAcc(axis.ToUnityVector(), 2);
@@ -112,7 +112,7 @@ namespace o0.Bow
                 //var Speed = 
                 return Acc;
             }
-            var GyrOperator = Geometry.Quaternion.Euler((Gyr * GapMS).To<float>()).Inversed;
+            var GyrOperator = Geometry.Quaternion.Euler(Gyr * GapMS).Inversed;
             var RotatedLastSpeed = GyrOperator * LastSpeed.To<float>();
             var AccCorrection = (Speed - RotatedLastSpeed.To<double>()) / 9.8 / GapMS * 1000;
             // TestVector.SetMag(AccCorrection.ToUnityVector(), 2);

BIN
Assets/BowArrow/Scripts/Bluetooth/o0Lib/SixLabors.ImageSharp.dll


+ 0 - 33
Assets/BowArrow/Scripts/Bluetooth/o0Lib/SixLabors.ImageSharp.dll.meta

@@ -1,33 +0,0 @@
-fileFormatVersion: 2
-guid: 230751fea2b384345853cac523abb96c
-PluginImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  iconMap: {}
-  executionOrder: {}
-  defineConstraints: []
-  isPreloaded: 0
-  isOverridable: 0
-  isExplicitlyReferenced: 0
-  validateReferences: 1
-  platformData:
-  - first:
-      Any: 
-    second:
-      enabled: 1
-      settings: {}
-  - first:
-      Editor: Editor
-    second:
-      enabled: 0
-      settings:
-        DefaultValueInitialized: true
-  - first:
-      Windows Store Apps: WindowsStoreApps
-    second:
-      enabled: 0
-      settings:
-        CPU: AnyCPU
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

BIN
Assets/BowArrow/Scripts/Bluetooth/o0Lib/System.Text.Encoding.CodePages.dll


+ 0 - 33
Assets/BowArrow/Scripts/Bluetooth/o0Lib/System.Text.Encoding.CodePages.dll.meta

@@ -1,33 +0,0 @@
-fileFormatVersion: 2
-guid: 608f97968c7ef114bb40e1f0760abd5b
-PluginImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  iconMap: {}
-  executionOrder: {}
-  defineConstraints: []
-  isPreloaded: 0
-  isOverridable: 0
-  isExplicitlyReferenced: 0
-  validateReferences: 1
-  platformData:
-  - first:
-      Any: 
-    second:
-      enabled: 1
-      settings: {}
-  - first:
-      Editor: Editor
-    second:
-      enabled: 0
-      settings:
-        DefaultValueInitialized: true
-  - first:
-      Windows Store Apps: WindowsStoreApps
-    second:
-      enabled: 0
-      settings:
-        CPU: AnyCPU
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

BIN
Assets/BowArrow/Scripts/Bluetooth/o0Lib/o0NetLib.dll


+ 1 - 54
Assets/BowArrow/Scripts/Bluetooth/o0Lib/o0NetLib.dll.meta

@@ -11,24 +11,6 @@ PluginImporter:
   isExplicitlyReferenced: 0
   validateReferences: 1
   platformData:
-  - first:
-      : Any
-    second:
-      enabled: 0
-      settings:
-        Exclude Android: 0
-        Exclude Editor: 0
-        Exclude Linux64: 0
-        Exclude OSXUniversal: 0
-        Exclude Win: 0
-        Exclude Win64: 0
-        Exclude iOS: 0
-  - first:
-      Android: Android
-    second:
-      enabled: 1
-      settings:
-        CPU: ARMv7
   - first:
       Any: 
     second:
@@ -37,50 +19,15 @@ PluginImporter:
   - first:
       Editor: Editor
     second:
-      enabled: 1
+      enabled: 0
       settings:
-        CPU: AnyCPU
         DefaultValueInitialized: true
-        OS: AnyOS
-  - first:
-      Standalone: Linux64
-    second:
-      enabled: 1
-      settings:
-        CPU: None
-  - first:
-      Standalone: OSXUniversal
-    second:
-      enabled: 1
-      settings:
-        CPU: None
-  - first:
-      Standalone: Win
-    second:
-      enabled: 1
-      settings:
-        CPU: None
-  - first:
-      Standalone: Win64
-    second:
-      enabled: 1
-      settings:
-        CPU: None
   - first:
       Windows Store Apps: WindowsStoreApps
     second:
       enabled: 0
       settings:
         CPU: AnyCPU
-  - first:
-      iPhone: iOS
-    second:
-      enabled: 1
-      settings:
-        AddToEmbeddedBinaries: false
-        CPU: AnyCPU
-        CompileFlags: 
-        FrameworkDependencies: 
   userData: 
   assetBundleName: 
   assetBundleVariant: 

+ 5 - 7
Assets/InfraredProject/Resources/WebCameraView_Zim.prefab

@@ -2068,22 +2068,20 @@ MonoBehaviour:
   - {fileID: 1816618027063368961}
   ScreenQuad: {fileID: 1816618027713108881}
   SaveToggle: {fileID: 1816618028634983694}
-  ScreenLocateCameraSize: {x: 0, y: 0}
   ShowScreenQuad: 1
-  rawImage: {fileID: 1816618028071740130}
-  rawImage1: {fileID: 1816618027396250555}
-  rawImage2: {fileID: 1816618028782547288}
-  rawImage3: {fileID: 1816618027165090661}
-  rawImage4: {fileID: 1816618028593834237}
-  rawImage5: {fileID: 1816618027212933216}
+  outputRawImages: []
   FullScreenImage: {fileID: 1816618027668046880}
+  ScreenPixelCheaker: {fileID: 0}
   InfraredSpotSettings: {fileID: 11400000, guid: ca2f3b215f8d9d64caed905436a89b86, type: 2}
   DebugScreenImage: {fileID: 0}
   DebugOnEditorWin: 1
   bSinglePoint: 1
+  ReDoLocateCalibrationRatio: 0.08
+  infraredCount: 1
   m_UITime: {fileID: 1816618028881862620}
   updateInterval: 0.5
   m_FPS: {fileID: 1816618028690878102}
+  BackQuad: {fileID: 0}
   filterDis: 3
 --- !u!1 &1816618027789859626
 GameObject:

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

@@ -1,7 +1,6 @@
 using DbscanImplementation;
 using o0;
 using o0.Project;
-using SixLabors.ImageSharp;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -213,7 +212,7 @@ namespace ZIM
                 //times.Add(watch.ElapsedMilliseconds);
                 //UnityEngine.Debug.Log("time2: " + (times[times.Count - 1] - times[times.Count - 2]));
 
-                var db = Dbscan.Run(spotPoint, ZIM.Unity.Extension.LengthManhattan, samplingScale * 2, 3);
+                var db = Dbscan.Run(spotPoint, ZIM.Unity.ZIMMath.LengthManhattan, samplingScale * 2, 3);
                 var spotArea = DbscanToSpotAreas(db, brightPoint);
 
                 if (ScreenLocate.Main.DebugOnEditorWin)

+ 94 - 87
Assets/InfraredProject/WebCamera/Script/ZIM/InfraredLocate/ScreenIdentification.cs

@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Threading.Tasks;
 using UnityEngine;
+using UnityStandardAssets.ImageEffects;
 using ZIM;
 using ZIM.Unity;
 
@@ -114,19 +115,12 @@ namespace o0.Project
 
         void DebugImage(Texture2D image)
         {
-            QuadrilateralFit(out Texture2D LocateTex, out Texture2D DrawLineTex, 5, image);
-            ScreenLocate.DebugTexture(1, LocateTex);
-            ScreenLocate.DebugTexture(2, DrawLineTex);
-
+            QuadrilateralFit(out Texture2D LocateLightedRedTex,out Texture2D ChoosableLineTex, out Texture2D ScreenQuadTex, 5, image);
+            ScreenLocate.DebugTexture(1, LocateLightedRedTex);
+            ScreenLocate.DebugTexture(2, ScreenQuadTex);
             // 融合线段和原图
-            var pixel0 = image.GetPixels();
-            var pixel1 = DrawLineTex.GetPixels();
-            for (int i = 0; i < pixel0.Length; i++)
-                pixel0[i] += pixel1[i];
-            var texAdd = new Texture2D(image.width, image.height);
-            texAdd.SetPixels(pixel0);
-            texAdd.Apply();
-            ScreenLocate.DebugTexture(3, texAdd);
+            ScreenLocate.DebugTexture(3, image.Merge(ScreenQuadTex));
+            ScreenLocate.DebugTexture(4, ChoosableLineTex);
 
             //var watch = new System.Diagnostics.Stopwatch();
             //watch.Start();
@@ -141,13 +135,13 @@ namespace o0.Project
                     new QuadrilateralInCamera(quad, image.Size().o0Vector()));
 
                 // 透视变换
-                var srcWidth = LocateTex.width;
+                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 = LocateTex.GetPixels();
+                var srcPixel = LocateLightedRedTex.GetPixels();
                 Parallel.For(0, transformWidth, (x) =>
                 {
                     for (int y = 0; y < transformHeight; y++)
@@ -266,26 +260,29 @@ namespace o0.Project
             }
             else if (locateIndex >= 4 && locateIndex < locateArea.Count - 1)
             {
-                QuadrilateralFit(out _, out _);
+                QuadrilateralFit(out _, out _, out _);
                 ScreenWhiteTexture = null;
             }
             else
             {
-                QuadrilateralFit(out Texture2D LocateTex, out Texture2D DrawLineTex);
+                QuadrilateralFit(out Texture2D LocateLightedRedTex,out Texture2D ChoosableLineTex, out Texture2D ScreenQuadTex);
                 if (ScreenLocate.Main.DebugOnEditorWin)
                 {
-                    ScreenLocate.DebugTexture(1, LocateTex);
-                    ScreenLocate.DebugTexture(2, DrawLineTex);
+                    ScreenLocate.DebugTexture(1, LocateLightedRedTex);
+                    ScreenLocate.DebugTexture(2, ScreenQuadTex);
+                    // 融合线段和原图
+                    ScreenLocate.DebugTexture(3, LocateLightedRedTex.Merge(ScreenQuadTex));
+                    ScreenLocate.DebugTexture(4, ChoosableLineTex);
                 }
 
                 if (quadTemp.Count != LocateAreaData[0].Length)
                 {
-                    Debug.Log($"拟合四边形失败, quadTemp.Count: {quadTemp.Count}");
+                    Debug.Log($"<color=#FFA07A>[ScreenIdentification] 拟合四边形失败, quadTemp.Count: {quadTemp.Count}</color>");
                 }
                 else if (quadTemp.Count == 1)
                 {
                     Screen.QuadInCamera = new QuadrilateralInCamera(quadTemp[0], new Vector(Size.x, Size.y));
-                    //Debug.Log($"拟合四边形成功, quadTemp.Count: {quadTemp.Count}");
+                    Debug.Log($"<color=#ADD8E6>[ScreenIdentification] 拟合成功,Quad: {Screen.QuadInCamera.QuadString}</color>");
                 }
                 else
                 {
@@ -324,7 +321,7 @@ namespace o0.Project
                         }
                     }
                     Screen.QuadInCamera = new QuadrilateralInCamera(predicts, new Vector(Size.x, Size.y));
-                    Debug.Log($"[ScreenIdentification拟合结果] RSquared: {rs}, Quad: {Screen.QuadInCamera.QuadString}");
+                    Debug.Log($"<color=#ADD8E6>[ScreenIdentification] 拟合成功,RSquared: {rs}, Quad: {Screen.QuadInCamera.QuadString}</color>");
                     //if (rs < 0.8) Screen.Quad = null;
                 }
 
@@ -602,9 +599,8 @@ namespace o0.Project
             return sum;
         }
 
-        void QuadrilateralFit(out Texture2D LocateTex, out Texture2D DrawLineTex, float lineWidth = 10, Texture2D debugImage = null)
+        void QuadrilateralFit(out Texture2D LocateLightedRedTex,out Texture2D ChoosableLineTex, out Texture2D ScreenQuadTex, float lineWidth = 10, Texture2D debugImage = null)
         {
-            QuadrilateralInCamera screen = null;
             UnityEngine.Color[] differPixel = new UnityEngine.Color[Size.x * Size.y];
 
             //读取数据
@@ -634,7 +630,7 @@ namespace o0.Project
             var ScreenLocateTexG = ScreenLocateTexLighted.ToRGB(ColorChannel.Green);
             var ScreenLocateTexB = ScreenLocateTexLighted.ToRGB(ColorChannel.Blue);
 
-            LocateTex = ScreenLocateTexR;
+            LocateLightedRedTex = ScreenLocateTexR;
             //ScreenLocate.DebugTexture(2, ScreenLocateTexR);
             //ScreenLocate.DebugTexture(4, ScreenLocateTexG);
             //ScreenLocate.DebugTexture(5, ScreenLocateTexB);
@@ -650,77 +646,80 @@ namespace o0.Project
             //var ScreenLocateTexLightedMat = texture.Too0Mat();
 
             //var (edge, edgeDir) = ScreenLocateTexLightedMat.IdentifyEdge();
-            int conSize = 15;
+            int conSize = (int)Math.Ceiling(0.007f * Size.y) * 2 + 1;
+            Debug.Log($"[ScreenIdentification] Size: ({Size.x},{Size.y}), 卷积核Size: " + conSize);
             var (edge, edgeDir) = ScreenLocateTexLightedMat.zimIdentifyEdgeGradientAny(conSize);
-            ScreenLocate.DebugTexture(5, edgeDir.ToTex());
-            ScreenLocate.DebugTexture(4, edge.ToTex());
 
-            var drawLineMap = new Matrix(ScreenLocateTexLightedMat.Size, Tiling: true);
-            var minLength = locateIndex == -1 ? 50 : 50 * areaPercent;
-            var quadLines = ScreenLocateTexLightedMat.ZIMIdentifyQuadLSD(edge, edgeDir, out List<Line> lightLines, conSize, minLength);
+            var minLength = locateIndex == -1 ? 25 : 25 * areaPercent;
+            var quadLines = ScreenLocateTexLightedMat.ZIMIdentifyQuadLSD(edge, edgeDir, out Line[] oldLines, out List<Line> lightLines, Screen, conSize, conSize, minLength);
 
-            int lineCount = 0;
-            // LSD计算得到的矩阵尺寸较小(因为卷积),这里必须进行位移
-            var offset = new Vector((conSize - 1) / 2, (conSize - 1) / 2);
-            for (int i = 0; i < quadLines.Count; i++)
+            // 将识别到的边画出来,并判断能否拼成屏幕,能拼成则设置ScreenMap
+            // 线段顺序: 下、右、上、左
+            List<Line> LineIdentified = new List<Line>();
+            for (int i = 0; i < 4; i++)
             {
                 if (quadLines[i] != null)
-                {
-                    quadLines[i] += offset;
-                    drawLineMap.DrawLine(quadLines[i], (x, y) => 1, new Geometry2D.Float.Vector(0, lineWidth));
-                    lineCount++;
-                }
+                    LineIdentified.Add(quadLines[i]);
+                else if (oldLines != null)
+                    LineIdentified.Add(oldLines[i]);
             }
-            //foreach (var l in lightLines)
-            //{
-            //    if (l != null)
-            //    {
-            //        if (quadLines.Contains(l))
-            //        {
-            //            drawLineMap.DrawLine(l, (x, y) => 1, new Geometry2D.Float.Vector(0, 10));
-            //            lineCount++;
-            //        }
-            //        else
-            //        {
-            //            drawLineMap.DrawLine(l, (x, y) => 1, new Geometry2D.Float.Vector(0, 2));
-            //        }
-            //    }
-            //}
-            if (lineCount == 4)
+
+            var drawScreenMap = new Matrix(ScreenLocateTexLightedMat.Size, Tiling: true);
+            foreach (var l in LineIdentified)
+                drawScreenMap.DrawLine(l, (x, y) => 1, new Geometry2D.Float.Vector(0, lineWidth));
+            ScreenQuadTex = drawScreenMap.ToTex();      // out ScreenQuadTex
+
+            QuadrilateralInCamera screenQuad = null;
+            if (LineIdentified.Count == 4)
             {
-                var a = quadLines[0].Intersect(quadLines[3], false).Value;
-                var b = quadLines[0].Intersect(quadLines[1], false).Value;
-                var c = quadLines[2].Intersect(quadLines[3], false).Value;
-                var d = quadLines[1].Intersect(quadLines[2], false).Value;
-                screen = new QuadrilateralInCamera(a, b, c, d, new Vector(Size.x, Size.y));
-                if (!screen.IsQuadComplete())
-                    screen = null;
+                var a = LineIdentified[0].Intersect(LineIdentified[3], false).Value;
+                var b = LineIdentified[0].Intersect(LineIdentified[1], false).Value;
+                var c = LineIdentified[2].Intersect(LineIdentified[3], false).Value;
+                var d = LineIdentified[1].Intersect(LineIdentified[2], false).Value;
+                screenQuad = new QuadrilateralInCamera(a, b, c, d, new Vector(Size.x, Size.y));
+                if (!screenQuad.IsQuadComplete())
+                    screenQuad = null;
+            }
+            if (screenQuad == null && Screen.QuadInCamera != null)     // 如果可能,回退到上一个screen
+            {
+                Debug.Log("<color=#ADD8E6>[ScreenIdentification] 本次识别失败,回退到上次的识别结果</color>");
+                quadTemp.Add(Screen.QuadInCamera.Quad);
+            }
+            else if (screenQuad != null)
+            {
+                Debug.Log("<color=#ADD8E6>[ScreenIdentification] 识别到四边形</color>");
+                quadTemp.Add(screenQuad.Quad);
             }
-            if (screen != null)
-                quadTemp.Add(screen.Quad);
-
-            //var lines = edge.IdentifyLineLSD(edgeDir, 100);
-            ////var lines = ScreenLocateTexLightedMat.IdentifyLineLSD();
 
-            //var drawLineMap = new MatrixF2D(edge..Size.x, edge.Size.y);
-            //var returnMaxLines = lines.Sub(0, 10);
-            //foreach (var (line, sum, gradient) in returnMaxLines)
-            //    drawLineMap.DrawLine(line, (x, y) => 1, new Geometry2D.Float.Vector(0, 10));
+            // 还需要输出一张识别结果图,包含干扰线段
+            var LSDLineMap = new Matrix(ScreenLocateTexLightedMat.Size, Tiling: true);
+            foreach (var l in lightLines)
+            {
+                if (l != null && !quadLines.Contains(l))
+                    LSDLineMap.DrawLine(l, (x, y) => 3, new Geometry2D.Float.Vector(0, 2), true); // 其他的备选线段
+            }
+            foreach (var l in quadLines)
+            {
+                if (l != null)
+                    LSDLineMap.DrawLine(l, (x, y) => 2, new Geometry2D.Float.Vector(0, 4)); // 这次识别到的线段
+            }
+            if (oldLines != null)
+            {
+                foreach (var l in oldLines)
+                    LSDLineMap.DrawLine(l, (x, y) => 1, new Geometry2D.Float.Vector(0, 2), true);     // 旧的屏幕线段(例如上次手动识别的)
+            }
+            ChoosableLineTex = LSDLineMap.ToTexRGBA(floatValueToColor);
 
-            DrawLineTex = drawLineMap.ToTex();
-            //ScreenLocate.DebugTexture(3, drawLineMap.ToTex());
-            //var FileSavePath = Application.persistentDataPath + "/ScreenLocateTexture.bin";
-            bool Save = ScreenLocate.Main.SaveToggle.isOn;
-            string time;
-            if (Save)
+            // 是否将图片保存到本地
+            if (ScreenLocate.Main.SaveToggle.isOn)
             {
-                time = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+                var time = DateTime.Now.ToString("yyyyMMdd_HHmmss");
                 var FileSavePath = $"{time}屏幕定位数据.bin";
                 FileSavePath.FileWriteByte(ScreenWhiteTexture);
 
                 var bytes = ScreenLocateTexLighted.EncodeToPNG();
                 File.WriteAllBytes($"{time}屏幕.png", bytes);
-                bytes = DrawLineTex.EncodeToPNG();
+                bytes = ScreenQuadTex.EncodeToPNG();
                 File.WriteAllBytes($"{time}屏幕边框识别.png", bytes);
                 Debug.Log("ScreenLocateTexture Saved To: " + FileSavePath);
             }
@@ -728,14 +727,7 @@ namespace o0.Project
             //times.Add(watch.ElapsedMilliseconds);
             //UnityEngine.Debug.Log("time: " + (times[times.Count - 1] - times[times.Count - 2]));
 
-            //ScreenLocate.DebugTexture(5, edge.IdentifyLine(edgeDir).ToTex());
-            //ScreenLocate.DebugTexture(4, ScreenLocateTexLighted.Too0Mat().IdentifyEdgeGradientX().ToTex());
-            //ScreenLocate.DebugTexture(5, ScreenLocateTexLighted.Too0Mat().IdentifyEdgeGradientY().ToTex());
-
-            //var convolutionLighted2 = ScreenLocateTexLighted.Too0Mat().IdentifyEdgeVariance().ToTex();
-
-            // opecncv处理
-            // zim
+            // opecncv处理, zim
             {
                 //var cvLines = edge.cvHoughLinesP();
                 //ScreenLocate.DebugTexture(5, cvLines);
@@ -747,5 +739,20 @@ namespace o0.Project
 
             UnityEngine.Object.Destroy(ScreenLocateTex);
         }
+
+        private UnityEngine.Color floatValueToColor(float i)
+        {
+            switch (i)
+            {
+                case 1:
+                    return UnityEngine.Color.green;
+                case 2:
+                    return UnityEngine.Color.red;
+                case 3:
+                    return UnityEngine.Color.yellow;
+                default:
+                    return UnityEngine.Color.black;
+            }
+        }
     }
 }

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

@@ -20,7 +20,7 @@ namespace ZIM.Unity
 
         public Rect QuadRect { get; private set; }
         public Vector2 UVSize { get; private set; }     // UV代表屏幕空间的坐标,UVSize代表屏幕坐标的取值范围
-        public bool Active => QuadInCamera != null;
+        public bool Active;
 
         QuadrilateralInCamera quadInCamera;     // 记录的分辨率和识别时的分辨率可能不同
         public QuadrilateralInCamera QuadInCamera
@@ -61,6 +61,12 @@ namespace ZIM.Unity
                 QuadRect = new Rect(aabb.Item1.x, aabb.Item1.y, aabb.Item2.x - aabb.Item1.x, aabb.Item2.y - aabb.Item1.y);
                 Debug.Log("Complete Screen Identification");
                 //Debug.Log("QuadRect:" + QuadRect);
+
+                Active = true;
+            }
+            else
+            {
+                Active = false;
             }
         }
 

+ 14 - 15
Assets/InfraredProject/WebCamera/Script/ZIM/Other/FindLines.cs

@@ -1,9 +1,8 @@
-using System.Collections;
+锘縰sing System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using o0.Geometry2D;
 using System;
-using SixLabors.ImageSharp.PixelFormats;
 using UnityEngine.UIElements;
 using o0.Num;
 using Unity.VisualScripting;
@@ -14,7 +13,7 @@ using o0.Project;
 
 namespace ZIM.Image
 {
-    // 灰度图处理(float)
+    // 鐏板害鍥惧�鐞�(float)
     public class ImgProcessGray
     {
         int width, height;
@@ -98,25 +97,25 @@ namespace ZIM.Image
         {
             bit -= 1;
             var scale = 1 / p.Max();
-            Parallel.For(0, p.Length, (i) => p[i] *= scale);        // 归一化
+            Parallel.For(0, p.Length, (i) => p[i] *= scale);        // 褰掍竴鍖�
             int[] pint = new int[p.Length];
-            Parallel.For(0, p.Length, i => pint[i] = (int)(p[i] * bit));        // 映射到256色彩
+            Parallel.For(0, p.Length, i => pint[i] = (int)(p[i] * bit));        // 鏄犲皠鍒�256鑹插僵
 
             int[] H = new int[bit+1];
             for (int i = 0; i < p.Length; i++)
                 H[pint[i]]++;
             float[] HF = new float[bit+1];
             for (int i = 0; i <= bit; i++)
-                HF[i] = H[i] / (float)p.Length;       // 概率
+                HF[i] = H[i] / (float)p.Length;       // 姒傜巼
 
             float[] D = new float[bit + 1];
             float temp = 0;
-            for (int i = 1; i <= bit; i++)      // 不取颜色为0的概率
+            for (int i = 1; i <= bit; i++)      // 涓嶅彇棰滆壊涓�0鐨勬�鐜�
             {
                 temp += HF[i];
-                D[i] = temp;        // 累计密度
+                D[i] = temp;        // 绱��瀵嗗害
             }
-            Parallel.For(0, p.Length, i => p[i] = D[pint[i]] / D.Last());       // 去密度为颜色,并归一化
+            Parallel.For(0, p.Length, i => p[i] = D[pint[i]] / D.Last());       // 鍘诲瘑搴︿负棰滆壊锛屽苟褰掍竴鍖�
 
         }
     }
@@ -128,7 +127,7 @@ namespace ZIM.Image
         public float Variance;
         public int noiseCount;
 
-        // kernel_size应是奇数,偶数没测试
+        // kernel_size搴旀槸濂囨暟锛屽伓鏁版病娴嬭瘯
         public ConvEdge(ImgProcessGray imgGray, (int, int) pixel, int kernel_size, int scale = 1)
         {
             EdgePoint = new Vector<float>(pixel.Item1, pixel.Item2);
@@ -148,8 +147,8 @@ namespace ZIM.Image
             mean /= convList.Count;
             convList.Sort((a, b) => a.Item1.CompareTo(b.Item1));
 
-            var vMean0 = Vector<float>.Zero;  // 暗区
-            var vMean1 = Vector<float>.Zero;  // 明区
+            var vMean0 = Vector<float>.Zero;  // 鏆楀尯
+            var vMean1 = Vector<float>.Zero;  // 鏄庡尯
             for (int k = 0; k < convList.Count / 2; k++)
             {
                 Variance += (float)Math.Pow((convList[k].Item1 - mean), 2) / convList.Count;
@@ -170,7 +169,7 @@ namespace ZIM.Image
             GetEdgeDirection(vMean0, vMean1);
         }
 
-        // 返回 1 在明区,返回 0 在暗区, -1 在边界上
+        // 杩斿洖 1 鍦ㄦ槑鍖猴紝杩斿洖 0 鍦ㄦ殫鍖�, -1 鍦ㄨ竟鐣屼笂
         public int AreaOfPoint(Vector<float> v)
         {
             var ev = v - EdgePoint;
@@ -180,7 +179,7 @@ namespace ZIM.Image
             return dot < 0 ? 1 : 0;
         }
 
-        void GetEdgeDirection(Vector<float> v0, Vector<float> v1)   // v0 是暗部平均点,v1 是亮部平均点
+        void GetEdgeDirection(Vector<float> v0, Vector<float> v1)   // v0 鏄�殫閮ㄥ钩鍧囩偣锛寁1 鏄�寒閮ㄥ钩鍧囩偣
         {
             var dir = v1 - v0;
             EdgeDirection = new Vector<float>(dir.y, -dir.x);
@@ -196,7 +195,7 @@ namespace ZIM.Image
         //        for (int j = vec.y - kernel_size / 2 * scale; j < vec.y + kernel_size / 2 * scale; j += scale)
         //        {
         //            var index2 = webCamera.cameraInfo.Vector2ToIndex(i, j);
-        //            if (index2 > 0 && index2 < pixels.Length)       // 超出边缘不计算
+        //            if (index2 > 0 && index2 < pixels.Length)       // 瓒呭嚭杈圭紭涓嶈�绠�
         //                sum += pixels[index2];
         //        }
         //    }

+ 10 - 1
Assets/InfraredProject/WebCamera/Script/ZIM/Other/QuadrilateralInCamera.cs

@@ -62,7 +62,7 @@ namespace ZIM.Unity
         }
 
         // 这里是标准化坐标(即数值范围0-1)
-        public List<Vector2> GetUnityVertexList()
+        public List<Vector2> GetUnityVertexNormalizedList()
         {
             return new List<Vector2>() {
                 new Vector2(Quad.A.x / CameraSize.x, Quad.A.y / CameraSize.y),
@@ -72,6 +72,15 @@ namespace ZIM.Unity
             };
         }
 
+        // 线段顺序: 下、右、上、左
+        public Line[] GetLines() => new Line[4]
+        {
+            new Line(Quad.A, Quad.B),
+            new Line(Quad.B, Quad.D),
+            new Line(Quad.C, Quad.D),
+            new Line(Quad.A, Quad.C)
+        };
+
         // 摄像机分辨率变化时调用
         public void ReSize(Vector sizeNew, AspectRatioSetting viewAspectRatioSetting)
         {

+ 1 - 2
Assets/InfraredProject/WebCamera/Script/ZIM/Other/TextureZIM.cs

@@ -1,5 +1,4 @@
-using SixLabors.ImageSharp.PixelFormats;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;

+ 16 - 9
Assets/InfraredProject/WebCamera/Script/ZIM/ScreenLocate.cs

@@ -13,6 +13,7 @@ using ZIM;
 using ZIM.Unity;
 using static SLAMUVC.UVCManager;
 using Color = UnityEngine.Color;
+using Time = UnityEngine.Time;
 
 [RequireComponent(typeof(Canvas))]
 public partial class ScreenLocate : MonoBehaviour
@@ -111,6 +112,10 @@ public partial class ScreenLocate : MonoBehaviour
     //是否单点显示
     public bool bSinglePoint = true;//默认单点识别
 
+    [NonSerialized]
+    public float ReDoLocateCalibrationRatio = 0.04f;  // 重复定位时校准的距离比例,例如先手动定位,再自动定位,会以手动的结果来校准
+
+    [NonSerialized]
     public InfraredCount infraredCount = InfraredCount.Single;
 
     bool bIdentifyRed = true;//默认设备红色
@@ -150,7 +155,7 @@ public partial class ScreenLocate : MonoBehaviour
 
     //o0.Project.WebCam o0WebCam = null;
     o0.Project.ScreenIdentification screenIdentification;
-    public o0.Project.ScreenIdentification getScreenIdentification => screenIdentification;
+    public o0.Project.ScreenIdentification ScreenIdentification => screenIdentification;
 
     /// <summary>
     /// 正在识别的状态,自动识别时候记录
@@ -392,7 +397,7 @@ public partial class ScreenLocate : MonoBehaviour
 
         if (screenIdentification.Screen.RefreshCameraSize(getUVCCameraInfoSize))       // 同步分辨率, 分辨率变化后还需同步到InfraredDemo
         {
-            quadUnityVectorList = screenIdentification.Screen.QuadInCamera.GetUnityVertexList();
+            quadUnityVectorList = screenIdentification.Screen.QuadInCamera.GetUnityVertexNormalizedList();
 
             if (!ContainsNaN(quadUnityVectorList))
             {
@@ -714,7 +719,7 @@ public partial class ScreenLocate : MonoBehaviour
     {
         bAutomaticRecognition = true;
         bAutomaticRecognitionStart = true;
-        screenIdentification.Screen.QuadInCamera = null;
+        ResetScreenIdentification();
         //DefaultResolutionIndex = InfraredDemoMain?.ResolutionIndex ?? 0;        // 记录一下进入前的分辨率(游戏场景的分辨率,比识别时更低)
         //HighScreenLocateResolutionIndex = InfraredDemoMain.getTextureToResolutionNewIndex(); //  index = 0
         // Debug.Log("[ScreenLocate] 开始捕获 DefaultResolutionIndex:" + DefaultResolutionIndex + " ,HighScreenLocateResolutionIndex:" + HighScreenLocateResolutionIndex);
@@ -828,7 +833,7 @@ public partial class ScreenLocate : MonoBehaviour
     // 重置屏幕识别的数据
     public void ResetScreenIdentification()
     {
-        screenIdentification.Screen.QuadInCamera = null;
+        screenIdentification.Screen.Active = false;
     }
 
     /// <summary>
@@ -897,12 +902,14 @@ public partial class ScreenLocate : MonoBehaviour
                 }
             }
         }
-        quadUnityVectorList = screen.GetUnityVertexList();      // 记录四个点
+        quadUnityVectorList = screen.GetUnityVertexNormalizedList();      // 记录四个点
         if (!ContainsNaN(quadUnityVectorList))
         {
             SaveScreenLocateVectorList();
             //SyncInfraredDemo();
-            //SyncInfraredScreenPositioningView();
+            if (DebugOnEditorWin)
+                SyncInfraredScreenPositioningView();
+
             InfraredCameraHelper?.InvokeOnUVCPosUpdate(quadUnityVectorList);
             Debug.Log("[ScreenLocate] ShowScreen 已识别到屏幕,更新quadUnityVectorList:" + PrintVector2List(quadUnityVectorList));
         }
@@ -986,7 +993,7 @@ public partial class ScreenLocate : MonoBehaviour
             }
             Info.text = "按ESC退出";
             SetScreen(Color.black);
-            Info.transform.SetAsLastSibling();
+            //Info.transform.SetAsLastSibling();
             this.mode = Mode.ScreenMap;
         }
         else if (mode == Mode.InfraredLocate)
@@ -998,7 +1005,7 @@ public partial class ScreenLocate : MonoBehaviour
                 i.gameObject.SetActive(false);
             FullScreenImage.gameObject.SetActive(false);
             ScreenPixelCheaker.HideImage();
-            Info.transform.SetSiblingIndex(transform.childCount - 4);
+            //Info.transform.SetSiblingIndex(transform.childCount - 4);
             this.mode = Mode.InfraredLocate;
 
 #if (!NDEBUG && DEBUG && ENABLE_LOG)
@@ -1010,7 +1017,7 @@ public partial class ScreenLocate : MonoBehaviour
             Info.text = "左键单击屏幕 左下角";
             FullScreenImage.gameObject.SetActive(true);
             ScreenPixelCheaker.ShowImage();
-            Info.transform.SetSiblingIndex(transform.childCount - 1);
+            //Info.transform.SetSiblingIndex(transform.childCount - 1);
 
             // var newTex = WebCamera.webCamTexture.AutoLight(10);
             //DebugTexture(1, TextureToTexture2D(rawImage.texture));

+ 0 - 16
Assets/InfraredProject/WebCamera/Script/ZIM/ZIMMath.cs

@@ -1,16 +0,0 @@
-using System;
-using o0.Geometry2D.Float;
-
-namespace ZIM
-{
-    public static partial class ZIMMath
-    {
-        // 向量与x轴的夹角,返回0-360度
-        public static float DegreeToXAxis(this Vector v)
-        {
-            var a = v.x > 0 ? Math.Atan(v.y / v.x) * 180 / Math.PI : 180 + Math.Atan(v.y / v.x) * 180 / Math.PI;
-            a = a < 0 ? 360 + a : a;
-            return (float)a;
-        }
-    }
-}

+ 15 - 7
Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/Extension.cs

@@ -63,11 +63,6 @@ namespace ZIM.Unity
             return c.Value.GetColorName();
         }
 
-        public static float LengthManhattan(this Vector2 v)
-        {
-            return Math.Abs(v.x) + Math.Abs(v.y);
-        }
-
         public static float Brightness(this Color c)
         {
             return 0.59f * c.r + 0.3f * c.r + 0.11f * c.r;    // 红色为主
@@ -82,6 +77,21 @@ namespace ZIM.Unity
             return (int)(0.59f * r + 0.3f * g + 0.11f * b);    // 红色为主
         }
 
+        public static Texture2D Merge(this Texture2D a, Texture2D b)
+        {
+            if (a.width != b.width || a.height != b.height)
+                throw new InvalidOperationException("尺寸不同无法合并texture");
+
+            var pixel0 = a.GetPixels();
+            var pixel1 = b.GetPixels();
+            for (int i = 0; i < pixel0.Length; i++)
+                pixel0[i] += pixel1[i];
+            var texAdd = new Texture2D(a.width, a.height);
+            texAdd.SetPixels(pixel0);
+            texAdd.Apply();
+            return texAdd;
+        }
+
         // 像素坐标映射到Unity局部坐标
         public static Vector2 pixelToLocalPosition_AnchorCenter(this Vector2 pixel, Vector2 size, Rect dstRect)
         {
@@ -130,8 +140,6 @@ namespace ZIM.Unity
             return (float)a;
         }
 
-        public static double LengthManhattan(this Vector2 a, Vector2 b) => Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
-
         public static Texture2D zimAutoLightSimple(this WebCamTexture texture)
         {
             var pixel = texture.GetPixels();

+ 32 - 0
Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/ZIMMath.cs

@@ -0,0 +1,32 @@
+using o0.Geometry2D.Float;
+using System;
+using UnityEngine;
+
+namespace ZIM.Unity
+{
+    public static partial class ZIMMath
+    {
+        // 向量与x轴的夹角,返回0-360度
+        public static float DegreeToXAxis(this Vector v)
+        {
+            //var a = v.x > 0 ? Math.Atan(v.y / v.x) * 180 / Math.PI : 180 + Math.Atan(v.y / v.x) * 180 / Math.PI;
+            var a = Math.Atan2(v.y, v.x) * 180 / Math.PI;
+            if (a < 0)
+                a += 360;
+            return (float)a;
+        }
+
+        // Projects a vector onto another vector.
+        public static Vector2 Project(this Vector2 vector, Vector2 onNormal)
+        {
+            float dotProduct = Vector2.Dot(vector, onNormal);
+            float magnitudeSquared = onNormal.sqrMagnitude;
+            if (magnitudeSquared < Mathf.Epsilon)
+                return Vector2.zero;
+            return (dotProduct / magnitudeSquared) * onNormal;
+        }
+
+        public static float LengthManhattan(this Vector2 v) => Math.Abs(v.x) + Math.Abs(v.y);
+        public static double LengthManhattan(Vector2 v1, Vector2 v2) => (v1 - v2).LengthManhattan();
+    }
+}

+ 0 - 0
Assets/InfraredProject/WebCamera/Script/ZIM/ZIMMath.cs.meta → Assets/InfraredProject/WebCamera/Script/ZIM/ZIMUnity/ZIMMath.cs.meta


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

@@ -499,6 +499,14 @@ PrefabInstance:
   m_Modification:
     m_TransformParent: {fileID: 0}
     m_Modifications:
+    - target: {fileID: 92116852860472276, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_AnchoredPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 92116852860472276, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_AnchoredPosition.y
+      value: 0
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618027111760060, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: m_AnchorMax.y
       value: 0
@@ -507,6 +515,10 @@ PrefabInstance:
       propertyPath: m_AnchorMin.y
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618027111760060, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_SizeDelta.x
+      value: 0
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618027111760060, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: m_AnchoredPosition.x
       value: 0
@@ -567,6 +579,34 @@ PrefabInstance:
       propertyPath: m_AnchoredPosition.y
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618027473945697, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618027473945703, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_Interactable
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618027668046881, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 14
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618027704660352, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_ChildScaleWidth
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618027704660352, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_ChildControlWidth
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618027704660352, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_ChildForceExpandHeight
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618027704660354, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618027770806185, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: m_Name
       value: WebCameraView
@@ -675,6 +715,10 @@ PrefabInstance:
       propertyPath: m_LocalEulerAnglesHint.z
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618027770806191, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_ReferenceResolution.x
+      value: 2400
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618027770806195, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: DebugScreenImage
       value: 
@@ -723,6 +767,10 @@ PrefabInstance:
       propertyPath: m_AnchorMin.y
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618028247322129, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_SizeDelta.x
+      value: 0
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618028247322129, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: m_AnchoredPosition.x
       value: 0
@@ -731,6 +779,18 @@ PrefabInstance:
       propertyPath: m_AnchoredPosition.y
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618028443458514, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618028610635777, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 15
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618028610635836, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_IsActive
+      value: 0
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618028627016767, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: m_AnchorMax.y
       value: 0
@@ -751,6 +811,10 @@ PrefabInstance:
       propertyPath: m_AnchoredPosition.y
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618028690878103, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 17
+      objectReference: {fileID: 0}
     - target: {fileID: 1816618028747326785, guid: a749571a9e509ee42a24695575e9a483, type: 3}
       propertyPath: m_SizeDelta.x
       value: 0
@@ -763,6 +827,38 @@ PrefabInstance:
       propertyPath: m_Name
       value: CameraAutoLight
       objectReference: {fileID: 0}
+    - target: {fileID: 1816618028881862621, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 16
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618028908289204, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_Text
+      value: "\u5B9A\u4F4D\u5C4F\u5E55"
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618028919766142, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618028955147172, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 13
+      objectReference: {fileID: 0}
+    - target: {fileID: 1816618029080775715, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 2619052586130603127, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 6526240123610443117, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 19
+      objectReference: {fileID: 0}
+    - target: {fileID: 9177528485162872681, guid: a749571a9e509ee42a24695575e9a483, type: 3}
+      propertyPath: m_RootOrder
+      value: 21
+      objectReference: {fileID: 0}
     m_RemovedComponents: []
   m_SourcePrefab: {fileID: 100100000, guid: a749571a9e509ee42a24695575e9a483, type: 3}
 --- !u!114 &1816618028118130020 stripped

+ 12 - 0
Assets/InfraredProject/o0/o0Extension.cs

@@ -80,6 +80,18 @@ namespace o0.Project
             tex.Apply();
             return tex;
         }
+        static public Texture2D ToTexRGBA(this Matrix mat, Func<float, UnityEngine.Color> ToColorFunc)
+        {
+            var length = mat.Size.x * mat.Size.y;
+            var ele = mat.Element;
+            UnityEngine.Color[] pixel = new UnityEngine.Color[length];
+            Parallel.For(0, length, i => pixel[i] = ToColorFunc(ele[i]));
+            var tex = new Texture2D(mat.Size.x, mat.Size.y);
+            tex.SetPixels(pixel);
+            tex.Apply();
+            return tex;
+        }
+
         static public Texture2D ToRGB(this Texture2D Tex, ColorChannel channel = ColorChannel.Red)
         {
             var length = Tex.width * Tex.height;

+ 15 - 4
Assets/InfraredProject/o0/o0IdentifyLineLSD.cs

@@ -108,17 +108,28 @@ namespace o0.Project
         }/**/
 
 
-        ///////////////////线  线梯度和 线梯度方向0-180/////////返回的线以梯度和最高值到最低值排列
+        /// <summary>
+        /// List<(Line, float, float)>
+        ///       线  线梯度和 线梯度方向0-180
+        /// </summary>
+        /// <returns>以梯度和最高值到最低值排列</returns>
         static public List<(Line, float, float)> IdentifyLineLSD(this Matrix mat, float minLength = 100)
         {
             var (edge, edgeDir) = mat.IdentifyEdge();
             return edge.IdentifyLineLSD(edgeDir, minLength);
         }
 
-        ///////////////////线  线梯度和 线梯度方向0-180/////////返回的线以梯度和最高值到最低值排列
+        /// <summary>
+        /// List<(Line, float, float)>
+        ///       线  线梯度和 线梯度方向0-180
+        /// </summary>
+        /// <param name="LineCaptureSize">获取line后,在line的位置清空多大范围的数据,以防重复获取(比如线段长10,size为5,3,则清空3像素宽,15像素长的长方形区域)</param>
+        /// <returns>以梯度和最高值到最低值排列</returns>
         static public List<(Line, float, float)> IdentifyLineLSD(this Matrix gradientValueMat, Matrix gradientDirMat, float minLength = 100,
-            int maxReturnCount = int.MaxValue)
+            int maxReturnCount = int.MaxValue, Vector LineCaptureSize = default)
         {
+            if (LineCaptureSize == default)
+                LineCaptureSize = Vector.One * minLength;
             var matBuffer = gradientValueMat;
             //var (mat, gradientMat) = tex.IdentifyEdge();
 
@@ -165,7 +176,7 @@ namespace o0.Project
                 var (line , lineLength, sum, gradientI) = lines.Max((a, b) => a.Item3.CompareTo(b.Item3));
                 if(lineLength != 0)
                 {
-                    matBuffer.DrawLine(line, (x, y) => 0, Vector.One * minLength);
+                    matBuffer.DrawLine(line, (x, y) => 0, LineCaptureSize);
                 }
                 if (lineLength > minLength)
                     returnLines.Add((line, sum, gradientI));

+ 1 - 1
Assets/InfraredProject/o0/o0InfraredIdentification.cs

@@ -132,7 +132,7 @@ namespace o0.Project
                     //o0WebCamera.DebugTexture(4, ScreenLocateTexLighted.Too0Mat().IdentifyEdgeGradient().ToTex());
                     o0WebCamera.DebugTexture(4, edge.ToTex());
 
-                    var quadLines = ScreenLocateTexLightedMat.ZIMIdentifyQuadLSD(edge, edgeDir, out List<Geometry2D.Float.Line> lightLines, 15, 100);
+                    var quadLines = ScreenLocateTexLightedMat.ZIMIdentifyQuadLSD(edge, edgeDir, out _,  out List<Geometry2D.Float.Line> lightLines, null, 15, 100);
 
                     var drawLineMap = new Matrix(edge.Size, Tiling: true);
                     //drawLineMap.DrawLine(quadLines[0], (x, y) => 1, new Geometry2D.Float.Vector(0, 10));

+ 113 - 63
Assets/InfraredProject/o0/zimIdentifyLineLSD.cs

@@ -8,7 +8,9 @@ using UnityEngine;
 using UnityEngine.UI;
 using o0.Geometry2D.Float;
 using ZIM;
+using ZIM.Unity;
 using o0.Num;
+using o0.Geometry2D;
 
 namespace o0.Project
 {
@@ -93,9 +95,10 @@ namespace o0.Project
             return (new Vector(B1, xToYFunc(B1)), Sum1);
         }
 
-        // 线段顺序: 下、右、上、左
-        public static List<Line> ZIMIdentifyQuadLSD(this Matrix screenLocateMat, Matrix edgeMat, Matrix edgeDirMat,out List<Line> lightLines, 
-            float gradientLength, float minLength = 100)
+        // 返回四边形的四条边,List长度一定是4 (如果没有识别到就是null),且线段顺序是: 下、右、上、左
+        public static List<Line> ZIMIdentifyQuadLSD(this Matrix screenLocateMat, Matrix edgeMat, Matrix edgeDirMat,
+            out Line[] oldLines, out List<Line> lightLines, ScreenMap screen, 
+            float conSize, float gradientLength, float minLength = 100)
         {
             // 加权平均
             Vector[] avgPointsColumn = new Vector[screenLocateMat.Size.x];
@@ -119,79 +122,126 @@ namespace o0.Project
             }
             avgPoint /= valueSum;
 
-            var lines = edgeMat.IdentifyLineLSD(edgeDirMat, minLength, 20);
+            var lines = edgeMat.IdentifyLineLSD(edgeDirMat, minLength, 20, LineCaptureSize: new Vector(0, 5));
             //Debug.Log("[IdentifyLineLSD] lines.Count: " + lines.Count);
+            // LSD计算得到的矩阵尺寸较小(因为卷积),这里必须进行位移
+            var offset = new Vector((conSize - 1) / 2, (conSize - 1) / 2);
+            for (int i = 0; i < lines.Count; i++)
+                lines[i] = (lines[i].Item1 + offset, lines[i].Item2, lines[i].Item3);
 
-            // 下、右、上、左
-            var quadLines = new List<(float, Line)>[4] {new List<(float, Line)>(), new List<(float, Line)>(), new List<(float, Line)>(), new List<(float, Line)>() };        
-            var avaAngleHalf = 75f;
-
-            lightLines = new List<Line>();
-            foreach (var (line, sum, gradient) in lines)
+            // 沿直线计算平均梯度
+            float averageGradient(Line line)
             {
-                lightLines.Add(line);
-                var a = (avgPoint - (line.A + line.B) / 2).DegreeToXAxis();
-                //Debug.Log(a + ", " + gradient + ", " + sum);
-                int index = -1;
-                if (Math.Abs(a - gradient) < avaAngleHalf || Math.Abs(a - 360 - gradient) < avaAngleHalf || Math.Abs(a + 360 - gradient) < avaAngleHalf)
+                var dir = (line.B - line.A).Normalized;
+                var vertical = new Vector(-dir.y, dir.x) * (gradientLength / 2);
+                var step = 2;
+                var ll = line.Length;
+                var lg = new List<float>();
+                for (int i = 0; i <= ll; i += step)
                 {
-                    if (gradient > 45 && gradient < 135)     // 下
-                        index = 0;
-                    else if (gradient > 135 && gradient < 225) // 右
-                        index = 1;
-                    else if (gradient > 225 && gradient < 315)  // 上
-                        index = 2;
-                    else
-                        index = 3;
-
-                    // 沿直线计算平均梯度
-                    var dir = (line.B - line.A).Normalized;
-                    var vertical = new Vector(-dir.y, dir.x) * (gradientLength / 2);
-                    var step = 2;
-                    var ll = line.Length;
-                    var lg = new List<float>();
-                    for (int i = 0; i <= ll; i += step) 
-                    {
-                        var point = line.A + dir * i;
-                        var ga = point + vertical;
-                        var gb = point - vertical;
-                        lg.Add(screenLocateMat[(int)ga.x, (int)ga.y] - screenLocateMat[(int)gb.x, (int)gb.y]);
-                        //Debug.Log(lg.Last());
-                    }
+                    var point = line.A + dir * i;
+                    var ga = point + vertical;
+                    var gb = point - vertical;
+                    lg.Add(screenLocateMat[(int)ga.x, (int)ga.y] - screenLocateMat[(int)gb.x, (int)gb.y]);
+                }
+                return Math.Abs(lg.Mean());
+            }
 
-                    //var g = Math.Abs(lg.Mean());
-                    //Debug.Log(gradient + ", " + g);
+            // 下、右、上、左
+            var quadLines = new List<(float, Line)>[4] {new List<(float, Line)>(), new List<(float, Line)>(), new List<(float, Line)>(), new List<(float, Line)>() };
+            lightLines = new List<Line>();
+            oldLines = null;
 
-                    //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]);
-                    //}
+            // 如果已有定位数据,根据现有数据筛选线条
+            if (screen.QuadInCamera != null)
+            {
+                Debug.Log("[IdentifyLineLSD] 根据已有定位数据做筛选");
+                screen.RefreshCameraSize(new Vector2(screenLocateMat.Size.x, screenLocateMat.Size.y));
 
-                    //var avg1 = lp1.Mean();
-                    //var avg2 = lp2.Mean();
-                    //var v1 = lp1.Variance();
-                    //var v2 = lp2.Variance();
+                var calibration = ScreenLocate.Main.ReDoLocateCalibrationRatio * screenLocateMat.Size.y;
+                oldLines = screen.QuadInCamera.GetLines();
 
-                    //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);
+                var pedals = oldLines.Select((i) => i.PointPedal(avgPoint)).ToArray();     // 当前定位的垂足,下、右、上、左
 
-                    //quadLines[index].Add((lineGradient, line));
+                foreach (var i in lines)
+                {
+                    float minDistance = float.MaxValue;
+                    int index = -1;
+                    foreach (var j in pedals.Index())
+                    {
+                        var d = (i.Item1.PointPedal(avgPoint) - pedals[j]).Length;
+                        if (d < minDistance)
+                        {
+                            minDistance = d;
+                            index = j;
+                        }
+                    }
+                    Debug.Log(minDistance +", -----------"+ calibration);
+                    if (minDistance < calibration)      // 垂足的距离足够近
+                    {
+                        quadLines[index].Add((averageGradient(i.Item1), i.Item1));
+                        lightLines.Add(i.Item1);
+                    }
+                }
+            }
+            else
+            {
+                var avaAngleHalf = 75f;
+                foreach (var (line, sum, gradient) in lines)
+                {
+                    lightLines.Add(line);
 
-                    quadLines[index].Add((Math.Abs(lg.Mean()), line));
+                    var a = (avgPoint - (line.A + line.B) / 2).DegreeToXAxis();
+                    //Debug.Log(a + ", " + gradient + ", " + sum);
+                    int index = -1;
+                    if (Math.Abs(a - gradient) < avaAngleHalf || Math.Abs(a - 360 - gradient) < avaAngleHalf || Math.Abs(a + 360 - gradient) < avaAngleHalf)
+                    {
+                        if (gradient > 45 && gradient < 135)     // 下
+                            index = 0;
+                        else if (gradient > 135 && gradient < 225) // 右
+                            index = 1;
+                        else if (gradient > 225 && gradient < 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((averageGradient(line), line));
+                    }
                 }
             }
 
-            var result = new List<Line>();
-            foreach (var list in quadLines)
-                result.Add(list.Max((a, b) => a.Item1.CompareTo(b.Item1)).Item2);
-            return result;
+            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();
         }
     }
 }

+ 13 - 28
Assets/SmartBow/Resources/SmartBow/Prefabs/Views/Home/InfraredScreenPositioningView.prefab

@@ -1360,6 +1360,7 @@ MonoBehaviour:
   textTip2: {fileID: 4901933954594160457}
   btnAuto: {fileID: 2949056324684405733}
   btnHandMovement: {fileID: 4946330363055889030}
+  btnRecordInfrared: {fileID: 4671111450719678205}
   normalColor: {r: 1, g: 1, b: 1, a: 1}
   highlightedColor: {r: 0, g: 1, b: 0, a: 1}
   normalTextColor: {r: 0, g: 0, b: 0, a: 1}
@@ -2373,7 +2374,7 @@ GameObject:
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
-  m_IsActive: 0
+  m_IsActive: 1
 --- !u!224 &4870896031829746376
 RectTransform:
   m_ObjectHideFlags: 0
@@ -2390,9 +2391,9 @@ RectTransform:
   m_Father: {fileID: 2371513326884009388}
   m_RootOrder: 3
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0, y: 1}
-  m_AnchorMax: {x: 0, y: 1}
-  m_AnchoredPosition: {x: 961.38, y: -68}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 274.68, y: 137}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!222 &701688289760265111
@@ -2523,12 +2524,13 @@ RectTransform:
   - {fileID: 7490425254874396240}
   - {fileID: 4870896031829746376}
   - {fileID: 2329041637679056857}
+  - {fileID: 8072716410762509428}
   m_Father: {fileID: 7371505907208373617}
   m_RootOrder: 6
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0}
   m_AnchorMax: {x: 0.5, y: 0}
-  m_AnchoredPosition: {x: 0, y: 170}
+  m_AnchoredPosition: {x: -144.87, y: 170}
   m_SizeDelta: {x: 1183, y: 136}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!114 &6316035318644418506
@@ -3954,12 +3956,12 @@ RectTransform:
   m_ConstrainProportionsScale: 0
   m_Children:
   - {fileID: 8331608948875303033}
-  m_Father: {fileID: 7371505907208373617}
-  m_RootOrder: 7
+  m_Father: {fileID: 2371513326884009388}
+  m_RootOrder: 5
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0, y: 1}
-  m_AnchorMax: {x: 0, y: 1}
-  m_AnchoredPosition: {x: 2194, y: -1254.2501}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 505.9, y: 137}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!222 &292131567826074232
@@ -4385,7 +4387,6 @@ RectTransform:
   - {fileID: 8816989788969488603}
   - {fileID: 2480474177723386199}
   - {fileID: 2371513326884009388}
-  - {fileID: 8072716410762509428}
   m_Father: {fileID: 518485857765021418}
   m_RootOrder: 2
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -4723,7 +4724,6 @@ GameObject:
   - component: {fileID: 9012286184410734088}
   - component: {fileID: 2924947975297261077}
   - component: {fileID: 6015847050880714621}
-  - component: {fileID: 7986556078843686473}
   m_Layer: 5
   m_Name: Text
   m_TagString: Untagged
@@ -4792,22 +4792,7 @@ MonoBehaviour:
     m_HorizontalOverflow: 1
     m_VerticalOverflow: 1
     m_LineSpacing: 1
-  m_Text: "\u624B\u52A8"
---- !u!114 &7986556078843686473
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 8261923157045011813}
-  m_Enabled: 0
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 0f4efe98aab6c6b41a7ee1f4c49df27b, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
-  textKey: 
-  layoutRebuildObject: {fileID: 0}
-  languageFontSizes: []
+  m_Text: "\u91CD\u7F6E"
 --- !u!1 &8427933407996438405
 GameObject:
   m_ObjectHideFlags: 0

+ 6 - 0
Assets/SmartBow/Resources/SmartBow/Prefabs/ZIM/BtnRecordInfrared.cs

@@ -22,6 +22,12 @@ public class BtnRecordInfrared : MonoBehaviour
         GetComponent<Button>().onClick.AddListener(OnClick_RecordInfrared);
     }
 
+    public void Reset()
+    {
+        operateIndex = 0;
+        btnText.text = btnHint[operateIndex];
+    }
+
     // 记录红外灯位置,作为屏幕四个点
     public void OnClick_RecordInfrared()
     {

+ 7 - 3
Assets/SmartBow/Scripts/Views/InfraredViewParts/InfraredScreenPositioningView.cs

@@ -60,6 +60,8 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
     Button btnAuto;
     [SerializeField]
     Button btnHandMovement;
+    [SerializeField]
+    BtnRecordInfrared btnRecordInfrared;
     bool bAuto = true;
     [SerializeField] Color normalColor = Color.white;
     [SerializeField] Color highlightedColor = Color.green;
@@ -271,7 +273,7 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
         draggableParent.gameObject.SetActive(false);
         pointsParent.gameObject.SetActive(true);
         if (ScreenLocate.Main) {
-            ZIM.Unity.QuadrilateralInCamera screen = ScreenLocate.Main.getScreenIdentification.Screen.QuadInCamera;
+            ZIM.Unity.QuadrilateralInCamera screen = ScreenLocate.Main.ScreenIdentification.Screen.QuadInCamera;
             //设置points点
             for (int i = 0; i < 4; i++)
             {
@@ -455,10 +457,9 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
         SaveLocalPos();
     }
 
-    //置位置
+    //置位置
     public void onReset()
     {
-
         oldLinePosition.Clear();
 
         // 获取屏幕的四个角的像素坐标
@@ -483,6 +484,9 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
 
         //设置一次位置
         SetLinePos();
+
+        btnRecordInfrared.Reset();
+        ScreenLocate.Main.ScreenIdentification.SetScreenQuad(null);
     }
 
     #endregion

+ 10 - 10
ProjectSettings/EditorBuildSettings.asset

@@ -5,40 +5,40 @@ EditorBuildSettings:
   m_ObjectHideFlags: 0
   serializedVersion: 2
   m_Scenes:
-  - enabled: 1
+  - enabled: 0
     path: Assets/BowArrow/Scenes/Entry.unity
     guid: 14a16d0455f1bf44a8cf4e02c0550a99
-  - enabled: 1
+  - enabled: 0
     path: Assets/BowArrow/Scenes/Login.unity
     guid: 200a793b1fc5aac438c87e1b342a939a
-  - enabled: 1
+  - enabled: 0
     path: Assets/BowArrow/Scenes/Home.unity
     guid: 8aa5affa1b256294a8c908dbab6122d0
-  - enabled: 1
+  - enabled: 0
     path: Assets/BowArrow/Scenes/Game.unity
     guid: 3ee64920a7ce6dd4782fcc656bb2b337
-  - enabled: 1
+  - enabled: 0
     path: Assets/BowArrow/Scenes/GameChallengeScene/GameChallenge.unity
     guid: 983e1d3256c7dbe49accee6b31bb6d07
   - enabled: 0
     path: Assets/BowArrow/Scenes/GameChallengeScene/GameChallengeNightEnv.unity
     guid: eaefd9b800b58ce4dbb99498871991ca
-  - enabled: 1
+  - enabled: 0
     path: Assets/DuckHunter/Scenes/DuckHunter.unity
     guid: 9920b6e59e0690940a0130b75073a1ea
-  - enabled: 1
+  - enabled: 0
     path: Assets/WildAttack/Scenes/WildAttack.unity
     guid: 9fc0d4010bbf28b4594072e72b8655ab
-  - enabled: 1
+  - enabled: 0
     path: Assets/FruitMaster/Scenes/FruitMaster.unity
     guid: 5600e697996c4b64b8ca124f15f30a58
-  - enabled: 1
+  - enabled: 0
     path: Assets/BowArrow/Scenes/GameDouble.unity
     guid: ab9cb5f113d25ed4a9c69a584d2e5c01
   - enabled: 0
     path: Assets/BowArrow/Scenes/Test.unity
     guid: 14f136990a82f0042aae1edcec1f03a2
-  - enabled: 0
+  - enabled: 1
     path: Assets/InfraredProject/WebCamera/zimWebCamera.unity
     guid: 7561eb6cd780e5e4887e30791c911a9b
   m_configObjects: {}