private static void GenerateProposals(Mat anchors, int featStride, Mat scoreBlob, Mat bboxBlob, Mat landmarkBlob, float probThreshold, IList <FaceObject> faceObjects) { var w = scoreBlob.W; var h = scoreBlob.H; // generate face proposal from bbox deltas and shifted anchors var numAnchors = anchors.H; for (var q = 0; q < numAnchors; q++) { var anchor = anchors.Row(q); using var score = scoreBlob.Channel(q + numAnchors); using var bbox = bboxBlob.ChannelRange(q * 4, 4); using var landmark = landmarkBlob.ChannelRange(q * 10, 10); // shifted anchor var anchorY = anchor[1]; var anchorW = anchor[2] - anchor[0]; var anchorH = anchor[3] - anchor[1]; for (var i = 0; i < h; i++) { var anchorX = anchor[0]; for (var j = 0; j < w; j++) { var index = i * w + j; var prob = score[index]; if (prob >= probThreshold) { // apply center size using var mat0 = bbox.Channel(0); using var mat1 = bbox.Channel(1); using var mat2 = bbox.Channel(2); using var mat3 = bbox.Channel(3); var dx = mat0[index]; var dy = mat1[index]; var dw = mat2[index]; var dh = mat3[index]; var cx = anchorX + anchorW * 0.5f; var cy = anchorY + anchorH * 0.5f; var pbCx = cx + anchorW * dx; var pbCy = cy + anchorH * dy; var pbW = anchorW * (float)Math.Exp(dw); var pbH = anchorH * (float)Math.Exp(dh); var x0 = pbCx - pbW * 0.5f; var y0 = pbCy - pbH * 0.5f; var x1 = pbCx + pbW * 0.5f; var y1 = pbCy + pbH * 0.5f; var obj = new FaceObject(); obj.Rect.X = x0; obj.Rect.Y = y0; obj.Rect.Width = x1 - x0 + 1; obj.Rect.Height = y1 - y0 + 1; using var landmarkMat0 = landmark.Channel(0); using var landmarkMat1 = landmark.Channel(1); using var landmarkMat2 = landmark.Channel(2); using var landmarkMat3 = landmark.Channel(3); using var landmarkMat4 = landmark.Channel(4); using var landmarkMat5 = landmark.Channel(5); using var landmarkMat6 = landmark.Channel(6); using var landmarkMat7 = landmark.Channel(7); using var landmarkMat8 = landmark.Channel(8); using var landmarkMat9 = landmark.Channel(9); obj.Landmark[0].X = cx + (anchorW + 1) * landmarkMat0[index]; obj.Landmark[0].Y = cy + (anchorH + 1) * landmarkMat1[index]; obj.Landmark[1].X = cx + (anchorW + 1) * landmarkMat2[index]; obj.Landmark[1].Y = cy + (anchorH + 1) * landmarkMat3[index]; obj.Landmark[2].X = cx + (anchorW + 1) * landmarkMat4[index]; obj.Landmark[2].Y = cy + (anchorH + 1) * landmarkMat5[index]; obj.Landmark[3].X = cx + (anchorW + 1) * landmarkMat6[index]; obj.Landmark[3].Y = cy + (anchorH + 1) * landmarkMat7[index]; obj.Landmark[4].X = cx + (anchorW + 1) * landmarkMat8[index]; obj.Landmark[4].Y = cy + (anchorH + 1) * landmarkMat9[index]; obj.Prob = prob; faceObjects.Add(obj); } anchorX += featStride; } anchorY += featStride; } } }