much better

This commit is contained in:
Boki 2026-02-13 15:07:03 -05:00
parent 86c7a31231
commit db37d3c179

View file

@ -34,18 +34,15 @@ public class WorldMap : IDisposable
var sw = Stopwatch.StartNew();
_frameCount++;
// Noise gate: skip frames with too many wall pixels (waypoint glow, effects)
// But NOT during warmup or re-bootstrap — we need to stitch something to get started
var wallPixels = Cv2.CountNonZero(wallMask);
var totalPixels = wallMask.Width * wallMask.Height;
var density = (double)wallPixels / totalPixels;
var isNoisy = density > _config.WallMaxDensity;
var needsBootstrap = _frameCount <= _config.WarmupFrames || _consecutiveMatchFails >= 30;
if (isNoisy && !needsBootstrap)
// Block-based noise filter: zero out 50×50 blocks with >25% wall density
// Removes localized glow (waypoints, effects) while preserving real walls
var cleanFraction = FilterNoisyBlocks(wallMask, classifiedMat);
if (cleanFraction < 0.25 && !needsBootstrap)
{
Log.Information("Noise gate: {Density:P1} wall density ({Pixels} px), skipping ({Ms:F1}ms)",
density, wallPixels, sw.Elapsed.TotalMilliseconds);
Log.Information("Noise filter: {Clean:P0} clean, skipping ({Ms:F1}ms)",
cleanFraction, sw.Elapsed.TotalMilliseconds);
return _position;
}
@ -260,6 +257,46 @@ public class WorldMap : IDisposable
}
}
/// <summary>
/// Zero out 50×50 blocks where wall density exceeds 25%.
/// Modifies wallMask and classifiedMat in-place.
/// Returns fraction of blocks that are clean (0.01.0).
/// </summary>
private static double FilterNoisyBlocks(Mat wallMask, Mat classifiedMat,
int blockSize = 50, double blockMaxDensity = 0.25)
{
var rows = wallMask.Rows;
var cols = wallMask.Cols;
var totalBlocks = 0;
var cleanBlocks = 0;
for (var by = 0; by < rows; by += blockSize)
for (var bx = 0; bx < cols; bx += blockSize)
{
var bw = Math.Min(blockSize, cols - bx);
var bh = Math.Min(blockSize, rows - by);
totalBlocks++;
var blockRect = new Rect(bx, by, bw, bh);
using var blockRoi = new Mat(wallMask, blockRect);
var wallCount = Cv2.CountNonZero(blockRoi);
if ((double)wallCount / (bw * bh) > blockMaxDensity)
{
// Zero out this noisy block in both mats
blockRoi.SetTo(Scalar.Black);
using var classBlock = new Mat(classifiedMat, blockRect);
classBlock.SetTo(Scalar.Black);
}
else
{
cleanBlocks++;
}
}
return totalBlocks > 0 ? (double)cleanBlocks / totalBlocks : 1.0;
}
public (double dirX, double dirY)? FindNearestUnexplored(MapPosition pos, int searchRadius = 200)
{
var cx = (int)Math.Round(pos.X);