added filter for text
This commit is contained in:
parent
dab5735c80
commit
7fd80b1645
3 changed files with 36 additions and 8 deletions
|
|
@ -103,9 +103,23 @@ public class MinimapCapture : IDisposable
|
|||
using var highS = new Mat();
|
||||
Cv2.Threshold(satChan, highS, _config.WallMinSat, 255, ThresholdTypes.Binary);
|
||||
|
||||
// Exclude nameplate text: very bright (V > 230) AND unsaturated (S < 40)
|
||||
// Nameplates are pure white text; minimap walls are colored (have saturation)
|
||||
using var nameplateBright = new Mat();
|
||||
Cv2.Threshold(valueChan, nameplateBright, _config.NameplateMinValue, 255, ThresholdTypes.Binary);
|
||||
using var nameplateLowSat = new Mat();
|
||||
Cv2.Threshold(satChan, nameplateLowSat, _config.NameplateMaxSat, 255, ThresholdTypes.BinaryInv);
|
||||
using var nameplateMask = new Mat();
|
||||
Cv2.BitwiseAnd(nameplateBright, nameplateLowSat, nameplateMask);
|
||||
|
||||
var wallMask = new Mat();
|
||||
Cv2.BitwiseOr(highV, highS, wallMask);
|
||||
|
||||
// Subtract nameplates
|
||||
using var notNameplate = new Mat();
|
||||
Cv2.BitwiseNot(nameplateMask, notNameplate);
|
||||
Cv2.BitwiseAnd(wallMask, notNameplate, wallMask);
|
||||
|
||||
// Dilate to connect wall line fragments
|
||||
using var kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3, 3));
|
||||
Cv2.Dilate(wallMask, wallMask, kernel);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,10 @@ public class MinimapConfig
|
|||
public int WallMinValue { get; set; } = 200;
|
||||
public int WallMinSat { get; set; } = 150;
|
||||
|
||||
// Nameplate filter: exclude bright + unsaturated pixels (white text like "SALVAGE BENCH")
|
||||
public int NameplateMinValue { get; set; } = 230;
|
||||
public int NameplateMaxSat { get; set; } = 40;
|
||||
|
||||
// Connected components: minimum area to keep (kills speckle)
|
||||
public int WallMinArea { get; set; } = 30;
|
||||
|
||||
|
|
@ -98,7 +102,7 @@ public class MinimapConfig
|
|||
public int MatchSearchRadius { get; set; } = 100;
|
||||
|
||||
// Template matching: minimum correlation confidence to accept a match
|
||||
public double MatchConfidence { get; set; } = 0.3;
|
||||
public double MatchConfidence { get; set; } = 0.15;
|
||||
|
||||
// Wall confidence (canvas-level): per-pixel counters to filter transient noise
|
||||
public int ConfidenceInc { get; set; } = 3;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public class WorldMap : IDisposable
|
|||
private readonly Mat _confidence; // CV_16SC1: per-pixel wall confidence counter
|
||||
private MapPosition _position;
|
||||
private int _frameCount;
|
||||
private int _consecutiveMatchFails;
|
||||
private Mat? _prevWallMask; // for frame deduplication
|
||||
|
||||
public MapPosition Position => _position;
|
||||
|
|
@ -68,11 +69,13 @@ public class WorldMap : IDisposable
|
|||
|
||||
if (matched == null)
|
||||
{
|
||||
Log.Information("MatchAndStitch: dedup={Dedup:F1}ms match={Match:F1}ms (FAILED) total={Total:F1}ms",
|
||||
dedupMs, matchMs, sw.Elapsed.TotalMilliseconds);
|
||||
return _position; // skip stitching entirely on failed match
|
||||
_consecutiveMatchFails++;
|
||||
Log.Information("MatchAndStitch: dedup={Dedup:F1}ms match={Match:F1}ms (FAILED x{Fails}) total={Total:F1}ms",
|
||||
dedupMs, matchMs, _consecutiveMatchFails, sw.Elapsed.TotalMilliseconds);
|
||||
return _position; // don't stitch — wrong position would corrupt the canvas
|
||||
}
|
||||
|
||||
_consecutiveMatchFails = 0;
|
||||
_position = matched;
|
||||
var stitchStart = sw.Elapsed.TotalMilliseconds;
|
||||
StitchWithConfidence(classifiedMat, _position, boosted: false);
|
||||
|
|
@ -115,8 +118,13 @@ public class WorldMap : IDisposable
|
|||
|
||||
// Check if canvas has enough walls to match against
|
||||
var canvasWallCount = Cv2.CountNonZero(canvasWalls);
|
||||
var frameWallCount = Cv2.CountNonZero(wallMask);
|
||||
if (canvasWallCount < 50)
|
||||
{
|
||||
Log.Information("Match fail: too few canvas walls ({CanvasWalls}) frame walls={FrameWalls}",
|
||||
canvasWallCount, frameWallCount);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Template match: find where frame's walls best align with canvas walls
|
||||
using var result = new Mat();
|
||||
|
|
@ -125,7 +133,8 @@ public class WorldMap : IDisposable
|
|||
|
||||
if (maxVal < _config.MatchConfidence)
|
||||
{
|
||||
Log.Debug("Map match low confidence: {Conf:F3}", maxVal);
|
||||
Log.Information("Match fail: low confidence {Conf:F3} (need {Min:F2}) canvas={CanvasWalls} frame={FrameWalls}",
|
||||
maxVal, _config.MatchConfidence, canvasWallCount, frameWallCount);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -134,8 +143,8 @@ public class WorldMap : IDisposable
|
|||
var matchX = sx0 + maxLoc.X + frameSize / 2.0;
|
||||
var matchY = sy0 + maxLoc.Y + frameSize / 2.0;
|
||||
|
||||
Log.Debug("Map match: ({X:F1}, {Y:F1}) conf={Conf:F3} walls={Walls}",
|
||||
matchX, matchY, maxVal, canvasWallCount);
|
||||
Log.Debug("Map match: ({X:F1}, {Y:F1}) conf={Conf:F3} canvas={CanvasWalls} frame={FrameWalls}",
|
||||
matchX, matchY, maxVal, canvasWallCount, frameWallCount);
|
||||
|
||||
return new MapPosition(matchX, matchY);
|
||||
}
|
||||
|
|
@ -177,7 +186,7 @@ public class WorldMap : IDisposable
|
|||
if (srcVal == (byte)MapCell.Wall)
|
||||
{
|
||||
if (boosted)
|
||||
conf = confThreshold; // warmup: immediately at threshold
|
||||
conf = confMax; // warmup: max confidence so walls survive initial movement
|
||||
else
|
||||
conf = Math.Min((short)(conf + confInc), confMax);
|
||||
}
|
||||
|
|
@ -312,6 +321,7 @@ public class WorldMap : IDisposable
|
|||
_prevWallMask = null;
|
||||
_position = new MapPosition(_config.CanvasSize / 2.0, _config.CanvasSize / 2.0);
|
||||
_frameCount = 0;
|
||||
_consecutiveMatchFails = 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue