much better
This commit is contained in:
parent
86c7a31231
commit
db37d3c179
1 changed files with 46 additions and 9 deletions
|
|
@ -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.0–1.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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue