minimap working much better

This commit is contained in:
Boki 2026-02-13 13:48:31 -05:00
parent 7fd80b1645
commit 07fe46c596
2 changed files with 18 additions and 64 deletions

View file

@ -9,7 +9,6 @@ public class MinimapCapture : IDisposable
{
private readonly MinimapConfig _config;
private readonly IScreenCapture _backend;
private readonly Queue<Mat> _frameBuffer = new();
public MinimapCapture(MinimapConfig config)
{
@ -68,28 +67,25 @@ public class MinimapCapture : IDisposable
var playerOffset = FindCentroid(playerMask);
// --- 3. Wall mask: bright OR saturated → structure lines ---
using var rawWallMask = BuildWallMask(satChan, valueChan, playerMask);
var wallMask = BuildWallMask(satChan, valueChan, playerMask);
// --- 4. Build classified mat (walls only — explored is tracked by WorldMap) ---
// --- 4. Build classified mat (walls only — for stitching) ---
var classified = new Mat(_config.CaptureSize, _config.CaptureSize, MatType.CV_8UC1, Scalar.Black);
classified.SetTo(new Scalar((byte)MapCell.Wall), rawWallMask);
classified.SetTo(new Scalar((byte)MapCell.Wall), wallMask);
// --- 5. Temporal smoothing: majority vote on walls ---
var smoothed = TemporalSmooth(classified); // classified goes into ring buffer
// Raw walls used for everything: dedup, matching, and stitching.
// Temporal smoothing kills walls during movement (minimap scrolls between frames,
// 3/5 vote fails). The confidence system is the long-term noise filter instead.
// --- 6. Extract smoothed wall mask for tracking (filters transient noise) ---
var stableWallMask = new Mat();
Cv2.Compare(smoothed, new Scalar((byte)MapCell.Wall), stableWallMask, CmpType.EQ);
// --- 7. Gray for optical flow tracking (player zeroed) ---
// --- 5. Gray for optical flow tracking (player zeroed) ---
var grayForCorr = new Mat();
Cv2.CvtColor(bgr, grayForCorr, ColorConversionCodes.BGR2GRAY);
grayForCorr.SetTo(Scalar.Black, playerMask);
return new MinimapFrame(
GrayMat: grayForCorr,
WallMask: stableWallMask,
ClassifiedMat: smoothed,
WallMask: wallMask, // raw — for matching + dedup
ClassifiedMat: classified, // raw — for stitching (confidence filters noise)
PlayerOffset: playerOffset,
Timestamp: DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
);
@ -157,38 +153,6 @@ public class MinimapCapture : IDisposable
}
}
private Mat TemporalSmooth(Mat classified)
{
// Add raw frame to ring buffer (takes ownership)
_frameBuffer.Enqueue(classified);
while (_frameBuffer.Count > _config.TemporalFrameCount)
_frameBuffer.Dequeue().Dispose();
// Not enough frames yet — return as-is
if (_frameBuffer.Count < 2)
return classified.Clone();
var size = classified.Size();
using var wallCount = new Mat(size, MatType.CV_8UC1, Scalar.Black);
foreach (var frame in _frameBuffer)
{
using var isWall = new Mat();
Cv2.Compare(frame, new Scalar((byte)MapCell.Wall), isWall, CmpType.EQ);
Cv2.Add(wallCount, new Scalar(1), wallCount, isWall);
}
// Apply vote threshold
using var wallPass = new Mat();
Cv2.Threshold(wallCount, wallPass,
_config.WallTemporalThreshold - 0.5, 255, ThresholdTypes.Binary);
var result = new Mat(size, MatType.CV_8UC1, Scalar.Black);
result.SetTo(new Scalar((byte)MapCell.Wall), wallPass);
return result;
}
/// <summary>
/// Capture a single frame and return the requested pipeline stage as PNG bytes.
/// </summary>
@ -294,7 +258,5 @@ public class MinimapCapture : IDisposable
public void Dispose()
{
_backend.Dispose();
while (_frameBuffer.Count > 0)
_frameBuffer.Dequeue().Dispose();
}
}