/// <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()); } } }