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