| 47 | } |
| 48 | |
| 49 | void caffe_mtcnn::detect(cv::Mat& img, std::vector<face_box>& face_list) |
| 50 | { |
| 51 | cv::Mat working_img; |
| 52 | float alpha = 0.0078125; |
| 53 | float mean = 127.5; |
| 54 | |
| 55 | img.convertTo(working_img, CV_32FC3); |
| 56 | |
| 57 | working_img = (working_img - mean) * alpha; |
| 58 | |
| 59 | working_img = working_img.t(); |
| 60 | |
| 61 | cv::cvtColor(working_img, working_img, cv::COLOR_BGR2RGB); |
| 62 | |
| 63 | int img_h = working_img.rows; |
| 64 | int img_w = working_img.cols; |
| 65 | |
| 66 | std::vector<scale_window> win_list; |
| 67 | |
| 68 | std::vector<face_box> total_pnet_boxes; |
| 69 | std::vector<face_box> total_rnet_boxes; |
| 70 | std::vector<face_box> total_onet_boxes; |
| 71 | |
| 72 | cal_pyramid_list(img_h, img_w, min_size_, factor_, win_list); |
| 73 | |
| 74 | for(unsigned int i = 0; i < win_list.size(); i++) |
| 75 | { |
| 76 | std::vector<face_box> boxes; |
| 77 | |
| 78 | run_PNet(working_img, win_list[i], boxes); |
| 79 | |
| 80 | total_pnet_boxes.insert(total_pnet_boxes.end(), boxes.begin(), boxes.end()); |
| 81 | } |
| 82 | |
| 83 | std::vector<face_box> pnet_boxes; |
| 84 | |
| 85 | process_boxes(total_pnet_boxes, img_h, img_w, pnet_boxes); |
| 86 | |
| 87 | if(!pnet_boxes.size()) |
| 88 | return; |
| 89 | |
| 90 | run_RNet(working_img, pnet_boxes, total_rnet_boxes); |
| 91 | |
| 92 | std::vector<face_box> rnet_boxes; |
| 93 | process_boxes(total_rnet_boxes, img_h, img_w, rnet_boxes); |
| 94 | |
| 95 | if(!rnet_boxes.size()) |
| 96 | return; |
| 97 | |
| 98 | run_ONet(working_img, rnet_boxes, total_onet_boxes); |
| 99 | |
| 100 | // calculate the landmark |
| 101 | for(unsigned int i = 0; i < total_onet_boxes.size(); i++) |
| 102 | { |
| 103 | face_box& box = total_onet_boxes[i]; |
| 104 | |
| 105 | float h = box.x1 - box.x0 + 1; |
| 106 | float w = box.y1 - box.y0 + 1; |