fixes for noise
This commit is contained in:
parent
d2dab86544
commit
b9b9a41c3c
3 changed files with 61 additions and 71 deletions
|
|
@ -53,78 +53,51 @@ public class MinimapCapture : IDisposable
|
|||
if (bgr == null || bgr.Empty())
|
||||
return null;
|
||||
|
||||
// --- 1. HSV + extract S/V channels ---
|
||||
using var hsv = new Mat();
|
||||
Cv2.CvtColor(bgr, hsv, ColorConversionCodes.BGR2HSV);
|
||||
using var satChan = new Mat();
|
||||
using var valueChan = new Mat();
|
||||
Cv2.ExtractChannel(hsv, satChan, 1); // S
|
||||
Cv2.ExtractChannel(hsv, valueChan, 2); // V
|
||||
|
||||
// --- 2. Player mask (orange marker) ---
|
||||
// Player mask (orange marker)
|
||||
using var playerMask = new Mat();
|
||||
Cv2.InRange(hsv, _config.PlayerLoHSV, _config.PlayerHiHSV, playerMask);
|
||||
var playerOffset = FindCentroid(playerMask);
|
||||
|
||||
// --- 3. Wall mask: bright OR saturated → structure lines ---
|
||||
var wallMask = BuildWallMask(satChan, valueChan, playerMask);
|
||||
// Wall mask: target #A2AEE5 blue-lavender structure lines
|
||||
var wallMask = BuildWallMask(hsv, playerMask);
|
||||
|
||||
// --- 4. Build classified mat (walls only — for stitching) ---
|
||||
// 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), wallMask);
|
||||
|
||||
// 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.
|
||||
|
||||
// --- 5. Gray for optical flow tracking (player zeroed) ---
|
||||
// Gray for correlation tracking (player zeroed)
|
||||
var grayForCorr = new Mat();
|
||||
Cv2.CvtColor(bgr, grayForCorr, ColorConversionCodes.BGR2GRAY);
|
||||
grayForCorr.SetTo(Scalar.Black, playerMask);
|
||||
|
||||
return new MinimapFrame(
|
||||
GrayMat: grayForCorr,
|
||||
WallMask: wallMask, // raw — for matching + dedup
|
||||
ClassifiedMat: classified, // raw — for stitching (confidence filters noise)
|
||||
WallMask: wallMask,
|
||||
ClassifiedMat: classified,
|
||||
PlayerOffset: playerOffset,
|
||||
Timestamp: DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
||||
);
|
||||
}
|
||||
|
||||
private Mat BuildWallMask(Mat satChan, Mat valueChan, Mat playerMask)
|
||||
private Mat BuildWallMask(Mat hsv, Mat playerMask)
|
||||
{
|
||||
// Wall = bright OR saturated pixels (minimap structure lines, icons)
|
||||
using var highV = new Mat();
|
||||
Cv2.Threshold(valueChan, highV, _config.WallMinValue, 255, ThresholdTypes.Binary);
|
||||
using var highS = new Mat();
|
||||
Cv2.Threshold(satChan, highS, _config.WallMinSat, 255, ThresholdTypes.Binary);
|
||||
|
||||
// Exclude nameplate text: very bright (V > 230) AND unsaturated (S < 40)
|
||||
// Nameplates are pure white text; minimap walls are colored (have saturation)
|
||||
using var nameplateBright = new Mat();
|
||||
Cv2.Threshold(valueChan, nameplateBright, _config.NameplateMinValue, 255, ThresholdTypes.Binary);
|
||||
using var nameplateLowSat = new Mat();
|
||||
Cv2.Threshold(satChan, nameplateLowSat, _config.NameplateMaxSat, 255, ThresholdTypes.BinaryInv);
|
||||
using var nameplateMask = new Mat();
|
||||
Cv2.BitwiseAnd(nameplateBright, nameplateLowSat, nameplateMask);
|
||||
|
||||
// Target wall color #A2AEE5 — HSV(115, 75, 229)
|
||||
// This is map-independent: walls are always blue-lavender, fog is higher-saturation blue
|
||||
var wallMask = new Mat();
|
||||
Cv2.BitwiseOr(highV, highS, wallMask);
|
||||
Cv2.InRange(hsv, _config.WallLoHSV, _config.WallHiHSV, wallMask);
|
||||
|
||||
// Subtract nameplates
|
||||
using var notNameplate = new Mat();
|
||||
Cv2.BitwiseNot(nameplateMask, notNameplate);
|
||||
Cv2.BitwiseAnd(wallMask, notNameplate, wallMask);
|
||||
|
||||
// Dilate to connect wall line fragments
|
||||
using var kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3, 3));
|
||||
Cv2.Dilate(wallMask, wallMask, kernel);
|
||||
|
||||
// Subtract player (bright/saturated marker would otherwise be classified as wall)
|
||||
// Subtract player marker (orange overlaps blue range slightly on some maps)
|
||||
using var notPlayer = new Mat();
|
||||
Cv2.BitwiseNot(playerMask, notPlayer);
|
||||
Cv2.BitwiseAnd(wallMask, notPlayer, wallMask);
|
||||
|
||||
// Dilate to connect thin wall line fragments
|
||||
using var kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3, 3));
|
||||
Cv2.Dilate(wallMask, wallMask, kernel);
|
||||
|
||||
FilterSmallComponents(wallMask, _config.WallMinArea);
|
||||
return wallMask;
|
||||
}
|
||||
|
|
@ -176,16 +149,11 @@ public class MinimapCapture : IDisposable
|
|||
return result;
|
||||
}
|
||||
|
||||
using var satChan = new Mat();
|
||||
using var valueChan = new Mat();
|
||||
Cv2.ExtractChannel(hsv, satChan, 1);
|
||||
Cv2.ExtractChannel(hsv, valueChan, 2);
|
||||
|
||||
using var playerMask = new Mat();
|
||||
Cv2.InRange(hsv, _config.PlayerLoHSV, _config.PlayerHiHSV, playerMask);
|
||||
if (stage == MinimapDebugStage.Player) return EncodePng(playerMask);
|
||||
|
||||
using var wallMask = BuildWallMask(satChan, valueChan, playerMask);
|
||||
using var wallMask = BuildWallMask(hsv, playerMask);
|
||||
if (stage == MinimapDebugStage.Walls) return EncodePng(wallMask);
|
||||
|
||||
// Classified (walls + player only — explored is tracked by WorldMap)
|
||||
|
|
@ -214,15 +182,10 @@ public class MinimapCapture : IDisposable
|
|||
using var hsv = new Mat();
|
||||
Cv2.CvtColor(bgr, hsv, ColorConversionCodes.BGR2HSV);
|
||||
|
||||
using var satChan = new Mat();
|
||||
using var valueChan = new Mat();
|
||||
Cv2.ExtractChannel(hsv, satChan, 1);
|
||||
Cv2.ExtractChannel(hsv, valueChan, 2);
|
||||
|
||||
using var playerMask = new Mat();
|
||||
Cv2.InRange(hsv, _config.PlayerLoHSV, _config.PlayerHiHSV, playerMask);
|
||||
|
||||
using var wallMask = BuildWallMask(satChan, valueChan, playerMask);
|
||||
using var wallMask = BuildWallMask(hsv, playerMask);
|
||||
|
||||
// Colorized classified (walls + player)
|
||||
using var classified = new Mat(_config.CaptureSize, _config.CaptureSize, MatType.CV_8UC3, Scalar.Black);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue