fixes for noise

This commit is contained in:
Boki 2026-02-13 14:35:46 -05:00
parent d2dab86544
commit b9b9a41c3c
3 changed files with 61 additions and 71 deletions

View file

@ -33,6 +33,17 @@ public class WorldMap : IDisposable
var sw = Stopwatch.StartNew();
_frameCount++;
// Noise gate: skip frames with too many wall pixels (waypoint glow, effects)
var wallPixels = Cv2.CountNonZero(wallMask);
var totalPixels = wallMask.Width * wallMask.Height;
var density = (double)wallPixels / totalPixels;
if (density > _config.WallMaxDensity)
{
Log.Information("Noise gate: {Density:P1} wall density ({Pixels} px), skipping ({Ms:F1}ms)",
density, wallPixels, sw.Elapsed.TotalMilliseconds);
return _position;
}
// Frame deduplication: skip if minimap hasn't scrolled yet
if (_prevWallMask != null && _frameCount > 1)
{
@ -173,27 +184,42 @@ public class WorldMap : IDisposable
var confRoi = new Mat(_confidence, dstRect);
var confInc = (short)_config.ConfidenceInc;
var confDec = (short)_config.ConfidenceDec;
var confThreshold = (short)_config.ConfidenceThreshold;
var confMax = (short)_config.ConfidenceMax;
// Only increment confidence for wall pixels. Don't decay on non-wall pixels because
// temporal smoothing (3/5 vote) kills walls during movement — the minimap scrolls so
// wall pixels shift across frames and fail the vote. "Not wall" in the smoothed mat
// during movement means "couldn't confirm" not "definitely not a wall".
// Wall pixels: increase confidence. Non-wall pixels in visible area: decay confidence.
// Real walls accumulate high confidence (40) and survive brief non-confirmation during
// movement. Transient noise (waypoint glow, effects) only reaches moderate confidence
// and gets removed as it decays.
for (var row = 0; row < h; row++)
for (var col = 0; col < w; col++)
{
var srcVal = srcRoi.At<byte>(row, col);
if (srcVal != (byte)MapCell.Wall) continue;
var conf = confRoi.At<short>(row, col);
conf = boosted
? confMax
: Math.Min((short)(conf + confInc), confMax);
if (srcVal == (byte)MapCell.Wall)
{
conf = boosted
? confMax
: Math.Min((short)(conf + confInc), confMax);
}
else if (conf > 0)
{
// Visible area, not a wall → slow decay
conf = Math.Max((short)(conf - confDec), (short)0);
}
else
{
continue; // nothing to update
}
confRoi.Set(row, col, conf);
if (conf >= confThreshold)
dstRoi.Set(row, col, (byte)MapCell.Wall);
else if (dstRoi.At<byte>(row, col) == (byte)MapCell.Wall)
dstRoi.Set(row, col, (byte)MapCell.Explored); // lost confidence → demote
}
// Mark explored area: circle around player, only overwrite Unknown