diff --git a/Splitter-UI/Services/SingleThreadedDetector.cs b/Splitter-UI/Services/SingleThreadedDetector.cs index f4f06b8..8746e63 100644 --- a/Splitter-UI/Services/SingleThreadedDetector.cs +++ b/Splitter-UI/Services/SingleThreadedDetector.cs @@ -5,11 +5,11 @@ public class SingleThreadedDetector(IObjectDetector _detector) : IObjectDetec { private Lock _lock = new(); - public List<(OpenCvSharp.Rect box, Point2f center)> DetectAll(Mat frameCont) + public List<(OpenCvSharp.Rect box, Point2f center)> DetectAll(SingleTask job, Mat frameCont) { lock (_lock) { - return _detector.DetectAll(frameCont); + return _detector.DetectAll(job, frameCont); } } diff --git a/Splitter-UI/ViewModels/JobViewModel.cs b/Splitter-UI/ViewModels/JobViewModel.cs index f1e3738..9e1dd4c 100644 --- a/Splitter-UI/ViewModels/JobViewModel.cs +++ b/Splitter-UI/ViewModels/JobViewModel.cs @@ -258,7 +258,18 @@ public partial class JobViewModel : ObservableObject Preview = new PreviewData(frame, [], null, Job.GravitateTo ?? new (0.5f, 0.5f)); var detector = _detectorFactory(Job.Detect ?? ""); - var detections = detector.DetectAll(frame.ToMatContinuous()); + var j = new SingleTask + ( + Job : Job, + Info : Probe, + OutputFileName : "preview.jpg", + SegmentIndex : 0, + TotalSegments : 1, + SegmentStart : PositionSeconds, + SegmentLength : 1, // 1 second segment for detection + ProcessorFactory: _ => throw new NotImplementedException() + ); + var detections = detector.DetectAll(j, frame.ToMatContinuous()); Rect? crop = null; if (detections.Count > 0) diff --git a/splitter-cli/TrackingSplitter.cs b/splitter-cli/TrackingSplitter.cs index 8282401..5bde9ca 100644 --- a/splitter-cli/TrackingSplitter.cs +++ b/splitter-cli/TrackingSplitter.cs @@ -130,7 +130,7 @@ public class TrackingSplitter : LoggingBase, ISegmentProcessor, IDisposable Marshal.Copy(inBuffer, 0, frameMat.Data, inBytes); - var objects = _detector.DetectAll(frameMat); + var objects = _detector.DetectAll(job, frameMat); var primary = SelectTrackedObject(objects, kalman.LastMeasurement); camera.Update(primary); diff --git a/splitter-cli/algo/DummyDetector.cs b/splitter-cli/algo/DummyDetector.cs index c9d4912..c507e1a 100644 --- a/splitter-cli/algo/DummyDetector.cs +++ b/splitter-cli/algo/DummyDetector.cs @@ -1,7 +1,21 @@ namespace splitter.algo; -public class DummyDetector : IObjectDetector +public sealed class DummyDetector : IObjectDetector { - public List<(Rect box, Point2f center)> DetectAll(Mat frameCont) => []; + public List<(Rect box, Point2f center)> DetectAll(SingleTask job, Mat frameCont) + { + var h = job.Info.Height; + var w = job.Info.Width; + + var c = job.Job.GravitateTo ?? new Point2f(0.5f, 0.5f); + var x = (int)(c.X * w); + var y = (int)(c.Y * h); + + var center = new Point2f(x, y); + var rect = new Rect(x - 1, y - 1, 2, 2); + + return [(rect, center)]; + } + public void Dispose() {} } diff --git a/splitter-cli/algo/IObjectDetector.cs b/splitter-cli/algo/IObjectDetector.cs index 65751db..a82a5cd 100644 --- a/splitter-cli/algo/IObjectDetector.cs +++ b/splitter-cli/algo/IObjectDetector.cs @@ -2,5 +2,5 @@ public interface IObjectDetector : IDisposable { - List<(Rect box, Point2f center)> DetectAll(Mat frameCont); + List<(Rect box, Point2f center)> DetectAll(SingleTask job, Mat frameCont); } \ No newline at end of file diff --git a/splitter-cli/algo/RealBasicVsr2xDmlEnhancer.cs b/splitter-cli/algo/RealBasicVsr2xDmlEnhancer.cs index 9baaaae..b1eccb4 100644 --- a/splitter-cli/algo/RealBasicVsr2xDmlEnhancer.cs +++ b/splitter-cli/algo/RealBasicVsr2xDmlEnhancer.cs @@ -7,22 +7,22 @@ public sealed unsafe class RealBasicVsr2xDmlEnhancer : IVideoEnhancer { public int ResolutionMultiplier => 2; - private InferenceSession _session; - private SessionOptions _options; + private InferenceSession _session = null!; + private SessionOptions _options = null!; - private int _inW; - private int _inH; - private int _window; + private int _inW; + private int _inH; + private int _window; - private readonly Queue _frames = new Queue(32); + private readonly Queue _frames = new Queue(32); - private float[] _inputBuffer; - private float[] _outputBuffer; + private float[] _inputBuffer = null!; + private float[] _outputBuffer = null!; - private DenseTensor _inputTensor; - private DenseTensor _outputTensor; + private DenseTensor _inputTensor = null!; + private DenseTensor _outputTensor = null!; - private Mat _outputMat; + private Mat _outputMat = null!; private readonly List _inputList = new List(1); @@ -58,7 +58,7 @@ public sealed unsafe class RealBasicVsr2xDmlEnhancer : IVideoEnhancer public unsafe bool TryProcessFrame(Mat input, out Mat output, CancellationToken token) { - output = null; + output = null!; if (token.IsCancellationRequested) return false; @@ -194,115 +194,6 @@ public sealed unsafe class RealBasicVsr2xDmlEnhancer : IVideoEnhancer return true; } - public unsafe bool TryProcessFrame2(Mat input, out Mat output, CancellationToken token) - { - output = null; - - if (token.IsCancellationRequested) - return false; - - if (_frames.Count == _window) - { - var old = _frames.Dequeue(); - old.Dispose(); - } - - _frames.Enqueue(input.Clone()); - - if (_frames.Count < _window) - return false; - - int T = _window; - int H = _inH; - int W = _inW; - - // ------------------------------------------------------------ - // INPUT: CV_8UC3 BGR -> normalized RGB, channels-first [1,T,3,H,W] - // ------------------------------------------------------------ - - int t = 0; - - foreach (var f in _frames) - { - byte* src = (byte*)f.Data; - int stride = (int)f.Step(); - - for (int y = 0; y < H; y++) - { - byte* row = src + y * stride; - - for (int x = 0; x < W; x++) - { - int p = x * 3; - - byte b = row[p + 0]; - byte g = row[p + 1]; - byte r = row[p + 2]; - - float rN = r * (1.0f / 255.0f); - float gN = g * (1.0f / 255.0f); - float bN = b * (1.0f / 255.0f); - - int idxR = ((((0 * T) + t) * 3 + 0) * H + y) * W + x; - int idxG = ((((0 * T) + t) * 3 + 1) * H + y) * W + x; - int idxB = ((((0 * T) + t) * 3 + 2) * H + y) * W + x; - - _inputBuffer[idxR] = rN; - _inputBuffer[idxG] = gN; - _inputBuffer[idxB] = bN; - } - } - - t++; - } - - _inputList.Clear(); - _inputList.Add(NamedOnnxValue.CreateFromTensor("input", _inputTensor)); - - using var results = _session.Run(_inputList); - - var outTensor = results[0].AsTensor(); - - var dims = outTensor.Dimensions; // [1, T, 3, H2, W2] - - int outT = dims[1]; - int outH = dims[3]; - int outW = dims[4]; - - int last = outT - 1; - - unsafe - { - byte* dstBase = (byte*)_outputMat.Data; - int dstStride = (int)_outputMat.Step(); - - for (int y = 0; y < outH; y++) - { - byte* row = dstBase + y * dstStride; - - for (int x = 0; x < outW; x++) - { - float b = outTensor[0, last, 0, y, x]; // B, 0..1 - float g = outTensor[0, last, 1, y, x]; // G, 0..1 - float r = outTensor[0, last, 2, y, x]; // R, 0..1 - - int p = x * 3; - - row[p + 0] = (byte)(b * 255.0f); // B - row[p + 1] = (byte)(g * 255.0f); // G - row[p + 2] = (byte)(r * 255.0f); // R - } - } - } - - - output = _outputMat; - //ColorDebug.DumpAll(output, "C:\\Temp\\splitter-color-debug\\output"); - return true; - } - - - public int Flush(Span outputFrames, CancellationToken token) { return 0; diff --git a/splitter-cli/algo/UltraFaceDetector.cs b/splitter-cli/algo/UltraFaceDetector.cs index 2935629..2ae1e3d 100644 --- a/splitter-cli/algo/UltraFaceDetector.cs +++ b/splitter-cli/algo/UltraFaceDetector.cs @@ -23,7 +23,7 @@ public sealed class UltraFaceDetector: LoggingBase, IDisposable, IObjectDetector _ultraFace = UltraFace.Create(param); } - public List<(Rect box, Point2f center)> DetectAll(Mat frameCont) + public List<(Rect box, Point2f center)> DetectAll(SingleTask job, Mat frameCont) { // Convert to byte[] for UltraFace var bytesFull = frameCont.Rows * frameCont.Cols * frameCont.ElemSize(); diff --git a/splitter-cli/algo/YoloOnnxObjectDetector.cs b/splitter-cli/algo/YoloOnnxObjectDetector.cs index 68cc6d9..d1aa60e 100644 --- a/splitter-cli/algo/YoloOnnxObjectDetector.cs +++ b/splitter-cli/algo/YoloOnnxObjectDetector.cs @@ -78,7 +78,7 @@ public sealed class YoloOnnxObjectDetector : LoggingBase, IObjectDetector, IDisp _inputs.Add(NamedOnnxValue.CreateFromTensor(_inputName, _inputTensor)); } - public List<(Rect box, Point2f center)> DetectAll(Mat frameCont) + public List<(Rect box, Point2f center)> DetectAll(SingleTask job, Mat frameCont) { if (frameCont.Empty()) {