InfraredSpot.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using ZIM.Unity;
  5. using Color = UnityEngine.Color;
  6. namespace ZIM
  7. {
  8. public class InfraredSpot
  9. {
  10. // 达到该数量才完成初始化
  11. //static int InitCount = 5;
  12. static int MaxVerifyFailLimit = 20;
  13. public static float MinVerifyLength = 240;
  14. public static void RefreshMinVerifyLength(o0.Geometry2D.Float.Vector cameraSize)
  15. {
  16. MinVerifyLength = (cameraSize.x + cameraSize.y) / 20;
  17. }
  18. // 返回null代表没有点,范围在[0, 1]内
  19. public Vector2? ScreenUV
  20. {
  21. get
  22. {
  23. if (ScreenLocation.HasValue)
  24. {
  25. return screenMap.UVNormalized(ScreenLocation.Value);
  26. }
  27. else
  28. {
  29. return null;
  30. }
  31. }
  32. }
  33. // 范围在摄像机的Size内
  34. public Vector2? CameraLocation
  35. {
  36. get
  37. {
  38. if (ScreenLocation.HasValue)
  39. {
  40. return screenMap.TransformToCamera(ScreenLocation.Value);
  41. }
  42. else
  43. return null;
  44. }
  45. }
  46. public Vector2? Predict { get; set; } // 为null时代表未初始化
  47. public InfraredMatch Match { get; private set; }
  48. public bool Disappear;
  49. //PixelSpotArea verifyArea;
  50. int verifyFailLimit;
  51. List<PixelSpotArea> spots;
  52. SimpleLocationEstimation estimation;
  53. Vector2? ScreenLocation;
  54. ScreenMap screenMap;
  55. public InfraredSpot(ScreenMap screenMap, InfraredMatch match)
  56. {
  57. this.screenMap = screenMap;
  58. Match = match;
  59. spots = new List<PixelSpotArea>();
  60. Reset();
  61. }
  62. public void Reset()
  63. {
  64. spots.Clear();
  65. estimation = new SimpleLocationEstimation(0.5f);
  66. ScreenLocation = null;
  67. Predict = null;
  68. Disappear = false;
  69. //verifyArea = null;
  70. verifyFailLimit = MaxVerifyFailLimit;
  71. }
  72. public bool Verify(List<PixelSpotArea> areas, Dictionary<InfraredMatch, PixelSpotArea> matchedArea)
  73. {
  74. if (Predict == null) // 未初始化
  75. return false;
  76. PixelSpotArea select = null;
  77. var minLength = float.MaxValue;
  78. var predict = Predict.Value;
  79. var refPoint = (predict + spots.Last().Centroid) / 2; // 用预测点和最后一个点的中点来判断是否追踪到
  80. foreach (var i in areas)
  81. {
  82. var len = (i.Centroid - refPoint).magnitude;
  83. if (len < MinVerifyLength)
  84. {
  85. if (len < minLength) // 找到追踪到的,并且距离最近的spot
  86. {
  87. select = i;
  88. minLength = len;
  89. }
  90. }
  91. }
  92. if (select == null)
  93. {
  94. //Debug.Log(verifyFailLimit);
  95. verifyFailLimit--;
  96. if (verifyFailLimit == 0)
  97. Reset();
  98. return false;
  99. }
  100. //verifyArea = select;
  101. matchedArea[Match] = select;
  102. return true;
  103. }
  104. //public void UpdateByVerifyArea()
  105. //{
  106. // Update(verifyArea);
  107. //}
  108. // 为null时采用预测点
  109. public void Update(PixelSpotArea area)
  110. {
  111. if (area == null)
  112. {
  113. //throw new System.Exception("[InfraredSpot] Update Wrong");
  114. UpdateByPredict();
  115. return;
  116. }
  117. var predict = estimation.Update(area.Centroid);
  118. ScreenLocation = area.Centroid * 0.8f + predict * 0.2f; // 参考一点预测点,防止光标不稳定
  119. spots.Add(area);
  120. if (spots.Count > 15)
  121. {
  122. Predict = predict;
  123. spots.RemoveAt(0);
  124. }
  125. }
  126. void UpdateByPredict()
  127. {
  128. if (spots.Count != 0)
  129. {
  130. if (Predict == null) // 还未初始化,直接Reset
  131. Reset();
  132. else
  133. {
  134. // 采用预测点,但超出屏幕则Reset
  135. if (screenMap.UVInScreen(Predict.Value))
  136. {
  137. ScreenLocation = Predict;
  138. var newP = estimation.Update(Predict.Value);
  139. Predict = newP;
  140. }
  141. else
  142. Reset();
  143. }
  144. }
  145. }
  146. }
  147. }