| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- using o0;
- using o0.Num;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using UnityEngine;
- using ZIM.Unity;
- using static ScreenLocate;
- using Color = UnityEngine.Color;
- namespace ZIM
- {
- public interface IPixel<T>
- {
- // 像素坐标点
- T Point { get;}
- }
- // 亮区的点用来定位(计算center),泛光区域的点用来计算radius
- public class PixelSpotArea_DbScan
- {
- // 中心
- Vector2 centroid = default; // 该项目里center不可能等于0,0
- public Vector2 Centroid
- {
- get
- {
- if (centroid != default)
- return centroid;
- foreach (var p in Pixels0)
- centroid += p.Point;
- return centroid /= Pixels0.Count;
- }
- }
- // 亮区的半径,计算含泛光点
- float radius = 0;
- public float Radius
- {
- set
- {
- radius = value;
- }
- get
- {
- if (radius != 0)
- return radius;
- return radius = CalculateRadius();
- }
- }
- public float CalculateRadius()
- {
- //var radiusDic = new Dictionary<int, float>() { { 0, 0 }, { 45, 0 }, { 90, 0 }, { 135, 0 }, { 180, 0 }, { 225, 0 }, { 270, 0 }, { 315, 0 } };
- var radiusDic = new float[8];
- foreach (var p in Pixels0)
- {
- var dir = p.Point - Centroid;
- var radius = dir.magnitude;
- var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
- if (degreeI > 7) degreeI = 0; // 防止正好360度
- if (radius > radiusDic[degreeI])
- radiusDic[degreeI] = radius;
- }
- foreach (var p in Pixels1)
- {
- var dir = p - Centroid;
- var radius = dir.magnitude;
- var degreeI = radius < 0.00001f ? 0 : (int)(dir.DegreeToXAxis() / 45);
- if (degreeI > 7) degreeI = 0;
- if (radius > radiusDic[degreeI])
- radiusDic[degreeI] = radius;
- }
- return radiusDic.Mean();
- }
- // 中心亮点
- public List<IPixel<Vector2>> Pixels0 = new List<IPixel<Vector2>>();
- // 泛光
- public List<Vector2> Pixels1 = new List<Vector2>();
- public PixelSpotArea_DbScan(IEnumerable<IPixel<Vector2>> p) // kmeans中用随机点初始化,作为中心
- {
- Pixels0.AddRange(p);
- }
- // 中心亮点
- public void Add0(IPixel<Vector2> p)
- {
- Pixels0.Add(p);
- }
- // 泛光
- public void Add1(Vector2 point)
- {
- Pixels1.Add(point);
- }
- public void Clear()
- {
- Pixels0.Clear();
- Pixels1.Clear();
- }
- public float TotalBrightness(Color[] pixels, Func<int, int, int> Vector2ToIndex, int outer_size = 3)
- {
- (int x, int y) rectMin = ((int)(Centroid.x - Radius - outer_size), (int)(Centroid.y - Radius - outer_size));
- (int x, int y) rectMax = ((int)(Centroid.x + Radius + outer_size), (int)(Centroid.y + Radius + outer_size));
- var total = 0f;
- Parallel.For(rectMin.x, rectMax.x, (i) =>
- {
- var t = 0;
- for (int j = rectMin.y; j < rectMax.y; j++)
- {
- var index = Vector2ToIndex(i, j);
- var b = pixels[index].Brightness(64);
- t += b;
- }
- lock (InfraredLocate.locker)
- {
- total += t;
- }
- });
- //total /= (rectMax.y - rectMin.y) * (rectMax.x - rectMin.x);
- return total;
- }
- }
- }
|