PixelSpotAreaOld.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using o0;
  2. using o0.Num;
  3. using o0InfraredLocate.ZIM;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. using UnityEngine;
  9. using ZIM.Unity;
  10. using static ScreenLocate;
  11. using Color = UnityEngine.Color;
  12. namespace ZIM
  13. {
  14. // 亮区的点用来定位(计算center),泛光区域的点用来计算radius
  15. public class PixelSpotAreaOld
  16. {
  17. // 中心
  18. public Vector2 Centroid { get; private set; }
  19. // 亮区的半径,计算含泛光点
  20. float radius = 0;
  21. public float Radius
  22. {
  23. set
  24. {
  25. radius = value;
  26. }
  27. get
  28. {
  29. if (radius != 0)
  30. return radius;
  31. //var radiusDic = new Dictionary<int, float>() { { 0, 0 }, { 45, 0 }, { 90, 0 }, { 135, 0 }, { 180, 0 }, { 225, 0 }, { 270, 0 }, { 315, 0 } };
  32. var radiusDic = new float[8];
  33. foreach (var p in Pixels0)
  34. {
  35. var dir = p - Centroid;
  36. var radius = dir.magnitude;
  37. var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
  38. if (degreeI > 7) degreeI = 0; // 防止正好360度
  39. if (radius > radiusDic[degreeI])
  40. radiusDic[degreeI] = radius;
  41. }
  42. foreach (var p in Pixels1)
  43. {
  44. var dir = p - Centroid;
  45. var radius = dir.magnitude;
  46. var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
  47. if (degreeI > 7) degreeI = 0;
  48. if (radius > radiusDic[degreeI])
  49. radiusDic[degreeI] = radius;
  50. }
  51. return radius = radiusDic.Mean();
  52. }
  53. }
  54. public List<Vector2> Pixels0 = new List<Vector2>();
  55. public List<Vector2> Pixels1 = new List<Vector2>();
  56. public PixelSpotAreaOld(Vector2 center) // kmeans中用随机点初始化,作为中心
  57. {
  58. Centroid = center;
  59. }
  60. public void Add0(Vector2 point)
  61. {
  62. Pixels0.Add(point);
  63. }
  64. public void Add1(Vector2 point)
  65. {
  66. Pixels1.Add(point);
  67. }
  68. // 计算中心点,用亮区计算, 如果中心改变则输出true,不变输出false
  69. public bool UpdateCentroid()
  70. {
  71. Vector2 sum = Vector2.zero;
  72. foreach (var p in Pixels0)
  73. sum += p;
  74. var newCentroid = sum / Pixels0.Count;
  75. if (Centroid == newCentroid)
  76. return false;
  77. Centroid = newCentroid;
  78. return true;
  79. }
  80. // 不影响center
  81. public void Clear()
  82. {
  83. Pixels0.Clear();
  84. Pixels1.Clear();
  85. }
  86. public float TotalBrightness(Color[] pixels, Func<int, int, int> Vector2ToIndex, int outer_size = 3)
  87. {
  88. (int x, int y) rectMin = ((int)(Centroid.x - Radius - outer_size), (int)(Centroid.y - Radius - outer_size));
  89. (int x, int y) rectMax = ((int)(Centroid.x + Radius + outer_size), (int)(Centroid.y + Radius + outer_size));
  90. var total = 0f;
  91. Parallel.For(rectMin.x, rectMax.x, (i) =>
  92. {
  93. var t = 0;
  94. for (int j = rectMin.y; j < rectMax.y; j++)
  95. {
  96. var index = Vector2ToIndex(i, j);
  97. var b = pixels[index].Brightness(64);
  98. t += b;
  99. }
  100. lock (InfraredLocate.Locker)
  101. {
  102. total += t;
  103. }
  104. });
  105. //total /= (rectMax.y - rectMin.y) * (rectMax.x - rectMin.x);
  106. return total;
  107. }
  108. }
  109. }