public static float IoU(OutputVector v1, OutputVector v2) { float x1 = Math.Max(v1.X, v2.X); float y1 = Math.Max(v1.Y, v2.Y); float x2 = Math.Min(v1.X + v1.W, v2.X + v2.W); float y2 = Math.Min(v1.Y + v1.H, v2.Y + v2.H); float area = Math.Max(0, (x2 - x1) * (y2 - y1)); float iou = area / (v1.W * v1.H + v2.W * v2.H - area); return(iou); }
private static Task <IEnumerable <OutputVector> > FilterAsync(float[] output, string key) { return(new Task <IEnumerable <OutputVector> >(() => { var result = new List <OutputVector>(); var(anchors, stride, grids) = AnchorsDict[key]; for (int channel = 0; channel < anchors.Length; channel++) { for (int row = 0; row < grids; row++) { for (int col = 0; col < grids; col++) { var start = (grids * grids * channel + grids * row + col) * VECTOR_LENGTH; var objectConfidence = Functions.Sigmoid(output[start + 4]); if (objectConfidence < Params.ConfidenceThreshold) { continue; } var span = new ReadOnlySpan <float>(output, start, VECTOR_LENGTH); var scores = span.Slice(5, VECTOR_LENGTH - 5).ToArray() .Select(c => Functions.Sigmoid(c)); var vector = new OutputVector { ObjectConfidence = objectConfidence, X = (Functions.Sigmoid(span[0]) * 2 - 0.5f + col) * stride, Y = (Functions.Sigmoid(span[1]) * 2 - 0.5f + row) * stride, W = MathF.Pow(Functions.Sigmoid(span[2]) * 2, 2) * anchors[channel].width, H = MathF.Pow(Functions.Sigmoid(span[3]) * 2, 2) * anchors[channel].height, ClassScores = scores.ToArray() }; if (vector.ClassMaxScore >= Params.ConfidenceThreshold) { result.Add(vector); } } } } return result; })); }