|
|
@@ -87,6 +87,9 @@ namespace o0.Project
|
|
|
|
|
|
public void SetScreenQuad(QuadrilateralInCamera quad) => Screen.QuadInCamera = quad;
|
|
|
|
|
|
+ // 上一次半自动识别的情况,false代表这条边识别失败,线段顺序: 下、右、上、左
|
|
|
+ public bool[] LastQuadSemiAutoState;
|
|
|
+
|
|
|
public event Action OnLocateScreenEnter;
|
|
|
public event Action OnLocateScreenEnd;
|
|
|
public bool bStartLocateScreen { get; set; } = false;//是否进行捕获
|
|
|
@@ -146,7 +149,8 @@ namespace o0.Project
|
|
|
/// 初始化了两个数据 capture 和 delay
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
- public bool isInitLocateScreen() {
|
|
|
+ public bool isInitLocateScreen()
|
|
|
+ {
|
|
|
return capture != 0 && delay != 0;
|
|
|
}
|
|
|
|
|
|
@@ -167,28 +171,28 @@ namespace o0.Project
|
|
|
new QuadrilateralInCamera(quad, images[0].Size().o0Vector()));
|
|
|
|
|
|
// 透视变换
|
|
|
-// var srcWidth = LocateLightedRedTex.width;
|
|
|
-// var transformWidth = (int)((quad.B.x - quad.A.x + quad.D.x - quad.C.x) / 2);
|
|
|
-// var transformHeight = (int)((quad.C.y - quad.A.y + quad.D.y - quad.B.y) / 2);
|
|
|
-// var transformTex = new Texture2D(transformWidth, transformHeight);
|
|
|
-// var pt = new ZIMPerspectiveTransform(new OrdinalQuadrilateral(new Vector(0, 0), new Vector(transformWidth, 0), new Vector(0, transformHeight), new Vector(transformWidth, transformHeight)), quad);
|
|
|
-// var dstPixel = new UnityEngine.Color[transformWidth * transformHeight];
|
|
|
-// var srcPixel = LocateLightedRedTex.GetPixels();
|
|
|
-// Parallel.For(0, transformWidth, (x) =>
|
|
|
-// {
|
|
|
-// for (int y = 0; y < transformHeight; y++)
|
|
|
-// {
|
|
|
-// var index = y * transformWidth + x;
|
|
|
-// var sampleCoord = pt.TransformRound(x, y);
|
|
|
-// dstPixel[index] = srcPixel[sampleCoord.y * srcWidth + sampleCoord.x];
|
|
|
-// }
|
|
|
-// });
|
|
|
-// transformTex.SetPixels(dstPixel);
|
|
|
-// transformTex.Apply();
|
|
|
-// //ScreenLocate.DebugTexture(1, transformTex);
|
|
|
-//#if (!NDEBUG && DEBUG && ENABLE_LOG)
|
|
|
-// Console.WriteLine($"{TAG} ScreenLocate.DebugTexture 1:{transformTex.GetNativeTexturePtr()}");
|
|
|
-//#endif
|
|
|
+ // var srcWidth = LocateLightedRedTex.width;
|
|
|
+ // var transformWidth = (int)((quad.B.x - quad.A.x + quad.D.x - quad.C.x) / 2);
|
|
|
+ // var transformHeight = (int)((quad.C.y - quad.A.y + quad.D.y - quad.B.y) / 2);
|
|
|
+ // var transformTex = new Texture2D(transformWidth, transformHeight);
|
|
|
+ // var pt = new ZIMPerspectiveTransform(new OrdinalQuadrilateral(new Vector(0, 0), new Vector(transformWidth, 0), new Vector(0, transformHeight), new Vector(transformWidth, transformHeight)), quad);
|
|
|
+ // var dstPixel = new UnityEngine.Color[transformWidth * transformHeight];
|
|
|
+ // var srcPixel = LocateLightedRedTex.GetPixels();
|
|
|
+ // Parallel.For(0, transformWidth, (x) =>
|
|
|
+ // {
|
|
|
+ // for (int y = 0; y < transformHeight; y++)
|
|
|
+ // {
|
|
|
+ // var index = y * transformWidth + x;
|
|
|
+ // var sampleCoord = pt.TransformRound(x, y);
|
|
|
+ // dstPixel[index] = srcPixel[sampleCoord.y * srcWidth + sampleCoord.x];
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // transformTex.SetPixels(dstPixel);
|
|
|
+ // transformTex.Apply();
|
|
|
+ // //ScreenLocate.DebugTexture(1, transformTex);
|
|
|
+ //#if (!NDEBUG && DEBUG && ENABLE_LOG)
|
|
|
+ // Console.WriteLine($"{TAG} ScreenLocate.DebugTexture 1:{transformTex.GetNativeTexturePtr()}");
|
|
|
+ //#endif
|
|
|
}
|
|
|
|
|
|
//times.Add(watch.ElapsedMilliseconds);
|
|
|
@@ -669,7 +673,7 @@ namespace o0.Project
|
|
|
sw.Start();
|
|
|
|
|
|
//读取数据
|
|
|
- if (debugImages != null && debugImages.Count != 0)
|
|
|
+ if (debugImages != null && debugImages.Count != 0)
|
|
|
{
|
|
|
foreach (var i in debugImages)
|
|
|
{
|
|
|
@@ -693,7 +697,7 @@ namespace o0.Project
|
|
|
var whitePixel = new UnityEngine.Color[Size.x * Size.y];
|
|
|
Parallel.For(0, Size.x, x =>
|
|
|
{
|
|
|
- for (int y = 0; y < Size.y; y++)
|
|
|
+ for (int y = 0; y < Size.y; y++)
|
|
|
{
|
|
|
var i = y * Size.x + x;
|
|
|
var d = ScreenWhiteTexture[i] - ScreenBlackTexture[i];
|
|
|
@@ -754,7 +758,7 @@ namespace o0.Project
|
|
|
|
|
|
#region 半自动识别
|
|
|
List<LineIdentified> LineIdentifiedSemiAuto = new List<LineIdentified>(); // 线段顺序: 下、右、上、左
|
|
|
- bool[] newLines = new bool[4] { true, true, true, true };
|
|
|
+ LastQuadSemiAutoState = new bool[4] { true, true, true, true };
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
{
|
|
|
if (quadLinesSemiAuto[i] != null)
|
|
|
@@ -762,7 +766,7 @@ namespace o0.Project
|
|
|
else if (manualLines != null)
|
|
|
{
|
|
|
LineIdentifiedSemiAuto.Add(manualLines[i]);
|
|
|
- newLines[i] = false;
|
|
|
+ LastQuadSemiAutoState[i] = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -788,7 +792,8 @@ namespace o0.Project
|
|
|
{
|
|
|
Debug.Log("<color=aqua>[ScreenIdentification] 识别到四边形</color>");
|
|
|
quadTemp.Add(QuadSemiAuto.Quad);
|
|
|
- }else if (QuadAuto != null)
|
|
|
+ }
|
|
|
+ else if (QuadAuto != null)
|
|
|
{
|
|
|
Debug.Log("<color=aqua>[ScreenIdentification] 识别到四边形</color>");
|
|
|
quadTemp.Add(QuadAuto.Quad);
|
|
|
@@ -799,7 +804,7 @@ namespace o0.Project
|
|
|
var ScreenQuadMap = new Matrix(Size, Tiling: true); // 识别的到的屏幕四边形(半自动和自动在一张图上)
|
|
|
foreach (var i in LineIdentifiedSemiAuto.Index())
|
|
|
{
|
|
|
- if (newLines[i])
|
|
|
+ if (LastQuadSemiAutoState[i])
|
|
|
o0Extension.DrawLine(ScreenQuadMap, LineIdentifiedSemiAuto[i].DrawLine, (x, y) => 2, new Geometry2D.Float.Vector(0, 10));
|
|
|
else
|
|
|
o0Extension.DrawLine(ScreenQuadMap, LineIdentifiedSemiAuto[i].DrawLine, (x, y) => 1, new Geometry2D.Float.Vector(0, 6), true);
|
|
|
@@ -845,7 +850,7 @@ namespace o0.Project
|
|
|
log += $"\r\n屏幕四边形_手动识别{QuadManual != null}\r\n屏幕四边形_半自动识别{QuadSemiAuto != null}\r\n屏幕四边形_全自动识别{QuadAuto != null}";
|
|
|
Debug.Log(log);
|
|
|
// 是否将图片保存到本地
|
|
|
- if (ScreenLocate.Main.SaveToggle.isOn && ScreenLocate.Main.DebugOnZIMDemo)
|
|
|
+ if (ScreenLocate.Main.SaveToggle?.isOn ?? false && ScreenLocate.Main.DebugOnZIMDemo)
|
|
|
{
|
|
|
var FileDirectory = $"Debug_屏幕定位/";
|
|
|
SaveImages(FileDirectory, log, ScreenLocateTexture, allLinesTex, ChoosableLineTex, ScreenQuad);
|
|
|
@@ -996,24 +1001,26 @@ namespace o0.Project
|
|
|
var quadLinesSemiAuto = new List<(float, LineIdentified)>[4] { new List<(float, LineIdentified)>(), new List<(float, LineIdentified)>(), new List<(float, LineIdentified)>(), new List<(float, LineIdentified)>() };
|
|
|
var quadLinesAuto = new List<(float, LineIdentified)>[4] { new List<(float, LineIdentified)>(), new List<(float, LineIdentified)>(), new List<(float, LineIdentified)>(), new List<(float, LineIdentified)>() };
|
|
|
possibleLines = new List<LineIdentified>();
|
|
|
- manualLines = null;
|
|
|
|
|
|
// 如果已有手动定位数据,根据现有数据筛选线条(半自动)
|
|
|
+ manualLines = null;
|
|
|
if (QuadManual != null)
|
|
|
{
|
|
|
Debug.Log("[IdentifyLineLSD] 根据已有定位数据做筛选");
|
|
|
- var calibration = ScreenLocate.Main.ReDoLocateCalibrationRatio * Size.y;
|
|
|
manualLines = QuadManual.GetLines().Select((i) => new LineIdentified(0, i, 0, 0, true)).ToArray();
|
|
|
-
|
|
|
- var pedals = manualLines.Select((i) => o0Extension.PointPedal(i.Line, avgPoint, out _)).ToArray(); // 当前定位的垂足,下、右、上、左
|
|
|
+ var calibration = ScreenLocate.Main.ReDoLocateCalibrationRatio * Size.y;
|
|
|
+ var avgPointCross = manualLines.Select((i) => i.Line.LineCrossWithPoint(avgPoint)).ToArray(); // 对于平均点的corss值
|
|
|
+ var avgPointPedal = manualLines.Select((i) => o0Extension.PointPedal(i.Line, avgPoint, out _)).ToArray(); // 当前定位的垂足,下、右、上、左
|
|
|
|
|
|
foreach (var line in innerLines)
|
|
|
{
|
|
|
- // 筛选条件:1-梯度方向匹配,2-垂足的距离足够近, 3-新的线段的中点,到旧线段的垂足,要在旧线段内
|
|
|
+ // 筛选条件:1-梯度方向匹配,2-垂足的距离足够近, 3-线段的AB点均在旧线段外部, 4-新的线段的中点,到旧线段的垂足,要在旧线段内
|
|
|
if (isScreenLine(line, out int index))
|
|
|
{
|
|
|
- var distanceToOld = (o0Extension.PointPedal(line.Line, avgPoint, out _) - pedals[index]).Length;
|
|
|
- if (distanceToOld < calibration)
|
|
|
+ var distanceToOld = (o0Extension.PointPedal(line.Line, avgPoint, out _) - avgPointPedal[index]).Length;
|
|
|
+ if (distanceToOld < calibration &&
|
|
|
+ manualLines[index].Line.LineCrossWithPoint(line.Line.A) * avgPointCross[index] <= 0 &&
|
|
|
+ manualLines[index].Line.LineCrossWithPoint(line.Line.B) * avgPointCross[index] <= 0)
|
|
|
{
|
|
|
var middleToOldLine = o0Extension.PointPedal(manualLines[index].Line, (line.Line.A + line.Line.B) / 2, out bool inLineSegment);
|
|
|
if (inLineSegment)
|
|
|
@@ -1029,7 +1036,7 @@ namespace o0.Project
|
|
|
// 全自动
|
|
|
foreach (var line in allLines)
|
|
|
{
|
|
|
- if (isScreenLine(line , out int index))
|
|
|
+ if (isScreenLine(line, out int index))
|
|
|
{
|
|
|
if (line.Batch < 1) // 全自动只处理第一张图,默认是色差图
|
|
|
{
|
|
|
@@ -1050,7 +1057,7 @@ namespace o0.Project
|
|
|
return (resultSemiAuto.ToList(), resultAuto.ToList());
|
|
|
}
|
|
|
|
|
|
- void SaveImages(string FileDirectory, string log,
|
|
|
+ void SaveImages(string FileDirectory, string log,
|
|
|
Texture2D ScreenLocateTex, Texture2D allLinesTex, Texture2D ChoosableLineTex, Texture2D ScreenQuadTex)
|
|
|
{
|
|
|
if (!Directory.Exists(FileDirectory))
|