| 42 | } |
| 43 | |
| 44 | void DetectFaces( // all face rects into detpars |
| 45 | std::vector<DetectorParameter>& detpars, // out |
| 46 | const Image& img, // in |
| 47 | int minwidth) // in: as percent of img width |
| 48 | { |
| 49 | CV_Assert(!facedet_g.empty()); // check that OpenFaceDetector_ was called |
| 50 | |
| 51 | int leftborder = 0, topborder = 0; // border size in pixels |
| 52 | Image bordered_img(BORDER_FRAC == 0? |
| 53 | img: EnborderImg(leftborder, topborder, img)); |
| 54 | |
| 55 | // Detection results are very slightly better with equalization |
| 56 | // (tested on the MUCT images, which are not pre-equalized), and |
| 57 | // it's quick enough to equalize (roughly 10ms on a 1.6 GHz laptop). |
| 58 | |
| 59 | Image equalized_img; |
| 60 | cv::equalizeHist(bordered_img, equalized_img); |
| 61 | |
| 62 | CV_Assert(minwidth >= 1 && minwidth <= 100); |
| 63 | |
| 64 | // TODO smallest bioid faces are about 80 pixels width, hence 70 below |
| 65 | const int minpix = |
| 66 | MAX(minwidth <= 5? 70: 100, cvRound(img.cols * minwidth / 100.)); |
| 67 | |
| 68 | // the params below are accurate but slow |
| 69 | static const double SCALE_FACTOR = 1.1; |
| 70 | static const int MIN_NEIGHBORS = 3; |
| 71 | static const int DETECTOR_FLAGS = 0; |
| 72 | |
| 73 | vec_Rect facerects = // all face rects in image |
| 74 | Detect(equalized_img, facedet_g, NULL, |
| 75 | SCALE_FACTOR, MIN_NEIGHBORS, DETECTOR_FLAGS, minpix); |
| 76 | |
| 77 | // copy face rects into the detpars vector |
| 78 | |
| 79 | detpars.resize(NSIZE(facerects)); |
| 80 | for (int i = 0; i < NSIZE(facerects); i++) |
| 81 | { |
| 82 | Rect* facerect = &facerects[i]; |
| 83 | DetectorParameter detpar; // detpar constructor sets all fields INVALID |
| 84 | // detpar.x and detpar.y is the center of the face rectangle |
| 85 | detpar.x = facerect->x + facerect->width / 2.; |
| 86 | detpar.y = facerect->y + facerect->height / 2.; |
| 87 | detpar.x -= leftborder; // discount the border we added earlier |
| 88 | detpar.y -= topborder; |
| 89 | detpar.width = double(facerect->width); |
| 90 | detpar.height = double(facerect->height); |
| 91 | detpar.yaw = 0; // assume face has no yaw in this version of Stasm |
| 92 | detpar.eyaw = EYAW00; |
| 93 | detpars[i] = detpar; |
| 94 | } |
| 95 | } |
| 96 | // order by increasing distance from left marg, and dist from top marg within that |
| 97 | |
| 98 | static bool IncreasingLeftMargin( // compare predicate for std::sort |
no test coverage detected