o0InfraredIdentificationAutoLight.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using UnityEngine;
  7. namespace o0.Project
  8. {
  9. public partial class InfraredIdentification
  10. {
  11. Geometry.Vector<float> LastMin = Geometry.Vector<float>.Zero;
  12. Geometry.Vector<float> LastMax = Geometry.Vector<float>.One;
  13. public Texture2D AutoLight2(Texture2D texture, bool Smooth = false) => AutoLight2(texture.GetPixels(), Smooth);
  14. public Texture2D AutoLight2(WebCamTexture texture, bool Smooth = false) => AutoLight2(texture.GetPixels(), Smooth);
  15. public Texture2D AutoLight2(UnityEngine.Color[] pixel, bool Smooth = false)
  16. {
  17. List<float> rList = new List<float>();
  18. List<float> gList = new List<float>();
  19. List<float> bList = new List<float>();
  20. var sampleCount = 1000;
  21. float step = pixel.Length / sampleCount;
  22. for (float i = 0; i < pixel.Length; i += step)
  23. {
  24. var iP = pixel[Mathf.FloorToInt(i)];
  25. rList.Add(iP.r);
  26. gList.Add(iP.g);
  27. bList.Add(iP.b);
  28. }
  29. rList.Sort((a, b) => a.CompareTo(b));
  30. gList.Sort((a, b) => a.CompareTo(b));
  31. bList.Sort((a, b) => a.CompareTo(b));
  32. var minC = new Geometry.Vector<float>(rList[Mathf.FloorToInt(rList.Count * 0.01f)], gList[Mathf.FloorToInt(rList.Count * 0.01f)], bList[Mathf.FloorToInt(rList.Count * 0.01f)]);
  33. var maxC = new Geometry.Vector<float>(rList[Mathf.FloorToInt(rList.Count * 0.99f)], gList[Mathf.FloorToInt(rList.Count * 0.99f)], bList[Mathf.FloorToInt(rList.Count * 0.99f)]);
  34. if (Smooth)
  35. {
  36. LastMin = LastMin * 0.9 + minC * 0.1;
  37. LastMax = LastMax * 0.9 + maxC * 0.1;
  38. minC = LastMin;
  39. maxC = LastMax;
  40. }/**/
  41. var mapToMin = 0.05f;
  42. var mapToMax = 0.95f;
  43. Func<float, float, float, float> map = (value, min, max) =>
  44. {
  45. if (value <= min)
  46. return mapToMin;
  47. if (value >= max)
  48. return mapToMax;
  49. return (value - min) / (max - min) * (mapToMax - mapToMin) + mapToMin;
  50. };
  51. foreach (var i in pixel.Index())
  52. {
  53. var iP = pixel[i];
  54. pixel[i] = new UnityEngine.Color(map(iP.r, minC[0], maxC[0]),
  55. map(iP.g, minC[1], maxC[1]),
  56. map(iP.b, minC[2], maxC[2]));
  57. }
  58. var newTex = new Texture2D(Size.x, Size.y);
  59. newTex.SetPixels(pixel);
  60. newTex.Apply();
  61. return newTex;
  62. }
  63. }
  64. public static partial class Extension
  65. {
  66. public static Texture2D AutoLight(this Texture2D texture, int ignoreExtremum = 10, int sampleCount = -1) => AutoLight(texture.GetPixels(), new Geometry2D.Vector<int>(texture.width, texture.height), ignoreExtremum, sampleCount);
  67. public static Texture2D AutoLight(this WebCamTexture texture, int ignoreExtremum = 10, int sampleCount = -1) => AutoLight(texture.GetPixels(), new Geometry2D.Vector<int>(texture.width, texture.height), ignoreExtremum, sampleCount);
  68. /////////////////////////////////////////////////////////忽略极值///////////////采样数量
  69. public static Texture2D AutoLight(this UnityEngine.Color[] pixel, Geometry2D.Vector<int> size, int ignoreExtremum = 10, int sampleCount = -1)
  70. {
  71. SortedList<float> rMax = new SortedList<float>();
  72. SortedList<float> rMin = new SortedList<float>();
  73. SortedList<float> gMax = new SortedList<float>();
  74. SortedList<float> gMin = new SortedList<float>();
  75. SortedList<float> bMax = new SortedList<float>();
  76. SortedList<float> bMin = new SortedList<float>();
  77. foreach (var i in ignoreExtremum.Range())
  78. {
  79. rMax.Add(0);
  80. rMin.Add(1);
  81. gMax.Add(0);
  82. gMin.Add(1);
  83. bMax.Add(0);
  84. bMin.Add(1);
  85. }
  86. float step = sampleCount < 1 ? 1 : pixel.Length / sampleCount;
  87. for (float i = 0; i < pixel.Length; i += step)
  88. {
  89. var iP = pixel[Mathf.FloorToInt(i)];
  90. if (iP.r > rMax.First())
  91. {
  92. rMax.Add(iP.r);
  93. rMax.RemoveAt(0);
  94. }
  95. if (iP.r < rMin.Last())
  96. {
  97. rMin.Add(iP.r);
  98. rMin.RemoveAt(rMin.Count - 1);
  99. }//
  100. if (iP.g > gMax.First())
  101. {
  102. gMax.Add(iP.g);
  103. gMax.RemoveAt(0);
  104. }
  105. if (iP.g < gMin.Last())
  106. {
  107. gMin.Add(iP.g);
  108. gMin.RemoveAt(gMin.Count - 1);
  109. }//
  110. if (iP.b > bMax.First())
  111. {
  112. bMax.Add(iP.b);
  113. bMax.RemoveAt(0);
  114. }
  115. if (iP.b < bMin.Last())
  116. {
  117. bMin.Add(iP.b);
  118. bMin.RemoveAt(bMin.Count - 1);
  119. }
  120. }
  121. var minC = new Geometry.Vector<float>(rMin.Last(), gMin.Last(), bMin.Last());
  122. var maxC = new Geometry.Vector<float>(rMax.First(), gMax.First(), bMax.First());
  123. /*
  124. var mapToMin = 0;
  125. var mapToMax = 1;
  126. Func<float, float, float, float> map = (value, min, max) =>
  127. {
  128. if (value <= min)
  129. return mapToMin;
  130. if (value >= max)
  131. return mapToMax;
  132. return (value - min) / (max - min) * (mapToMax - mapToMin) + mapToMin;
  133. };/**/
  134. Func<float, float, float, float> map = (value, min, max) =>
  135. {
  136. if (value <= min)
  137. return 0;
  138. if (value >= max)
  139. return 1;
  140. return (value - min) / (max - min);
  141. };
  142. foreach (var i in pixel.Index())
  143. {
  144. var iP = pixel[i];
  145. pixel[i] = new UnityEngine.Color(map(iP.r, minC[0], maxC[0]),
  146. map(iP.g, minC[1], maxC[1]),
  147. map(iP.b, minC[2], maxC[2]));
  148. }
  149. var newTex = new Texture2D(size.x, size.y);
  150. newTex.SetPixels(pixel);
  151. newTex.Apply();
  152. return newTex;
  153. }
  154. /////////////////////////////////////////////////////////忽略极值///////////////采样数量
  155. public static Matrix AutoLight(this Matrix mat, int ignoreExtremum = 10)
  156. {
  157. var pixel = mat.Element;
  158. var min = pixel.Min(ignoreExtremum);
  159. var max = pixel.Max(ignoreExtremum);
  160. var minC = min.Last();
  161. var maxC = max.First();
  162. Func<float, float, float, float> map = (value, min, max) =>
  163. {
  164. if (value <= min)
  165. return 0;
  166. if (value >= max)
  167. return 1;
  168. return (value - min) / (max - min);
  169. };
  170. var newMat = new Matrix(mat.Size, Tiling: true);
  171. var newMatElement = newMat.Element;
  172. Parallel.For(0, pixel.Length, i => {
  173. newMatElement[i] = map(pixel[i], minC, maxC);
  174. });
  175. return newMat;
  176. }
  177. }
  178. }