using o0.Geometry2D.Float; using o0InfraredLocate.ZIM; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Internal; namespace ZIM.Unity { public static partial class Extension { public static UnityEngine.Color UnityColor(this o0.Color c) { return new UnityEngine.Color(c.r, c.g, c.b, c.a); } public static o0.Color o0Color(this UnityEngine.Color c) { return new o0.Color(c.r, c.g, c.b, c.a); } public static Texture2D zimAutoLightSimple(this WebCamTexture texture) { var pixel = texture.GetPixels(); return pixel.zimAutoLightSimple(texture.width, texture.height); } public static Texture2D zimAutoLightSimple(this Texture2D texture) { var pixel = texture.GetPixels(); return pixel.zimAutoLightSimple(texture.width, texture.height); } public static Vector2 Size(this Texture2D texture) { return new Vector2(texture.width, texture.height); } // 亮点放大到1 public static Texture2D zimAutoLightSpot(this WebCamTexture texture) { var pixel = texture.GetPixels(); float[] brightness = new float[pixel.Length]; Parallel.For(0, pixel.Length, (i) => brightness[i] = pixel[i].Brightness()); var max = Enumerable.Max(brightness); var scale = max >= 0.5f ? 1 / max : 1.3f; // 设个阈值 0.5 Parallel.For(0, pixel.Length, (i) => pixel[i] = pixel[i].RGBMutiply(scale)); var tex = new Texture2D(texture.width, texture.height); tex.SetPixels(pixel); tex.Apply(); return tex; } public static Texture2D zimAutoLight(this WebCamTexture texture) { var pixel = texture.GetPixels(); return zimAutoLight(pixel, texture.width, texture.height, 0); } public static Texture2D zimAutoLight(this Texture2D texture, int brightness) { var pixel = texture.GetPixels(); return zimAutoLight(pixel, texture.width, texture.height, brightness); } public static Texture2D zimAutoLight(this Color[] pixel, int width, int height, [DefaultValue("0")] int brightness) { float[] p = new float[pixel.Length]; Parallel.For(0, pixel.Length, (i) => p[i] = pixel[i].Brightness()); var scale = 1 / Enumerable.Max(p) * (2 + brightness); if (float.IsInfinity(scale)) return null; Parallel.For(0, p.Length, (i) => pixel[i] = pixel[i].RGBMutiply(scale)); // 归一化 var tex = new Texture2D(width, height); tex.SetPixels(pixel); tex.Apply(); return tex; } public static Texture2D zimAutoLevelEqualization(this WebCamTexture texture, int bit = 256) { var pixel = texture.GetPixels(); float[] p = new float[pixel.Length]; Parallel.For(0, pixel.Length, (i) => p[i] = pixel[i].r); // 红通道 bit -= 1; var scale = 1 / Enumerable.Max(p); if (float.IsInfinity(scale)) return null; Parallel.For(0, p.Length, (i) => p[i] *= scale); // 归一化 int[] pint = new int[p.Length]; Parallel.For(0, p.Length, i => pint[i] = (int)(p[i] * bit)); // 映射到256色彩 //Debug.Log(Enumerable.Max(pint) + ", " + scale); int[] H = new int[bit + 1]; for (int i = 0; i < p.Length; i++) H[pint[i]]++; float[] HF = new float[bit + 1]; for (int i = 0; i <= bit; i++) HF[i] = H[i] / (float)p.Length; // 概率 float[] D = new float[bit + 1]; float temp = 0; for (int i = 1; i <= bit; i++) // 不取颜色为0的概率 { temp += HF[i]; D[i] = temp; // 累计密度 } Parallel.For(0, p.Length, i => p[i] = D[pint[i]] / D.Last()); // 取密度为颜色,并归一化 UnityEngine.Color[] pixelLighted = new UnityEngine.Color[pixel.Length]; Parallel.For(0, pixel.Length, (i) => pixelLighted[i] = new UnityEngine.Color(p[i], 0, 0)); var tex = new Texture2D(texture.width, texture.height); tex.SetPixels(pixelLighted); tex.Apply(); return tex; } public static void CopyTo(this RenderTexture src, Texture2D dst) { var pre = RenderTexture.active; RenderTexture.active = src; dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0); dst.Apply(); RenderTexture.active = pre; } } }