using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace o0.Project { public partial class InfraredIdentification { Geometry.Vector LastMin = Geometry.Vector.Zero; Geometry.Vector LastMax = Geometry.Vector.One; public Texture2D AutoLight2(Texture2D texture, bool Smooth = false) => AutoLight2(texture.GetPixels(), Smooth); public Texture2D AutoLight2(WebCamTexture texture, bool Smooth = false) => AutoLight2(texture.GetPixels(), Smooth); public Texture2D AutoLight2(UnityEngine.Color[] pixel, bool Smooth = false) { List rList = new List(); List gList = new List(); List bList = new List(); var sampleCount = 1000; float step = pixel.Length / sampleCount; for (float i = 0; i < pixel.Length; i += step) { var iP = pixel[Mathf.FloorToInt(i)]; rList.Add(iP.r); gList.Add(iP.g); bList.Add(iP.b); } rList.Sort((a, b) => a.CompareTo(b)); gList.Sort((a, b) => a.CompareTo(b)); bList.Sort((a, b) => a.CompareTo(b)); var minC = new Geometry.Vector(rList[Mathf.FloorToInt(rList.Count * 0.01f)], gList[Mathf.FloorToInt(rList.Count * 0.01f)], bList[Mathf.FloorToInt(rList.Count * 0.01f)]); var maxC = new Geometry.Vector(rList[Mathf.FloorToInt(rList.Count * 0.99f)], gList[Mathf.FloorToInt(rList.Count * 0.99f)], bList[Mathf.FloorToInt(rList.Count * 0.99f)]); if (Smooth) { LastMin = LastMin * 0.9 + minC * 0.1; LastMax = LastMax * 0.9 + maxC * 0.1; minC = LastMin; maxC = LastMax; }/**/ var mapToMin = 0.05f; var mapToMax = 0.95f; Func map = (value, min, max) => { if (value <= min) return mapToMin; if (value >= max) return mapToMax; return (value - min) / (max - min) * (mapToMax - mapToMin) + mapToMin; }; foreach (var i in pixel.Index()) { var iP = pixel[i]; pixel[i] = new UnityEngine.Color(map(iP.r, minC[0], maxC[0]), map(iP.g, minC[1], maxC[1]), map(iP.b, minC[2], maxC[2])); } var newTex = new Texture2D(Size.x, Size.y); newTex.SetPixels(pixel); newTex.Apply(); return newTex; } } public static partial class Extension { public static Texture2D AutoLight(this Texture2D texture, int ignoreExtremum = 10, int sampleCount = -1) => AutoLight(texture.GetPixels(), new Geometry2D.Vector(texture.width, texture.height), ignoreExtremum, sampleCount); public static Texture2D AutoLight(this WebCamTexture texture, int ignoreExtremum = 10, int sampleCount = -1) => AutoLight(texture.GetPixels(), new Geometry2D.Vector(texture.width, texture.height), ignoreExtremum, sampleCount); /////////////////////////////////////////////////////////忽略极值///////////////采样数量 public static Texture2D AutoLight(this UnityEngine.Color[] pixel, Geometry2D.Vector size, int ignoreExtremum = 10, int sampleCount = -1) { SortedList rMax = new SortedList(); SortedList rMin = new SortedList(); SortedList gMax = new SortedList(); SortedList gMin = new SortedList(); SortedList bMax = new SortedList(); SortedList bMin = new SortedList(); foreach (var i in ignoreExtremum.Range()) { rMax.Add(0); rMin.Add(1); gMax.Add(0); gMin.Add(1); bMax.Add(0); bMin.Add(1); } float step = sampleCount < 1 ? 1 : pixel.Length / sampleCount; for (float i = 0; i < pixel.Length; i += step) { var iP = pixel[Mathf.FloorToInt(i)]; if (iP.r > rMax.First()) { rMax.Add(iP.r); rMax.RemoveAt(0); } if (iP.r < rMin.Last()) { rMin.Add(iP.r); rMin.RemoveAt(rMin.Count - 1); }// if (iP.g > gMax.First()) { gMax.Add(iP.g); gMax.RemoveAt(0); } if (iP.g < gMin.Last()) { gMin.Add(iP.g); gMin.RemoveAt(gMin.Count - 1); }// if (iP.b > bMax.First()) { bMax.Add(iP.b); bMax.RemoveAt(0); } if (iP.b < bMin.Last()) { bMin.Add(iP.b); bMin.RemoveAt(bMin.Count - 1); } } var minC = new Geometry.Vector(rMin.Last(), gMin.Last(), bMin.Last()); var maxC = new Geometry.Vector(rMax.First(), gMax.First(), bMax.First()); /* var mapToMin = 0; var mapToMax = 1; Func map = (value, min, max) => { if (value <= min) return mapToMin; if (value >= max) return mapToMax; return (value - min) / (max - min) * (mapToMax - mapToMin) + mapToMin; };/**/ Func map = (value, min, max) => { if (value <= min) return 0; if (value >= max) return 1; return (value - min) / (max - min); }; foreach (var i in pixel.Index()) { var iP = pixel[i]; pixel[i] = new UnityEngine.Color(map(iP.r, minC[0], maxC[0]), map(iP.g, minC[1], maxC[1]), map(iP.b, minC[2], maxC[2])); } var newTex = new Texture2D(size.x, size.y); newTex.SetPixels(pixel); newTex.Apply(); return newTex; } /////////////////////////////////////////////////////////忽略极值///////////////采样数量 public static Matrix AutoLight(this Matrix mat, int ignoreExtremum = 10) { var pixel = mat.Element; var min = pixel.Min(ignoreExtremum); var max = pixel.Max(ignoreExtremum); var minC = min.Last(); var maxC = max.First(); Func map = (value, min, max) => { if (value <= min) return 0; if (value >= max) return 1; return (value - min) / (max - min); }; var newMat = new Matrix(mat.Size, Tiling: true); var newMatElement = newMat.Element; Parallel.For(0, pixel.Length, i => { newMatElement[i] = map(pixel[i], minC, maxC); }); return newMat; } } }