Exemple #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())
                    //using(VectorOfMat outputTensors = new VectorOfMat())
                    {
                        _maskRcnnDetector.SetInput(blob, "image_tensor");
                        _maskRcnnDetector.Forward(tensors, new string[] { "detection_out_final", "detection_masks" });
                        //_maskRcnnModel.Predict(m, outputTensors);

                        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());
                            }
                    }
        }
Exemple #2
0
        public DetectedObject[] Detect(Mat image, double confThreshold = 0.5)
        {
            MCvScalar meanVal = new MCvScalar();

            Size imageSize = image.Size;

            DnnInvoke.BlobFromImage(
                image,
                _inputBlob,
                1.0,
                new Size(416, 416),
                meanVal,
                true,
                false,
                DepthType.Cv8U);
            _yoloDetector.SetInput(_inputBlob, "", 0.00392);
            int[]  outLayers    = _yoloDetector.UnconnectedOutLayers;
            String outLayerType = _yoloDetector.GetLayer(outLayers[0]).Type;

            String[] outLayerNames = _yoloDetector.UnconnectedOutLayersNames;

            using (VectorOfMat outs = new VectorOfMat())
            {
                List <DetectedObject> detectedObjects = new List <DetectedObject>();
                _yoloDetector.Forward(outs, outLayerNames);

                if (outLayerType.Equals("Region"))
                {
                    int size = outs.Size;

                    for (int i = 0; i < size; i++)
                    {
                        // Network produces output blob with a shape NxC where N is a number of
                        // detected objects and C is a number of classes + 4 where the first 4
                        // numbers are [center_x, center_y, width, height]
                        using (Mat m = outs[i])
                        {
                            int rows = m.Rows;
                            int cols = m.Cols;
                            float[,] data = m.GetData(true) as float[, ];
                            for (int j = 0; j < rows; j++)
                            {
                                using (Mat subM = new Mat(m, new Emgu.CV.Structure.Range(j, j + 1), new Emgu.CV.Structure.Range(5, cols)))
                                {
                                    double minVal = 0, maxVal = 0;
                                    Point  minLoc = new Point();
                                    Point  maxLoc = new Point();
                                    CvInvoke.MinMaxLoc(subM, ref minVal, ref maxVal, ref minLoc, ref maxLoc);
                                    if (maxVal > confThreshold)
                                    {
                                        int       centerX = (int)(data[j, 0] * imageSize.Width);
                                        int       centerY = (int)(data[j, 1] * imageSize.Height);
                                        int       width   = (int)(data[j, 2] * imageSize.Width);
                                        int       height  = (int)(data[j, 3] * imageSize.Height);
                                        int       left    = centerX - width / 2;
                                        int       top     = centerY - height / 2;
                                        Rectangle rect    = new Rectangle(left, top, width, height);

                                        DetectedObject obj = new DetectedObject();
                                        obj.ClassId   = maxLoc.X;
                                        obj.Confident = maxVal;
                                        obj.Region    = rect;
                                        obj.Label     = _labels[obj.ClassId];
                                        detectedObjects.Add(obj);
                                    }
                                }
                            }
                        }
                    }

                    return(detectedObjects.ToArray());
                }
                else
                {
                    throw new Exception(String.Format("Unknown output layer type: {0}", outLayerType));
                }
            }
        }