예제 #1
0
        /// <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());
        }