/// <summary> /// Utils: Compute the areas of rectangles given two corners. /// </summary> private static float AreaOf(FaceDetectionRectangle rect) { var h = Clip(rect.Y2 - rect.Y1 + 1, 0); var w = Clip(rect.X2 - rect.X1 + 1, 0); return(h * w); }
/// <summary> /// PostProcessing. /// Generates a list of BBox containing the detected face info. /// </summary> /// <param name="boundingBoxCollection">empty list of FaceDetectionRec to store results.</param> /// <param name="scores">score output of Onnx model.</param> /// <param name="boxes">box output of Onnx model.</param> /// <param name="scoreThreshold">threshold of score between 0 and 1 for filtering boxes.</param> private static void GenerateBBox( ICollection <FaceDetectionRectangle> boundingBoxCollection, TensorFloat scores, TensorFloat boxes, float scoreThreshold) { IReadOnlyList <float> vectorBoxes = boxes.GetAsVectorView(); IList <float> boxList = vectorBoxes.ToList(); IReadOnlyList <float> vectorScores = scores.GetAsVectorView(); IList <float> scoreList = vectorScores.ToList(); long numAnchors = scores.Shape[1]; if (numAnchors <= 0) { return; } for (var i = 0; i < numAnchors; i++) { if (scoreList[i * 2 + 1] > scoreThreshold) { var rect = new FaceDetectionRectangle { X1 = boxList[i * 4] * inputImageDataWidth, Y1 = boxList[i * 4 + 1] * inputImageDataHeight, X2 = boxList[i * 4 + 2] * inputImageDataWidth, Y2 = boxList[i * 4 + 3] * inputImageDataHeight, Score = Clip(scoreList[i * 2 + 1], 0, 1) }; boundingBoxCollection.Add(rect); } } }
/// <summary> /// Utils: Return intersection-over-union (Jaccard index) of 2 boxes. /// </summary> /// <returns>Float value > 0 if overlapped area exists. -1 if overlapped area doesn't exist.</returns> private static float IOUOf(FaceDetectionRectangle rect1, FaceDetectionRectangle rect2) { var rect = new FaceDetectionRectangle { X1 = Math.Max(rect1.X1, rect2.X1), Y1 = Math.Max(rect1.Y1, rect2.Y1), X2 = Math.Min(rect1.X2, rect2.X2), Y2 = Math.Min(rect1.Y2, rect2.Y2), Score = 0 }; var innerArea = AreaOf(rect); var area1 = AreaOf(rect1); var area2 = AreaOf(rect2); if (innerArea == 0 || area1 == 0 || area2 == 0) { return(-1); } return(innerArea / (area1 + area2 - innerArea)); }