|
|
@@ -134,8 +134,8 @@ namespace ZIM
|
|
|
(int x, int y) rectMin = ((int)rect.min.x / SamplingScale, (int)rect.min.y / SamplingScale);
|
|
|
(int x, int y) rectMax = ((int)rect.max.x / SamplingScale, (int)rect.max.y / SamplingScale);
|
|
|
|
|
|
- var spotPoint = new List<Vector2>(200); // 预估的初始容量
|
|
|
- var brightPoint = new List<Vector2>(1000);
|
|
|
+ var spotPoint = new List<Vector2>(100); // 预估的初始容量
|
|
|
+ var brightPoint = new List<Vector2>(500);
|
|
|
|
|
|
Parallel.For(rectMin.x, rectMax.x, (i) =>
|
|
|
{
|
|
|
@@ -172,14 +172,15 @@ namespace ZIM
|
|
|
|
|
|
//if (ScreenLocate.Main.DebugOnZIMDemo)
|
|
|
{
|
|
|
- if (spotPoint.Count > 500) // 如果亮点太多,控制亮点数量在500左右
|
|
|
+ float maxPoints = 200; // 如果亮点太多,通过间隔采样控制亮点在一定数量以内
|
|
|
+ if (spotPoint.Count > maxPoints)
|
|
|
{
|
|
|
- SamplingScale = (int)Math.Ceiling(SamplingScale * Math.Sqrt(spotPoint.Count / 500.0));
|
|
|
+ SamplingScale = (int)Math.Ceiling(SamplingScale * Math.Sqrt(spotPoint.Count / maxPoints));
|
|
|
return new List<ISpotArea>();
|
|
|
}
|
|
|
- else if (SamplingScale > 1 && spotPoint.Count < 100)
|
|
|
+ else if (SamplingScale > 1 && spotPoint.Count < maxPoints * 0.2f)
|
|
|
{
|
|
|
- SamplingScale = Math.Max((int)Math.Ceiling(SamplingScale * Math.Sqrt(spotPoint.Count / 200.0)), 1);
|
|
|
+ SamplingScale = Math.Max((int)Math.Ceiling(SamplingScale * Math.Sqrt(spotPoint.Count / maxPoints * 3)), 1);
|
|
|
return new List<ISpotArea>();
|
|
|
}
|
|
|
}
|
|
|
@@ -187,72 +188,72 @@ namespace ZIM
|
|
|
//times.Add(watch.ElapsedMilliseconds);
|
|
|
//UnityEngine.Debug.Log("time1: " + (times[times.Count - 1] - times[times.Count - 2]));
|
|
|
|
|
|
- // 所有点映射到屏幕空间
|
|
|
- Parallel.For(0, spotPoint.Count, (i) => spotPoint[i] = screenIdentification.Screen.TransformToScreen(spotPoint[i]));
|
|
|
- Parallel.For(0, brightPoint.Count, (i) => brightPoint[i] = screenIdentification.Screen.TransformToScreen(brightPoint[i]));
|
|
|
+ //Parallel.For(0, spotPoint.Count, (i) => spotPoint[i] = screenIdentification.Screen.TransformToScreen(spotPoint[i]));
|
|
|
+ //Parallel.For(0, brightPoint.Count, (i) => brightPoint[i] = screenIdentification.Screen.TransformToScreen(brightPoint[i]));
|
|
|
|
|
|
// 筛掉屏幕外的点
|
|
|
- var temp0 = new List<Vector2>(spotPoint.Count);
|
|
|
- var temp1 = new List<Vector2>(spotPoint.Count);
|
|
|
- foreach (var p in spotPoint)
|
|
|
+ if (screenIdentification.Screen.Active)
|
|
|
{
|
|
|
- if (screenIdentification.Screen.UVInScreen(p))
|
|
|
- temp0.Add(p);
|
|
|
- }
|
|
|
- foreach (var p in brightPoint)
|
|
|
- {
|
|
|
- if (screenIdentification.Screen.UVInScreen(p))
|
|
|
- temp1.Add(p);
|
|
|
+ var temp0 = new List<Vector2>(spotPoint.Count);
|
|
|
+ var temp1 = new List<Vector2>(spotPoint.Count);
|
|
|
+ foreach (var p in spotPoint)
|
|
|
+ {
|
|
|
+ var pS = screenIdentification.Screen.TransformToScreen(p);
|
|
|
+ if (screenIdentification.Screen.UVInScreen(pS))
|
|
|
+ temp0.Add(p);
|
|
|
+ }
|
|
|
+ foreach (var p in brightPoint)
|
|
|
+ {
|
|
|
+ var pS = screenIdentification.Screen.TransformToScreen(p);
|
|
|
+ if (screenIdentification.Screen.UVInScreen(pS))
|
|
|
+ temp1.Add(p);
|
|
|
+ }
|
|
|
+ spotPoint = temp0;
|
|
|
+ brightPoint = temp1;
|
|
|
}
|
|
|
- spotPoint = temp0;
|
|
|
- brightPoint = temp1;
|
|
|
|
|
|
+ //times.Add(watch.ElapsedMilliseconds);
|
|
|
+ //UnityEngine.Debug.Log("time2: " + (times[times.Count - 1] - times[times.Count - 2]));
|
|
|
+
|
|
|
+ // 聚类算法,得到结果
|
|
|
if (spotPoint.Count > 0)
|
|
|
{
|
|
|
- //times.Add(watch.ElapsedMilliseconds);
|
|
|
- //UnityEngine.Debug.Log("time2: " + (times[times.Count - 1] - times[times.Count - 2]));
|
|
|
-
|
|
|
var db = Dbscan.Run(spotPoint, ZIM.Unity.ZIMMath.LengthManhattan, SamplingScale, 4);
|
|
|
var spotArea = DbscanToSpotAreas(db, brightPoint);
|
|
|
//var spotArea = PixelSpotArea.Cluster(spotPoint, brightPoint, screenIdentification.Screen.UVInScreen);
|
|
|
|
|
|
- if (ScreenLocate.Main.DebugOnZIMDemo)
|
|
|
- DebugAreas(spotArea);
|
|
|
-
|
|
|
-
|
|
|
- //Debug.Log("db: " + db.Clusters.Count);
|
|
|
- //Debug.Log("db noise: " + db.Noise.Count);
|
|
|
- //foreach (var i in spotArea)
|
|
|
- //{
|
|
|
- // Debug.Log("i.Radius" + i.Radius);
|
|
|
- //}
|
|
|
-
|
|
|
//times.Add(watch.ElapsedMilliseconds);
|
|
|
//UnityEngine.Debug.Log("time3: " + (times[times.Count - 1] - times[times.Count - 2]));
|
|
|
|
|
|
- return spotArea;
|
|
|
-
|
|
|
- //半径再按透视修正一遍,降低一点常规角度下反射的影响
|
|
|
- //foreach (var i in spotArea)
|
|
|
- //{
|
|
|
- // var r0 = i.Radius / 2 / mCameraInfo.CurrentWidth;
|
|
|
- // var center = i.Centroid;
|
|
|
- // var offset1 = center + new Vector2(i.Radius / 2, 0);
|
|
|
- // var offset2 = center - new Vector2(i.Radius / 2, 0);
|
|
|
- // var offset3 = center + new Vector2(0, i.Radius / 2);
|
|
|
- // var offset4 = center - new Vector2(0, i.Radius / 2);
|
|
|
- // var transR = ((screenIdentification.Screen.TransformToScreen(offset1) - screenIdentification.Screen.TransformToScreen(offset2)).magnitude +
|
|
|
- // (screenIdentification.Screen.TransformToScreen(offset3) - screenIdentification.Screen.TransformToScreen(offset4)).magnitude) / 4;
|
|
|
- // var r1 = transR / screenIdentification.Screen.UVSize.x;
|
|
|
- // //Debug.Log(r1 / r0);
|
|
|
- // i.Radius *= (float)Math.Pow(r1 / r0, 2); // 摄像机位置不同参数也可能不同
|
|
|
- //}
|
|
|
+ //半径和中心按透视调整
|
|
|
+ if (screenIdentification.Screen.Active)
|
|
|
+ {
|
|
|
+ foreach (var i in spotArea)
|
|
|
+ {
|
|
|
+ var center = i.Centroid;
|
|
|
+ var offset1 = center + new Vector2(i.Radius, 0);
|
|
|
+ var offset2 = center - new Vector2(i.Radius, 0);
|
|
|
+ var offset3 = center + new Vector2(0, i.Radius);
|
|
|
+ var offset4 = center - new Vector2(0, i.Radius);
|
|
|
+ var transC = screenIdentification.Screen.TransformToScreen(i.Centroid);
|
|
|
+ var transR = ((screenIdentification.Screen.TransformToScreen(offset1) - screenIdentification.Screen.TransformToScreen(offset2)).magnitude +
|
|
|
+ (screenIdentification.Screen.TransformToScreen(offset3) - screenIdentification.Screen.TransformToScreen(offset4)).magnitude) / 4;
|
|
|
+ //var r0 = i.Radius / mCameraInfo.CurrentWidth;
|
|
|
+ //var r1 = transR / screenIdentification.Screen.UVSize.x;
|
|
|
+ //i.Radius *= (float)Math.Pow(r1 / r0, 2); // 摄像机位置不同参数也可能不同
|
|
|
+
|
|
|
+ i.Centroid = transC;
|
|
|
+ i.Radius = transR;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- //if (spotArea.Count == 1)
|
|
|
- //Debug.Log($"{spotArea[0].MaxRadius}");
|
|
|
+ //times.Add(watch.ElapsedMilliseconds);
|
|
|
+ //UnityEngine.Debug.Log("time4: " + (times[times.Count - 1] - times[times.Count - 2]));
|
|
|
|
|
|
- //return spotArea;
|
|
|
+ if (ScreenLocate.Main.DebugOnZIMDemo)
|
|
|
+ DebugAreas(spotArea);
|
|
|
|
|
|
+ return spotArea;
|
|
|
|
|
|
//// 排序亮区
|
|
|
//spotArea.Sort((a, b) => b.MaxRadius.CompareTo(a.MaxRadius));
|