private List <DnnDetectedObject> OptimizeDetections(float threshold, float nmsThreshold, bool nms, List <int> classIds, List <float> confidences, List <float> probabilities, List <Rect2d> boxes)
        {
            int[] indices;

            if (!nms)
            {
                indices = Enumerable.Range(0, boxes.Count).ToArray();
            }
            else
            {
                //using non-maximum suppression to reduce overlapping low confidence box
                CvDnn.NMSBoxes(boxes, confidences, threshold, nmsThreshold, out indices);
                _logger.LogDebug($"NMSBoxes drop {confidences.Count - indices.Length} overlapping result.");
            }

            var result = new List <DnnDetectedObject>();

            foreach (var i in indices)
            {
                var box = boxes[i];

                var detection = new DnnDetectedObject()
                {
                    Index       = classIds[i],
                    Label       = Labels[classIds[i]],
                    Color       = Colors[classIds[i]],
                    Probability = probabilities[i],
                    BoundingBox = box
                };
                result.Add(detection);
            }

            return(result);
        }
Beispiel #2
0
        private DnnDetectedObject[] ExtractYolo2Results(IEnumerable <Mat> output, Mat image, float threshold, float nmsThreshold, bool nms = true)
        {
            var classIds      = new List <int>();
            var confidences   = new List <float>();
            var probabilities = new List <float>();
            var boxes         = new List <Rect2d>();

            var w = image.Width;
            var h = image.Height;

            var prob = output.First();

            /* YOLO2 VOC output
             * 0 1 : center                    2 3 : w/h
             * 4 : confidence                  5 ~24 : class probability */
            const int prefix = 5;   //skip 0~4

            for (int i = 0; i < prob.Rows; i++)
            {
                var confidence = prob.At <float>(i, 4);
                if (confidence > threshold)
                {
                    //get classes probability
                    Cv2.MinMaxLoc(prob.Row(i).ColRange(prefix, prob.Cols), out _, out Point max);
                    var classes     = max.X;
                    var probability = prob.At <float>(i, classes + prefix);

                    if (probability > threshold) //more accuracy
                    {
                        //get center and width/height
                        var centerX = prob.At <float>(i, 0) * w;
                        var centerY = prob.At <float>(i, 1) * h;
                        var width   = prob.At <float>(i, 2) * w;
                        var height  = prob.At <float>(i, 3) * h;

                        float X = Math.Max(0, centerX - (width / 2.0f));
                        float Y = Math.Max(0, centerY - (height / 2.0f));

                        //put data to list for NMSBoxes
                        classIds.Add(classes);
                        confidences.Add(confidence);
                        probabilities.Add(probability);
                        boxes.Add(new Rect2d(X, Y, width, height));
                    }
                }
            }

            int[] indices;

            if (!nms)
            {
                //using non-maximum suppression to reduce overlapping low confidence box
                indices = Enumerable.Range(0, boxes.Count).ToArray();
            }
            else
            {
                CvDnn.NMSBoxes(boxes, confidences, threshold, nmsThreshold, out indices);
                _logger.LogInformation($"NMSBoxes drop {confidences.Count - indices.Length} overlapping result.");
            }

            var result = new List <DnnDetectedObject>();

            foreach (var i in indices)
            {
                var box = boxes[i];

                var detection = new DnnDetectedObject()
                {
                    Index       = classIds[i],
                    Label       = Labels[classIds[i]],
                    Color       = Colors[classIds[i]],
                    Probability = probabilities[i],
                    BoundingBox = box
                };
                result.Add(detection);
            }

            return(result.ToArray());
        }
        private DnnDetectedObject[][] ExtractYolo3SingleResults(IEnumerable <Mat> output, Mat image, float threshold, float nmsThreshold, bool nms = true)
        {
            DnnDetectedObject[][] results = new DnnDetectedObject[1][];

            var classIds      = new List <int>();
            var confidences   = new List <float>();
            var probabilities = new List <float>();
            var boxes         = new List <Rect2d>();

            //for nms
            classIds.Clear();
            confidences.Clear();
            probabilities.Clear();
            boxes.Clear();

            var w = image.Width;
            var h = image.Height;

            /*
             * YOLO3 COCO trainval output
             * 0 1 : center                    2 3 : w/h
             * 4 : confidence                  5 ~ 84 : class probability
             */
            const int prefix = 5;   //skip 0~4

            foreach (var prob in output)
            {
                //dimensions will be 2 for single image analysis and 3 for batch analysis
                //1 input Prob Dims:2 images: 0 - 300, 1 - 85

                for (var i = 0; i < prob.Size(0); i++)
                {
                    var confidence = prob.At <float>(i, 4);

                    //Filter out bogus results of > 100% confidence
                    if (confidence > threshold && confidence <= 1.0)
                    {
                        var colRange = new Range(prefix, prob.Size(1) - 1);

                        var maxProbIndex = prob.FindMaxValueIndexInRange <float>(i, colRange);

                        if (maxProbIndex == -1)
                        {
                            continue;
                        }

                        var probability = prob.At <float>(i, maxProbIndex);

                        if (probability > threshold) //more accuracy, you can cancel it
                        {
                            //get center and width/height
                            var centerX = prob.At <float>(i, 0) * w;
                            var centerY = prob.At <float>(i, 1) * h;
                            var width   = prob.At <float>(i, 2) * w;
                            var height  = prob.At <float>(i, 3) * h;

                            float X = Math.Max(0, centerX - (width / 2.0f));
                            float Y = Math.Max(0, centerY - (height / 2.0f));

                            //put data to list for NMSBoxes
                            classIds.Add(maxProbIndex - prefix);
                            confidences.Add(confidence);
                            probabilities.Add(probability);
                            boxes.Add(new Rect2d(X, Y, width, height));
                        }
                    }
                }
            }

            List <DnnDetectedObject> result = OptimizeDetections(threshold, nmsThreshold, nms, classIds, confidences, probabilities, boxes);

            results[0] = result.ToArray();

            return(results);
        }
        private IList <DnnDetectedObject[]> ExtractYoloBatchedResults(IEnumerable <Mat> output, IEnumerable <Mat> image, float threshold, float nmsThreshold, bool nms = true)
        {
            var inputImages = image.ToList();

            DnnDetectedObject[][] results = new DnnDetectedObject[inputImages.Count][];


            for (int inputIndex = 0; inputIndex < inputImages.Count; inputIndex++)
            {
                //for nms
                _classIds.Clear();
                _confidences.Clear();
                _probabilities.Clear();
                _boxes.Clear();

                var w = inputImages[inputIndex].Width;
                var h = inputImages[inputIndex].Height;

                /*
                 * YOLO3 COCO trainval output
                 * 0 1 : center                    2 3 : w/h
                 * 4 : confidence                  5 ~ 84 : class probability
                 */
                const int prefix = 5;   //skip 0~4

                foreach (var prob in output)
                {
                    //dimensions will be 2 for single image analysis and 3 for batch analysis
                    //2 input Prob Dims:3 images: 0 - 2, 1 - 300, 2 - 85

                    var probabilitiesRange = new Range(prefix, prob.Size(2) - 1);

                    for (var i = 0; i < prob.Size(1); i++)
                    {
                        var confidence = prob.At <float>(inputIndex, i, 4);

                        //Filter out bogus results of > 100% confidence
                        if (confidence > threshold && confidence <= 1.0)
                        {
                            var maxProbIndex = prob.FindMaxValueIndexInRange <float>(inputIndex, i, probabilitiesRange);

                            if (maxProbIndex == -1)
                            {
                                continue;
                            }

                            var probability = prob.At <float>(inputIndex, i, maxProbIndex);

                            if (probability > threshold) //more accuracy, you can cancel it
                            {
                                //get center and width/height
                                var centerX = prob.At <float>(inputIndex, i, 0) * w;
                                var centerY = prob.At <float>(inputIndex, i, 1) * h;
                                var width   = prob.At <float>(inputIndex, i, 2) * w;
                                var height  = prob.At <float>(inputIndex, i, 3) * h;

                                float X = Math.Max(0, centerX - (width / 2.0f));
                                float Y = Math.Max(0, centerY - (height / 2.0f));

                                //put data to list for NMSBoxes
                                _classIds.Add(maxProbIndex - prefix);
                                _confidences.Add(confidence);
                                _probabilities.Add(probability);
                                _boxes.Add(new Rect2d(X, Y, width, height));
                            }
                        }
                    }
                }

                results[inputIndex] = OptimizeDetections(threshold, nmsThreshold, nms).ToArray();
            }

            return(results);
        }