|
|
@@ -131,7 +131,7 @@ namespace o0.Project
|
|
|
areaSelected = -1;
|
|
|
quadTemp.Clear();
|
|
|
sumTemp.Clear();
|
|
|
- ScreenLocate.Main.DebugScreenImages.Clear();
|
|
|
+ //ScreenLocate.Main.DebugScreenImages.Clear();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -1003,8 +1003,7 @@ namespace o0.Project
|
|
|
var gM = ScreenGrad(line);
|
|
|
float e = (float)Math.Sqrt(Math.Ceiling(line.Line.Length / minLength)); // 长度系数,筛选时梯度更大、长度更长的线段更优
|
|
|
float d = (1.3f - distanceRatio) / 0.3f; // 距离系数,距离越近,系数越大
|
|
|
-
|
|
|
- line.ZIMGradient = e * d * gM; // 记录一下综合梯度,全自动新增的功能会二次使用
|
|
|
+ line.ZIMGradient = e * d * gM; // 记录一下综合梯度,新增的识别黑边功能会二次使用
|
|
|
return line.ZIMGradient;
|
|
|
}
|
|
|
// 根据线段梯度的角度,判断是不是屏幕的边,index代表是哪条边(顺序是: 下、右、上、左)
|
|
|
@@ -1037,6 +1036,7 @@ namespace o0.Project
|
|
|
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>();
|
|
|
|
|
|
+ #region 半自动(利用手动数据)
|
|
|
// 如果已有手动定位数据,根据现有数据筛选线条(半自动)
|
|
|
manualLines = null;
|
|
|
if (QuadManual != null)
|
|
|
@@ -1050,7 +1050,7 @@ namespace o0.Project
|
|
|
foreach (var line in innerLines)
|
|
|
{
|
|
|
// 筛选条件:1-梯度方向匹配,2-垂足的距离足够近, 3-线段的AB点均在旧线段外部, 4-新的线段的中点,到旧线段的垂足,要在旧线段内
|
|
|
- if (line.ScreenLineIndex >= 0)
|
|
|
+ if (line.ScreenLineIndex >= 0)
|
|
|
{
|
|
|
var distanceToOld = (o0Extension.PointPedal(line.Line, avgPoint, out _) - avgPointPedal[line.ScreenLineIndex]).Length;
|
|
|
if (distanceToOld < calibration &&
|
|
|
@@ -1067,7 +1067,23 @@ namespace o0.Project
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ // 获得结果
|
|
|
+ var resultSemiAuto = new LineIdentified[4];
|
|
|
+ var resultSemiAutoPedal = new Vector[4]; // 用于找平行线
|
|
|
+ for (int i = 0; i < 4; i++)
|
|
|
+ {
|
|
|
+ resultSemiAuto[i] = quadLinesSemiAuto[i].Max((a, b) => a.Item1.CompareTo(b.Item1)).Item2;
|
|
|
+ if (resultSemiAuto[i] != null)
|
|
|
+ resultSemiAutoPedal[i] = o0Extension.PointPedal(resultSemiAuto[i].Line, avgPoint, out _);
|
|
|
+ }
|
|
|
+ // 新增功能(解决黑边问题):根据 result 再找平行线,判断是否替换(1-在 result 内部,且离中点最近,2-接近平行)
|
|
|
+ UpdateResultlines(resultSemiAuto, FindInterLinePair(
|
|
|
+ (i) => true,
|
|
|
+ GetInterSelectableLines(quadLinesSemiAuto, resultSemiAuto, resultSemiAutoPedal, avgPoint)));
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 全自动
|
|
|
// 全自动
|
|
|
foreach (var line in innerLines)
|
|
|
{
|
|
|
@@ -1076,57 +1092,60 @@ namespace o0.Project
|
|
|
quadLinesAuto[line.ScreenLineIndex].Add((estimateGradient(line, 1), line));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 获得半自动和全自动的结果
|
|
|
- var resultSemiAuto = new LineIdentified[4];
|
|
|
+ // 获得结果
|
|
|
var resultAuto = new LineIdentified[4];
|
|
|
- var resultAutoPedal = new Vector[4]; // 用于找全自动的平行线
|
|
|
+ var resultAutoPedal = new Vector[4]; // 用于找平行线
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
{
|
|
|
- if (quadLinesSemiAuto[i].Count > 0)
|
|
|
- resultSemiAuto[i] = quadLinesSemiAuto[i].Max((a, b) => a.Item1.CompareTo(b.Item1)).Item2;
|
|
|
- if (quadLinesAuto[i].Count > 0)
|
|
|
- {
|
|
|
- resultAuto[i] = quadLinesAuto[i].Max((a, b) => a.Item1.CompareTo(b.Item1)).Item2;
|
|
|
- if (resultAuto[i] != null)
|
|
|
- resultAutoPedal[i] = o0Extension.PointPedal(resultAuto[i].Line, avgPoint, out _);
|
|
|
- }
|
|
|
+ resultAuto[i] = quadLinesAuto[i].Max((a, b) => a.Item1.CompareTo(b.Item1)).Item2;
|
|
|
+ if (resultAuto[i] != null)
|
|
|
+ resultAutoPedal[i] = o0Extension.PointPedal(resultAuto[i].Line, avgPoint, out _);
|
|
|
}
|
|
|
+ // 新增功能(解决黑边问题):根据 resultAuto 再找平行线,判断是否替换(1-在 result 内部,且离中点最近,2-接近平行,3-LineGuess判断是直线)
|
|
|
+ UpdateResultlines(resultAuto, FindInterLinePair(
|
|
|
+ new LineGuess(screenLocateMatList, gradientLength * 2, minLength).GuessIsLine,
|
|
|
+ GetInterSelectableLines(quadLinesAuto, resultAuto, resultAutoPedal, avgPoint)));
|
|
|
+ #endregion
|
|
|
|
|
|
- // 新增功能(全自动,为了解决黑边问题):根据 resultAuto 再找平行线,判断是否替换(1-在 resultAuto 内部,2-接近平行,3-LineGuess判断是直线)
|
|
|
- // 半自动不增加这个功能,直接通过增加到手动数据的距离阈值来解决黑边问题
|
|
|
- var interSelectable = new List<LineIdentified>();
|
|
|
- foreach (var line in innerLines)
|
|
|
+ return (resultSemiAuto.ToList(), resultAuto.ToList());
|
|
|
+ }
|
|
|
+
|
|
|
+ List<LineIdentified> GetInterSelectableLines(List<(float, LineIdentified)>[] quadLines, LineIdentified[] resultLines, Vector[] resultPedal, Vector avgPoint)
|
|
|
+ {
|
|
|
+ var result = new List<LineIdentified>();
|
|
|
+ foreach (var ql in quadLines)
|
|
|
{
|
|
|
- if (line.ScreenLineIndex >= 0 && line.Batch < 1)
|
|
|
+ foreach (var (_, line) in ql)
|
|
|
{
|
|
|
- if (line != resultAuto[line.ScreenLineIndex])
|
|
|
+ if (line != resultLines[line.ScreenLineIndex])
|
|
|
{
|
|
|
var pedal = o0Extension.PointPedal(line.Line, avgPoint, out _);
|
|
|
var a0 = pedal - avgPoint;
|
|
|
var a0L = a0.Length;
|
|
|
line.DistanceToMiddle = a0L;
|
|
|
- var a1 = resultAutoPedal[line.ScreenLineIndex] - avgPoint;
|
|
|
+ var a1 = resultPedal[line.ScreenLineIndex] - avgPoint;
|
|
|
var a1L = a1.Length;
|
|
|
if (a0L < a1L)
|
|
|
{
|
|
|
var dotN = a0.Dot(a1) / a0L / a1L;
|
|
|
- if (Math.Abs(dotN - 1) < 0.001) // 接近平行即可
|
|
|
- interSelectable.Add(line);
|
|
|
+ if (Math.Abs(dotN - 1) < 0.002) // 接近平行即可
|
|
|
+ result.Add(line);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- var (interA, interB) = FindInterLinePair(new LineGuess(screenLocateMatList, gradientLength * 2, minLength), interSelectable, 8);
|
|
|
- if (interA != null) // 替换上一步筛选的结果中的部分边,得到最终的结果
|
|
|
- resultAuto[interA.ScreenLineIndex] = interA;
|
|
|
- if (interB != null)
|
|
|
- resultAuto[interB.ScreenLineIndex] = interB;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- return (resultSemiAuto.ToList(), resultAuto.ToList());
|
|
|
+ void UpdateResultlines(LineIdentified[] result, (LineIdentified a, LineIdentified b) inter)
|
|
|
+ {
|
|
|
+ if (inter.a != null) // 替换上一步筛选的结果中的部分边,得到最终的结果
|
|
|
+ result[inter.a.ScreenLineIndex] = inter.a;
|
|
|
+ if (inter.b != null)
|
|
|
+ result[inter.b.ScreenLineIndex] = inter.b;
|
|
|
}
|
|
|
|
|
|
- (LineIdentified a, LineIdentified b) FindInterLinePair(LineGuess lineGuess, List<LineIdentified> interSelectable, int maxCountToSelect = 12)
|
|
|
+ (LineIdentified a, LineIdentified b) FindInterLinePair(Func<LineIdentified, bool> guessIsLine, List<LineIdentified> interSelectable, int maxCountToSelect = 8)
|
|
|
{
|
|
|
Debug.Log("[ScreenIdentification] selectable inter line count: " + interSelectable.Count);
|
|
|
interSelectable.Sort((a, b) => b.ZIMGradient.CompareTo(a.ZIMGradient));
|
|
|
@@ -1134,7 +1153,7 @@ namespace o0.Project
|
|
|
LineIdentified[] selected = new LineIdentified[4];
|
|
|
foreach (var line in interSelectable)
|
|
|
{
|
|
|
- if (lineGuess.GuessIsLine(line)) // 评价是不是Line, 并且找到离中心点最近的
|
|
|
+ if (guessIsLine(line)) // 评价是不是Line, 并且找到离中心点最近的
|
|
|
{
|
|
|
if (ScreenLocate.Main.DebugOnZIMDemo)
|
|
|
Debug.Log($"[ScreenIdentification] {interSelectable.IndexOf(line)}, guess is line: (index)" + line.ScreenLineIndex);
|