Esempio n. 1
0
        /// <summary>
        /// Perform detection on the input image and return the results
        /// </summary>
        /// <param name="m">The input image</param>
        /// <param name="matchScoreThreshold">A threshold used to filter boxes by score.</param>
        /// <param name="nmsThreshold">A threshold used in non maximum suppression.</param>
        /// <returns>The detected objects</returns>
        public MaskedObject[] Detect(IInputArray m, float matchScoreThreshold = 0.5f, float nmsThreshold = 0.4f)
        {
            using (InputArray iaM = m.GetInputArray())
                using (Mat blob = DnnInvoke.BlobFromImage(m))
                    using (VectorOfMat tensors = new VectorOfMat())
                    {
                        _maskRcnnDetector.SetInput(blob, "image_tensor");
                        _maskRcnnDetector.Forward(tensors, new string[] { "detection_out_final", "detection_masks" });

                        using (Mat boxes = tensors[0])
                            using (Mat masks = tensors[1])
                            {
                                System.Drawing.Size imgSize = iaM.GetSize();
                                float[,,,] boxesData = boxes.GetData(true) as float[, , , ];
                                int numDetections = boxesData.GetLength(2);

                                List <int>       classIds = new List <int>();
                                List <Rectangle> regions  = new List <Rectangle>();
                                List <float>     scores   = new List <float>();

                                for (int i = 0; i < numDetections; i++)
                                {
                                    int classId = (int)boxesData[0, 0, i, 1];

                                    if (_objectsOfInterest == null || _objectsOfInterest.Contains(_labels[classId]))
                                    {
                                        float     score = boxesData[0, 0, i, 2];
                                        Rectangle rect  = DetectedObject.GetRectangle(
                                            boxesData[0, 0, i, 3],
                                            boxesData[0, 0, i, 4],
                                            boxesData[0, 0, i, 5],
                                            boxesData[0, 0, i, 6],
                                            imgSize.Width,
                                            imgSize.Height);
                                        rect.Intersect(new Rectangle(Point.Empty, imgSize));

                                        regions.Add(rect);
                                        scores.Add(score);
                                        classIds.Add(classId);
                                    }
                                }
                                int[] validIdx = DnnInvoke.NMSBoxes(regions.ToArray(), scores.ToArray(), matchScoreThreshold, nmsThreshold);
                                List <MaskedObject> maskedObjects = new List <MaskedObject>();

                                for (int i = 0; i < validIdx.Length; i++)
                                {
                                    int       idx     = validIdx[i];
                                    int       classId = classIds[idx];
                                    Rectangle rect    = regions[idx];
                                    float     score   = scores[idx];

                                    int[] masksDim = masks.SizeOfDimension;
                                    using (Mat mask = new Mat(
                                               masksDim[2],
                                               masksDim[3],
                                               DepthType.Cv32F,
                                               1,
                                               masks.GetDataPointer(i, classId),
                                               masksDim[3] * masks.ElementSize))
                                    {
                                        MaskedObject mo = new MaskedObject(classId, _labels[classId], score, rect, mask);
                                        maskedObjects.Add(mo);
                                    }
                                }

                                return(maskedObjects.ToArray());
                            }
                    }
        }