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();
|
var sw = Stopwatch.StartNew();
|
||||||
_frameCount++;
|
_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;
|
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)",
|
Log.Information("Noise filter: {Clean:P0} clean, skipping ({Ms:F1}ms)",
|
||||||
density, wallPixels, sw.Elapsed.TotalMilliseconds);
|
cleanFraction, sw.Elapsed.TotalMilliseconds);
|
||||||
return _position;
|
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)
|
public (double dirX, double dirY)? FindNearestUnexplored(MapPosition pos, int searchRadius = 200)
|
||||||
{
|
{
|
||||||
var cx = (int)Math.Round(pos.X);
|
var cx = (int)Math.Round(pos.X);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue