| 60 | } |
| 61 | |
| 62 | std::vector<Face> PriorBox::decode(const cv::Mat& loc, |
| 63 | const cv::Mat& conf, |
| 64 | const cv::Mat& iou, |
| 65 | const float ignore_score) { |
| 66 | std::vector<Face> dets; // num * [x1, y1, x2, y2, x_re, y_re, x_le, y_le, x_ml, y_ml, x_n, y_n, x_mr, y_ml] |
| 67 | |
| 68 | float* loc_v = (float*)(loc.data); |
| 69 | float* conf_v = (float*)(conf.data); |
| 70 | float* iou_v = (float*)(iou.data); |
| 71 | for (auto i = 0; i < priors.size(); ++i) { |
| 72 | // get score |
| 73 | float cls_score = conf_v[i*2+1]; |
| 74 | float iou_score = iou_v[i]; |
| 75 | // clamp |
| 76 | if (iou_score < 0.f) { |
| 77 | iou_score = 0.f; |
| 78 | } |
| 79 | else if (iou_score > 1.f) { |
| 80 | iou_score = 1.f; |
| 81 | } |
| 82 | float score = std::sqrt(cls_score * iou_score); |
| 83 | |
| 84 | // ignore low scores |
| 85 | if (score < ignore_score) { continue; } |
| 86 | |
| 87 | Face face; |
| 88 | face.score = score; |
| 89 | // get bounding box |
| 90 | float cx = (priors[i].x + loc_v[i*14+0] * variance[0] * priors[i].width) * out_w; |
| 91 | float cy = (priors[i].y + loc_v[i*14+1] * variance[0] * priors[i].height) * out_h; |
| 92 | float w = priors[i].width * exp(loc_v[i*14+2] * variance[0]) * out_w; |
| 93 | float h = priors[i].height * exp(loc_v[i*14+3] * variance[1]) * out_h; |
| 94 | float x1 = cx - w / 2; |
| 95 | float y1 = cy - h / 2; |
| 96 | face.bbox_tlwh = { x1, y1, w, h }; |
| 97 | |
| 98 | // get landmarks, loc->[right_eye, left_eye, mouth_left, nose, mouth_right] |
| 99 | float x_re = (priors[i].x + loc_v[i*14+ 4] * variance[0] * priors[i].width) * out_w; |
| 100 | float y_re = (priors[i].y + loc_v[i*14+ 5] * variance[0] * priors[i].height) * out_h; |
| 101 | float x_le = (priors[i].x + loc_v[i*14+ 6] * variance[0] * priors[i].width) * out_w; |
| 102 | float y_le = (priors[i].y + loc_v[i*14+ 7] * variance[0] * priors[i].height) * out_h; |
| 103 | float x_n = (priors[i].x + loc_v[i*14+ 8] * variance[0] * priors[i].width) * out_w; |
| 104 | float y_n = (priors[i].y + loc_v[i*14+ 9] * variance[0] * priors[i].height) * out_h; |
| 105 | float x_mr = (priors[i].x + loc_v[i*14+10] * variance[0] * priors[i].width) * out_w; |
| 106 | float y_mr = (priors[i].y + loc_v[i*14+11] * variance[0] * priors[i].height) * out_h; |
| 107 | float x_ml = (priors[i].x + loc_v[i*14+12] * variance[0] * priors[i].width) * out_w; |
| 108 | float y_ml = (priors[i].y + loc_v[i*14+13] * variance[0] * priors[i].height) * out_h; |
| 109 | face.landmarks = { |
| 110 | {x_re, y_re}, // right eye |
| 111 | {x_le, y_le}, // left eye |
| 112 | {x_n, y_n }, // nose |
| 113 | {x_mr, y_mr}, // mouth right |
| 114 | {x_ml, y_ml} // mouth left |
| 115 | }; |
| 116 | |
| 117 | dets.push_back(face); |
| 118 | } |
| 119 | |