/// <summary> /// Returns face detection results. /// </summary> /// <param name="image">Bitmap</param> /// <returns>Rectangles</returns> public Rectangle[] Forward(Bitmap image) { var size = new Size(320, 240); using var clone = Imaging.Resize(image, size); int width = clone.Width; int height = clone.Height; var inputMeta = _session.InputMetadata; var name = inputMeta.Keys.ToArray()[0]; // pre-processing var dimentions = new int[] { 1, 3, height, width }; var tensors = clone.ToFloatTensor(true); tensors.Operator(new float[] { 127.0f, 127.0f, 127.0f }, Vector.Sub); tensors.Operator(128, Vector.Div); var inputData = tensors.Merge(true); // session run var t = new DenseTensor <float>(inputData, dimentions); var inputs = new List <NamedOnnxValue> { NamedOnnxValue.CreateFromTensor(name, t) }; var results = _session.Run(inputs).ToArray(); var confidences = results[0].AsTensor <float>().ToArray(); var boxes = results[1].AsTensor <float>().ToArray(); var length = confidences.Length; // post-proccessing var boxes_picked = new List <Rectangle>(); for (int i = 0, j = 0; i < length; i += 2, j += 4) { if (confidences[i + 1] > ConfidenceThreshold) { boxes_picked.Add( Imaging.ToBox( Rectangle.FromLTRB ( (int)(boxes[j + 0] * image.Width), (int)(boxes[j + 1] * image.Height), (int)(boxes[j + 2] * image.Width), (int)(boxes[j + 3] * image.Height) ))); } } // non-max suppression length = boxes_picked.Count; for (int i = 0; i < length; i++) { var first = boxes_picked[i]; for (int j = i + 1; j < length; j++) { var second = boxes_picked[j]; var iou = Imaging.IoU(first, second); if (iou > NmsThreshold) { boxes_picked.RemoveAt(j); length = boxes_picked.Count; j--; } } } // dispose foreach (var result in results) { result.Dispose(); } return(boxes_picked.ToArray()); }