private void GenerateBBox(ICollection <FaceInfo> boundingBoxCollection, Mat scores, Mat boxes, float scoreThreshold, int numAnchors) { for (var i = 0; i < numAnchors; i++) { if (scores.Channel(0)[i * 2 + 1] > scoreThreshold) { var rects = new FaceInfo(); var xCenter = boxes.Channel(0)[i * 4] * CenterVariance * this._Priors[i][2] + this._Priors[i][0]; var yCenter = boxes.Channel(0)[i * 4 + 1] * CenterVariance * this._Priors[i][3] + this._Priors[i][1]; var w = Math.Exp(boxes.Channel(0)[i * 4 + 2] * SizeVariance) * this._Priors[i][2]; var h = Math.Exp(boxes.Channel(0)[i * 4 + 3] * SizeVariance) * this._Priors[i][3]; rects.X1 = Clip(xCenter - w / 2.0, 1) * this._ImageW; rects.Y1 = Clip(yCenter - h / 2.0, 1) * this._ImageH; rects.X2 = Clip(xCenter + w / 2.0, 1) * this._ImageW; rects.Y2 = Clip(yCenter + h / 2.0, 1) * this._ImageH; rects.Score = Clip(scores.Channel(0)[i * 2 + 1], 1); boundingBoxCollection.Add(rects); } } }
private void NonMaximumSuppression(List <FaceInfo> input, ICollection <FaceInfo> output, NonMaximumSuppressionMode type = NonMaximumSuppressionMode.Blending) { input.Sort((f1, f2) => f1.Score.CompareTo(f2.Score)); var boxNum = input.Count; var merged = new int[boxNum]; for (var i = 0; i < boxNum; i++) { if (merged[i] > 0) { continue; } var buf = new List <FaceInfo> { input[i] }; merged[i] = 1; var h0 = input[i].Y2 - input[i].Y1 + 1; var w0 = input[i].X2 - input[i].X1 + 1; var area0 = h0 * w0; for (var j = i + 1; j < boxNum; j++) { if (merged[j] > 0) { continue; } var innerX0 = input[i].X1 > input[j].X1 ? input[i].X1 : input[j].X1; var innerY0 = input[i].Y1 > input[j].Y1 ? input[i].Y1 : input[j].Y1; var innerX1 = input[i].X2 < input[j].X2 ? input[i].X2 : input[j].X2; var innerY1 = input[i].Y2 < input[j].Y2 ? input[i].Y2 : input[j].Y2; var innerH = innerY1 - innerY0 + 1; var innerW = innerX1 - innerX0 + 1; if (innerH <= 0 || innerW <= 0) { continue; } var innerArea = innerH * innerW; var h1 = input[j].Y2 - input[j].Y1 + 1; var w1 = input[j].X2 - input[j].X1 + 1; var area1 = h1 * w1; var score = innerArea / (area0 + area1 - innerArea); if (score > this._IouThreshold) { merged[j] = 1; buf.Add(input[j]); } } switch (type) { case NonMaximumSuppressionMode.Hard: { output.Add(buf[0]); break; } case NonMaximumSuppressionMode.Blending: { var total = 0d; for (var j = 0; j < buf.Count; j++) { total += Math.Exp(buf[j].Score); } var rects = new FaceInfo(); for (var j = 0; j < buf.Count; j++) { var rate = Math.Exp(buf[j].Score) / total; rects.X1 += (float)(buf[j].X1 * rate); rects.Y1 += (float)(buf[j].Y1 * rate); rects.X2 += (float)(buf[j].X2 * rate); rects.Y2 += (float)(buf[j].Y2 * rate); rects.Score += (float)(buf[j].Score * rate); } output.Add(rects); break; } default: //{ // Console.WriteLine("wrong type of nms."); // exit(-1); //} break; } } #endregion #endregion }