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