Browse Source

fix bug-修复红外点的轨迹追踪功能

ZIM 1 year ago
parent
commit
9e2cf92580

+ 48 - 1
Assets/InfraredProject/WebCamera/Script/ZIM/DebugOnDemo.cs

@@ -1,12 +1,25 @@
-using System.Collections;
+using o0;
+using System.Collections;
 using System.Collections.Generic;
+using System.Linq;
 using UnityEngine;
+using ZIM;
 
 public class DebugOnDemo : MonoBehaviour
 {
+    //InfraredSpot infrared;
+
     void Start()
     {
         StartCoroutine(OpenDebug());
+
+        //infrared = new InfraredSpot(new ZIM.Unity.ScreenMap(new ZIM.Unity.QuadrilateralInCamera(
+        //    new Vector2(0,0),
+        //    new Vector2(100,0),
+        //    new Vector2(0,100),
+        //    new Vector2(100,100),
+        //    new Vector2(100,100)
+        //    )), InfraredMatch.Match0);
     }
 
     IEnumerator OpenDebug()
@@ -23,11 +36,45 @@ public class DebugOnDemo : MonoBehaviour
         Application.targetFrameRate = 60;
     }
 
+
+
     void Update()
     {
         if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) && Input.GetKeyDown(KeyCode.Return))
         {
             Screen.fullScreen = !Screen.fullScreen;
         }
+
+
+
+        //var matchedArea = new Dictionary<InfraredMatch, PixelSpotArea>() { { InfraredMatch.Match0, null } };
+        //var p0 = new Vector2(10, 10);
+        //var p1 = new Vector2(90, 90);
+        //List<PixelSpotArea> spotArea = new List<PixelSpotArea>() { 
+        //    new PixelSpotArea(p0, PixelSpotArea.GetGrid0(p0), PixelSpotArea.GetGrid1(p0)), 
+        //    new PixelSpotArea(p1, PixelSpotArea.GetGrid0(p1), PixelSpotArea.GetGrid1(p1)) };
+
+        //if (Input.GetKey(KeyCode.Z))
+        //{
+        //    spotArea[1].Join(new Vector2(92, 92));
+        //}
+
+        //var v0 = infrared.Verify(spotArea, matchedArea);
+
+        //if (v0)
+        //{
+
+        //}
+        //else
+        //{
+        //    if (spotArea.Count > 0)
+        //    {
+        //        matchedArea[InfraredMatch.Match0] = spotArea.Max((a, b) => a.Radius.CompareTo(b.Radius));
+        //    }
+        //}
+
+        //infrared.Update(matchedArea.FirstOrDefault().Value);
+
+        //Debug.Log(infrared.CameraLocation);
     }
 }

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

@@ -12,6 +12,11 @@ namespace ZIM
         static int MaxVerifyFailLimit = 20;
         public static float MinVerifyLength = 240;
 
+        public static void RefreshMinVerifyLength(o0.Geometry2D.Float.Vector cameraSize)
+        {
+            MinVerifyLength = (cameraSize.x + cameraSize.y) / 20;
+        }
+
         // 返回null代表没有点,范围在[0, 1]内
         public Vector2? ScreenUV
         {
@@ -56,7 +61,6 @@ namespace ZIM
         public InfraredSpot(ScreenMap screenMap, InfraredMatch match)
         {
             this.screenMap = screenMap;
-            MinVerifyLength = screenMap.UVSize.y / 6;
             Match = match;
             spots = new List<PixelSpotArea>();
             Reset();

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

@@ -664,8 +664,6 @@ namespace o0.Project
         /// <param name="debugImages">这个参数如果不为null且数量大于0,则执行debug操作</param>
         void QuadrilateralFit(List<Texture2D> debugImages = null)
         {
-            // 如果有旧的手动数据,刷新一下Size
-            QuadManual?.ReSize(new Vector(Size.x, Size.y), ScreenMap.ViewAspectRatioSetting);
             // 屏幕黑白差值,存放多批次的图像用于识别, 该List数量不能等于 0 
             List<UnityEngine.Color[]> PixelsMultipleBatches = new List<UnityEngine.Color[]>();
 
@@ -730,6 +728,8 @@ namespace o0.Project
             }
             Texture2D ScreenLocateTexture = LocateTexTemp[0];       // for output
 
+            // 如果有旧的手动数据,刷新一下Size
+            QuadManual?.ReSize(new Vector(Size.x, Size.y), ScreenMap.ViewAspectRatioSetting);
             // 估算屏幕中点,如果已有手动定位数据,根据现有数据取平均即可,否则从色差计算,ScreenLocateMatList[0]默认是屏幕的黑白色差
             Vector AvgPoint = QuadManual != null ? QuadManual.Quad.Centroid : GetAvgPoint(ScreenLocateMatList[0]);
             // 过滤得到四边形的四条边,

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

@@ -34,12 +34,12 @@ namespace ZIM.Unity
         }
 
         // 当分辨率不同时,刷新分辨率并返回true,否则返回false
-        public bool RefreshCameraSize(Vector2 curSize)
+        public bool RefreshCameraSize(Vector2 sizeNew) => RefreshCameraSize(sizeNew.o0Vector());
+        public bool RefreshCameraSize(Vector sizeNew)
         {
-            var sizeNew = curSize.o0Vector();
             if (QuadInCamera != null && QuadInCamera.CameraSize != sizeNew)
             {
-                UnityEngine.Debug.Log("[ScreenMap]根据分辨率映射: from " + QuadInCamera.SizeString + " to " + curSize);
+                UnityEngine.Debug.Log("[ScreenMap]根据分辨率映射: from " + QuadInCamera.SizeString + " to " + sizeNew);
                 QuadInCamera.ReSize(sizeNew, ViewAspectRatioSetting);
                 InitByQuad();
                 return true;

+ 42 - 36
Assets/InfraredProject/WebCamera/Script/ZIM/ScreenLocate.cs

@@ -446,40 +446,16 @@ public partial class ScreenLocate : MonoBehaviour
         if (infraredLocate == null)
         {
             infraredLocate = new InfraredLocate(mUVCCameraInfo, screenIdentification, InfraredSpotSettings, ScreenPixelCheaker);
+            InfraredSpot.RefreshMinVerifyLength(new o0.Geometry2D.Float.Vector(getUVCCameraInfoSize.x, getUVCCameraInfoSize.y));
             //InfraredDemo 初始化
             //float redfilterValue = PlayerPrefs.GetFloat("Init redFilterSliderValue", 0.8f);
             //Debug.Log("Init Red filterValue:" + redfilterValue);
             //infraredLocate.SetBrightnessThreshold(redfilterValue);     // 参数是 红外灯的亮度阈值,阈值越小能够检测到的亮度就越低,默认值是0.93
         }
 
-        if (RefreshQuadSize())       // 同步分辨率, 分辨率变化后还需同步到InfraredDemo
-        {
-            quadUnityVectorList = screenIdentification.Screen.QuadInCamera.GetUnityVertexNormalizedList();
-
-            if (!ContainsNaN(quadUnityVectorList))
-            {
-                SaveScreenLocateVectorList();
-                //SyncInfraredDemo();
-                //SyncInfraredScreenPositioningView();
-                InfraredCameraHelper?.InvokeOnUVCPosUpdate(quadUnityVectorList);
-                Debug.Log("[ScreenLocate] RefreshCameraSize 屏幕size改变:[" + (int)getUVCCameraInfoSize.x + "," + (int)getUVCCameraInfoSize.y + "]");
-                Debug.Log("[ScreenLocate] RefreshCameraSize 屏幕size改变,刷新quadUnityVectorList:" + PrintVector2List(quadUnityVectorList));
-            }
-            else
-            {
-                Debug.LogError("[ScreenLocate] RefreshCameraSize 屏幕size改变,存在NaN值,重新校准:" + PrintVector2List(quadUnityVectorList));
-            }
-
-            if (DebugOnZIMDemo)
-                Main.ShowScreen(screenIdentification.Screen.QuadInCamera);
-
-        }
-
-        //var t0 = Time.realtimeSinceStartup;
-
         /* New*/
         //Debug.Log((mUVCCameraInfo != null) +" = "+ mUVCCameraInfo.IsPreviewing + " = "+ screenIdentification.Screen.Active);
-        if (mUVCCameraInfo != null && mUVCCameraInfo.IsPreviewing)     // 成功定位屏幕后才做红外识别
+        if (mUVCCameraInfo != null && mUVCCameraInfo.IsPreviewing)
         {
             //if (bAutomaticRecognition)
             //{
@@ -509,13 +485,36 @@ public partial class ScreenLocate : MonoBehaviour
             CreateUVCTexture2DIfNeeded((int)getUVCCameraInfoSize.x, (int)getUVCCameraInfoSize.y);
             if (!screenIdentification.Update(mUVCTexture2D))
             {
-                CameraSize = new o0.Geometry2D.Vector<int>(mUVCTexture2D.width, mUVCTexture2D.height);
+                // 同步分辨率, 分辨率变化后还需同步到InfraredDemo
+                if (RefreshCameraSize())
+                {
+                    if (screenIdentification.Screen.QuadInCamera != null)
+                    {
+                        quadUnityVectorList = screenIdentification.Screen.QuadInCamera.GetUnityVertexNormalizedList();
+
+                        if (!ContainsNaN(quadUnityVectorList))
+                        {
+                            SaveScreenLocateVectorList();
+                            //SyncInfraredDemo();
+                            //SyncInfraredScreenPositioningView();
+                            InfraredCameraHelper?.InvokeOnUVCPosUpdate(quadUnityVectorList);
+                            Debug.Log("[ScreenLocate] RefreshCameraSize 屏幕size改变:[" + (int)getUVCCameraInfoSize.x + "," + (int)getUVCCameraInfoSize.y + "]");
+                            Debug.Log("[ScreenLocate] RefreshCameraSize 屏幕size改变,刷新quadUnityVectorList:" + PrintVector2List(quadUnityVectorList));
+                        }
+                        else
+                        {
+                            Debug.LogError("[ScreenLocate] RefreshCameraSize 屏幕size改变,存在NaN值,重新校准:" + PrintVector2List(quadUnityVectorList));
+                        }
+                    }
+                    
+                    if (DebugOnZIMDemo)
+                        Main.ShowScreen(screenIdentification.Screen.QuadInCamera);
+                }
+
+                // 获取像素,用于后续操作
                 var pixels = mUVCTexture2D.GetPixels();       // 从左往右、从下往上
 
                 AutoLightPixels(pixels, CameraSize.x, CameraSize.y);
-                //return;
-                //InfraredSpots = infraredLocate.Update(pixels);
-
                 if (bSinglePoint)
                     infraredSpotBuffer = infraredLocate.UpdateSingle(pixels);
                 else
@@ -713,14 +712,21 @@ public partial class ScreenLocate : MonoBehaviour
 
     }
 
-    private bool RefreshQuadSize()
+    private bool RefreshCameraSize()
     {
-        if (screenIdentification.Screen.RefreshCameraSize(getUVCCameraInfoSize))
+        var sizeNew = new o0.Geometry2D.Vector<int>((int)getUVCCameraInfoSize.x, (int)getUVCCameraInfoSize.y);
+        if (sizeNew != CameraSize) 
         {
-            var sizeNew = getUVCCameraInfoSize.o0Vector();
-            screenIdentification.QuadAuto?.ReSize(sizeNew, ScreenMap.ViewAspectRatioSetting);
-            screenIdentification.QuadManual?.ReSize(sizeNew, ScreenMap.ViewAspectRatioSetting);
-            screenIdentification.QuadSemiAuto?.ReSize(sizeNew, ScreenMap.ViewAspectRatioSetting);
+            Debug.Log("[ScreenLocate] 分辨率变化,刷新分辨率");
+            // 同步相机分辨率
+            CameraSize = sizeNew;
+            var sizeNewFloat = getUVCCameraInfoSize.o0Vector();
+            screenIdentification.Screen.RefreshCameraSize(sizeNewFloat);
+            screenIdentification.QuadAuto?.ReSize(sizeNewFloat, ScreenMap.ViewAspectRatioSetting);
+            screenIdentification.QuadManual?.ReSize(sizeNewFloat, ScreenMap.ViewAspectRatioSetting);
+            screenIdentification.QuadSemiAuto?.ReSize(sizeNewFloat, ScreenMap.ViewAspectRatioSetting);
+
+            InfraredSpot.RefreshMinVerifyLength(sizeNewFloat);
             return true;
         }
         return false;

+ 1 - 1
Assets/SmartBow/Resources/SmartBow/Prefabs/ZIM/CameraMask.prefab

@@ -54,7 +54,7 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 5607599880370664563}
-  m_Enabled: 0
+  m_Enabled: 1
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
   m_Name: 

+ 13 - 13
Assets/SmartBow/Resources/SmartBow/Prefabs/ZIM/PixelCheaker.cs

@@ -19,24 +19,24 @@ public class PixelCheaker : MonoBehaviour
 
     private Vector2 ellipseRadius;
 
-    public bool OutArea2D(Vector2 pixelPosition, Vector<int> imageSize, out float f) => OutArea2D(new Vector2(pixelPosition.x / imageSize.x, pixelPosition.y / imageSize.y), out f);
-    public bool OutArea2D(Vector2 pixelPosition, Vector2 imageSize, out float f) => OutArea2D(pixelPosition / imageSize, out f);
-    public bool OutArea2D(o0.Geometry2D.Float.Vector pixelPosition, Vector<int> imageSize, out float f) => OutArea2D(new Vector2(pixelPosition.x / imageSize.x, pixelPosition.y / imageSize.y), out f);
+    //public bool OutArea2D(Vector2 pixelPosition, Vector<int> imageSize, out float f) => OutArea2D(new Vector2(pixelPosition.x / imageSize.x, pixelPosition.y / imageSize.y), out f);
+    //public bool OutArea2D(Vector2 pixelPosition, Vector2 imageSize, out float f) => OutArea2D(pixelPosition / imageSize, out f);
+    //public bool OutArea2D(o0.Geometry2D.Float.Vector pixelPosition, Vector<int> imageSize, out float f) => OutArea2D(new Vector2(pixelPosition.x / imageSize.x, pixelPosition.y / imageSize.y), out f);
     public bool OutArea2D(Vector2 pixelPosition, Vector<int> imageSize) => OutArea2D(new Vector2(pixelPosition.x / imageSize.x, pixelPosition.y / imageSize.y));
     public bool OutArea2D(Vector2 pixelPosition, Vector2 imageSize) => OutArea2D(pixelPosition / imageSize);
     public bool OutArea2D(o0.Geometry2D.Float.Vector pixelPosition, Vector<int> imageSize) => OutArea2D(new Vector2(pixelPosition.x / imageSize.x, pixelPosition.y / imageSize.y));
 
     // out 椭圆的距离系数,越大表示离椭圆越远
-    private bool OutArea2D(Vector2 pixelUV, out float f)
-    {
-        Vector2 center = new Vector2(0.5f, 0.5f);           // 椭圆中心
-        float normalizedX = (pixelUV.x - center.x) / ellipseRadius.x;
-        float normalizedY = (pixelUV.y - center.y) / ellipseRadius.y;
-
-        float value = (normalizedX * normalizedX) + (normalizedY * normalizedY);    // 使用椭圆方程判断
-        f = (float)Math.Sqrt(value);
-        return value > 1.0f;
-    }
+    //private bool OutArea2D(Vector2 pixelUV, out float f)
+    //{
+    //    Vector2 center = new Vector2(0.5f, 0.5f);           // 椭圆中心
+    //    float normalizedX = (pixelUV.x - center.x) / ellipseRadius.x;
+    //    float normalizedY = (pixelUV.y - center.y) / ellipseRadius.y;
+
+    //    float value = (normalizedX * normalizedX) + (normalizedY * normalizedY);    // 使用椭圆方程判断
+    //    f = (float)Math.Sqrt(value);
+    //    return value > 1.0f;
+    //}
 
     // 无out的版本
     private bool OutArea2D(Vector2 pixelUV)