static void DiscardMissizedFaces( vec_DetPar& detpars) // io { // constants (TODO These have not yet been rigorously empirically adjusted.) static const double MIN_WIDTH = 1.33; // as fraction of median width static const double MAX_WIDTH = 1.33; // as fraction of median width if (NSIZE(detpars) >= 3) // need at least 3 faces { // sort the faces on their width (smallest first) so can get median width sort(detpars.begin(), detpars.end(), DecreasingWidth); const int median = cvRound(detpars[NSIZE(detpars) / 2].width); const int minallowed = cvRound(median / MIN_WIDTH); const int maxallowed = cvRound(MAX_WIDTH * median); // keep only faces that are not too big or small vec_DetPar all_detpars(detpars); detpars.resize(0); for (int iface = 0; iface < NSIZE(all_detpars); iface++) { DetPar* face = &all_detpars[iface]; if (face->width >= minallowed && face->width <= maxallowed) detpars.push_back(*face); else if (trace_g || TRACE_IMAGES) lprintf("[discard face%d of %d]", iface, NSIZE(all_detpars)); } } }
void DetectFaces( // all face rects into detpars vec_DetPar& detpars, // out const Image& img, // in int minwidth) // in: as percent of img width { CV_Assert(!facedet_g.empty()); // check that OpenFaceDetector_ was called int leftborder = 0, topborder = 0; // border size in pixels Image bordered_img(BORDER_FRAC == 0? img: EnborderImg(leftborder, topborder, img)); // Detection results are very slightly better with equalization // (tested on the MUCT images, which are not pre-equalized), and // it's quick enough to equalize (roughly 10ms on a 1.6 GHz laptop). Image equalized_img; cv::equalizeHist(bordered_img, equalized_img); CV_Assert(minwidth >= 1 && minwidth <= 100); // TODO smallest bioid faces are about 80 pixels width, hence 70 below const int minpix = MAX(minwidth <= 5? 70: 100, cvRound(img.cols * minwidth / 100.)); // the params below are accurate but slow static const double SCALE_FACTOR = 1.1; static const int MIN_NEIGHBORS = 3; static const int DETECTOR_FLAGS = 0; vec_Rect facerects = // all face rects in image Detect(equalized_img, facedet_g, NULL, SCALE_FACTOR, MIN_NEIGHBORS, DETECTOR_FLAGS, minpix); // copy face rects into the detpars vector detpars.resize(NSIZE(facerects)); for (int i = 0; i < NSIZE(facerects); i++) { Rect* facerect = &facerects[i]; DetPar detpar; // detpar constructor sets all fields INVALID // detpar.x and detpar.y is the center of the face rectangle detpar.x = facerect->x + facerect->width / 2.; detpar.y = facerect->y + facerect->height / 2.; detpar.x -= leftborder; // discount the border we added earlier detpar.y -= topborder; detpar.width = double(facerect->width); detpar.height = double(facerect->height); detpar.yaw = 0; // assume face has no yaw in this version of Stasm detpar.eyaw = EYAW00; detpars[i] = detpar; } }
void DetectFaces( // all face rects into detpars vec_DetPar& detpars, // out const Image& img, // in int minwidth) // in: as percent of img width { //Polyphemus version: we already have the face, returns the whole image rectangle bool changedForPolyphemus = true; //UO //CV_Assert(!facedet_g.empty()); // check that OpenFaceDetector_ was called //OU if(changedForPolyphemus) { /* #ifdef WITH_GUI cv::namedWindow("StasmFace", CV_WINDOW_NORMAL); cv::imshow("StasmFace", img);//cv::Mat(img, Rect(0,0,img.cols, img.rows))); #endif */ //if (img.cols != 800 || img.rows != 600) // sanity check //Err("Image must be 800x600 (your image is %dx%d)", img.cols, img.rows); DetPar detpar; detpar.x = img.cols / 2.; // approximate center of face detpar.y = img.rows / 2.; detpar.width = img.cols; // approximate size of face detpar.height = img.rows; detpar.yaw = 0; detpar.eyaw = EYAW00; detpars.resize(1); detpars[0] = detpar; //minwidth = 40; } else { int leftborder = 0, topborder = 0; // border size in pixels Image bordered_img(BORDER_FRAC == 0? img: EnborderImg(leftborder, topborder, img)); // Detection results are very slightly better with equalization // (tested on the MUCT images, which are not pre-equalized), and // it's quick enough to equalize (roughly 10ms on a 1.6 GHz laptop). Image equalized_img; cv::equalizeHist(bordered_img, equalized_img); CV_Assert(minwidth >= 1 && minwidth <= 100); // TODO smallest bioid faces are about 80 pixels width, hence 70 below const int minpix = MAX(minwidth <= 5? 70: 100, cvRound(img.cols * minwidth / 100.)); // the params below are accurate but slow static const double SCALE_FACTOR = 1.1; static const int MIN_NEIGHBORS = 3; static const int DETECTOR_FLAGS = 0; vec_Rect facerects = // all face rects in image Detect(equalized_img, facedet_g, NULL, SCALE_FACTOR, MIN_NEIGHBORS, DETECTOR_FLAGS, minpix); // copy face rects into the detpars vector detpars.resize(NSIZE(facerects)); for (int i = 0; i < NSIZE(facerects); i++) { Rect* facerect = &facerects[i]; DetPar detpar; // detpar constructor sets all fields INVALID // detpar.x and detpar.y is the center of the face rectangle detpar.x = facerect->x + facerect->width / 2.; detpar.y = facerect->y + facerect->height / 2.; detpar.x -= leftborder; // discount the border we added earlier detpar.y -= topborder; detpar.width = double(facerect->width); detpar.height = double(facerect->height); detpar.yaw = 0; // assume face has no yaw in this version of Stasm detpar.eyaw = EYAW00; detpars[i] = detpar; } } }