| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using ZIM.Unity;
- using Color = UnityEngine.Color;
- namespace ZIM
- {
- public class InfraredSpot
- {
- // 达到该数量才完成初始化
- //static int InitCount = 5;
- static int MaxVerifyFailLimit = 20;
- public static float MinVerifyLength = 240;
- public static void RefreshMinVerifyLength(o0.Geometry2D.Float.Vector cameraSize)
- {
- MinVerifyLength = (cameraSize.x + cameraSize.y) / 20;
- }
- // 返回null代表没有点,范围在[0, 1]内
- public Vector2? ScreenUV
- {
- get
- {
- if (ScreenLocation.HasValue)
- {
- return screenMap.UVNormalized(ScreenLocation.Value);
- }
- else
- {
- return null;
- }
- }
- }
- // 范围在摄像机的Size内
- public Vector2? CameraLocation
- {
- get
- {
- if (ScreenLocation.HasValue)
- {
- return screenMap.TransformToCamera(ScreenLocation.Value);
- }
- else
- return null;
- }
- }
- public Vector2? Predict { get; set; } // 为null时代表未初始化
- public InfraredMatch Match { get; private set; }
- public bool Disappear;
- //PixelSpotArea verifyArea;
- int verifyFailLimit;
- List<PixelSpotArea> spots;
- SimpleLocationEstimation estimation;
- Vector2? ScreenLocation;
- ScreenMap screenMap;
- public InfraredSpot(ScreenMap screenMap, InfraredMatch match)
- {
- this.screenMap = screenMap;
- Match = match;
- spots = new List<PixelSpotArea>();
- Reset();
- }
- public void Reset()
- {
- spots.Clear();
- estimation = new SimpleLocationEstimation(0.5f);
- ScreenLocation = null;
- Predict = null;
- Disappear = false;
- //verifyArea = null;
- verifyFailLimit = MaxVerifyFailLimit;
- }
- public bool Verify(List<PixelSpotArea> areas, Dictionary<InfraredMatch, PixelSpotArea> matchedArea)
- {
- if (Predict == null) // 未初始化
- return false;
- PixelSpotArea select = null;
- var minLength = float.MaxValue;
- var predict = Predict.Value;
- var refPoint = (predict + spots.Last().Centroid) / 2; // 用预测点和最后一个点的中点来判断是否追踪到
- foreach (var i in areas)
- {
- var len = (i.Centroid - refPoint).magnitude;
- if (len < MinVerifyLength)
- {
- if (len < minLength) // 找到追踪到的,并且距离最近的spot
- {
- select = i;
- minLength = len;
- }
- }
- }
- if (select == null)
- {
- //Debug.Log(verifyFailLimit);
- verifyFailLimit--;
- if (verifyFailLimit == 0)
- Reset();
- return false;
- }
- //verifyArea = select;
- matchedArea[Match] = select;
- return true;
- }
- //public void UpdateByVerifyArea()
- //{
- // Update(verifyArea);
- //}
- // 为null时采用预测点
- public void Update(PixelSpotArea area)
- {
- if (area == null)
- {
- //throw new System.Exception("[InfraredSpot] Update Wrong");
- UpdateByPredict();
- return;
- }
- var predict = estimation.Update(area.Centroid);
- //ScreenLocation = area.Center;
- ScreenLocation = area.Centroid * 0.8f + predict * 0.2f;
- spots.Add(area);
- if (spots.Count > 15)
- {
- Predict = predict;
- spots.RemoveAt(0);
- }
- }
- void UpdateByPredict()
- {
- if (spots.Count != 0)
- {
- if (Predict == null) // 还未初始化,直接Reset
- Reset();
- else
- {
- // 采用预测点,但超出屏幕则Reset
- if (screenMap.UVInScreen(Predict.Value))
- {
- ScreenLocation = Predict;
- var newP = estimation.Update(Predict.Value);
- Predict = newP;
- }
- else
- Reset();
- }
- }
- }
- }
- }
|