using DlibDotNet; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.FaceRecognitionDotNet.Dlib.Python; internal sealed class SimpleObjectDetector { #region Methods public static IEnumerable RunDetectorWithUpscale1(FrontalFaceDetector detector, Image img, uint upsamplingAmount, double adjustThreshold, List detectionConfidences, List weightIndices) { List? rectangles = new(); if (img.Mode == Mode.Greyscale) { Matrix? greyscaleMatrix = img.Matrix as Matrix; if (upsamplingAmount == 0) { detector.Operator(greyscaleMatrix, out IEnumerable? rectDetections, adjustThreshold); RectDetection[]? dets = rectDetections.ToArray(); SplitRectDetections(dets, rectangles, detectionConfidences, weightIndices); foreach (RectDetection? rectDetection in dets) rectDetection.Dispose(); } else { using PyramidDown? pyr = new(2); Matrix? temp = null; try { DlibDotNet.Dlib.PyramidUp(greyscaleMatrix, pyr, out temp); uint levels = upsamplingAmount - 1; while (levels > 0) { levels--; DlibDotNet.Dlib.PyramidUp(temp); } detector.Operator(temp, out IEnumerable? rectDetections, adjustThreshold); RectDetection[]? dets = rectDetections.ToArray(); foreach (RectDetection? t in dets) t.Rect = pyr.RectDown(t.Rect, upsamplingAmount); SplitRectDetections(dets, rectangles, detectionConfidences, weightIndices); foreach (RectDetection? rectDetection in dets) rectDetection.Dispose(); } finally { temp?.Dispose(); } } return rectangles; } else { Matrix? rgbMatrix = img.Matrix as Matrix; if (upsamplingAmount == 0) { detector.Operator(rgbMatrix, out IEnumerable? rectDetections, adjustThreshold); RectDetection[]? dets = rectDetections.ToArray(); SplitRectDetections(dets, rectangles, detectionConfidences, weightIndices); foreach (RectDetection? rectDetection in dets) rectDetection.Dispose(); } else { using PyramidDown? pyr = new(2); Matrix? temp = null; try { DlibDotNet.Dlib.PyramidUp(rgbMatrix, pyr, out temp); uint levels = upsamplingAmount - 1; while (levels > 0) { levels--; DlibDotNet.Dlib.PyramidUp(temp); } detector.Operator(temp, out IEnumerable? rectDetections, adjustThreshold); RectDetection[]? dets = rectDetections.ToArray(); foreach (RectDetection? t in dets) t.Rect = pyr.RectDown(t.Rect, upsamplingAmount); SplitRectDetections(dets, rectangles, detectionConfidences, weightIndices); foreach (RectDetection? rectDetection in dets) rectDetection.Dispose(); } finally { temp?.Dispose(); } } return rectangles; } } public static IEnumerable> RunDetectorWithUpscale2(FrontalFaceDetector detector, Image image, uint upsamplingAmount) { if (detector == null) throw new ArgumentNullException(nameof(detector)); if (image == null) throw new ArgumentNullException(nameof(image)); detector.ThrowIfDisposed(); image.ThrowIfDisposed(); List? detectionConfidences = new(); List? weightIndices = new(); const double adjustThreshold = 0.0; Rectangle[]? rects = RunDetectorWithUpscale1(detector, image, upsamplingAmount, adjustThreshold, detectionConfidences, weightIndices).ToArray(); int index = 0; foreach (Rectangle rect in rects) yield return new Tuple(rect, detectionConfidences[index++]); } #region Helpers private static void SplitRectDetections(RectDetection[] rectDetections, List rectangles, List detectionConfidences, List weightIndices) { rectangles.Clear(); detectionConfidences.Clear(); weightIndices.Clear(); foreach (RectDetection? rectDetection in rectDetections) { rectangles.Add(rectDetection.Rect); detectionConfidences.Add(rectDetection.DetectionConfidence); weightIndices.Add(rectDetection.WeightIndex); } } #endregion #endregion }