void DetectEyesAndMouth( // use OpenCV detectors to find the eyes and mouth DetPar& detpar, // io: eye and mouth fields updated, other fields untouched const Image& img) // in: ROI around face (already rotated if necessary) { #if TRACE_IMAGES CImage cimg; cvtColor(img, cimg, CV_GRAY2BGR); DesaturateImg(cimg); #endif const Rect facerect(cvRound(detpar.x - detpar.width/2), cvRound(detpar.y - detpar.height/2), cvRound(detpar.width), cvRound(detpar.height)); // possibly get the eyes detpar.lex = detpar.ley = INVALID; // mark eyes as unavailable detpar.rex = detpar.rey = INVALID; vec_Rect leyes, reyes; int ileft_best = -1, iright_best = -1; // index into leyes and reyes vecs if (!leye_det_g.empty()) // need the eyes? (depends on model estart field) { DetectAllEyes(leyes, reyes, img, detpar.eyaw, facerect); SelectEyes(ileft_best, iright_best, // indices of best left and right eye detpar.eyaw, leyes, reyes, EyeInnerRect(detpar.eyaw, facerect)); #if TRACE_IMAGES DrawEyes(cimg, leyes, reyes, ileft_best, iright_best, facerect, detpar.eyaw); #endif if (ileft_best >= 0) // left eye valid? RectToImgFrame(detpar.lex, detpar.ley, leyes[ileft_best]); if (iright_best >= 0) // right eye valid? RectToImgFrame(detpar.rex, detpar.rey, reyes[iright_best]); } // possibly get the mouth detpar.mouthx = detpar.mouthy = INVALID; // mark mouth as unavailable int imouth_best = -1; // index into mouths vector if (!mouth_det_g.empty()) // need the mouth? (depends on model estart field) { const Rect mouth_searchrect( MouthSearchRect(facerect, detpar.eyaw, ileft_best, iright_best, leyes, reyes)); vec_Rect mouths; DetectAllMouths(mouths, img, facerect, mouth_searchrect); if (!mouths.empty()) { SelectMouth(imouth_best, // get index of best mouth ileft_best, iright_best, leyes, reyes, mouths, facerect, mouth_searchrect, MouthInnerRect(facerect, detpar.eyaw, ileft_best, iright_best, leyes, reyes)); if (imouth_best >= 0) // mouth valid? { TweakMouthPosition(mouths, leyes, reyes, ileft_best, iright_best, imouth_best, detpar); RectToImgFrame(detpar.mouthx, detpar.mouthy, mouths[imouth_best]); } } #if TRACE_IMAGES DrawMouths(cimg, mouths, imouth_best, facerect, detpar.eyaw, ileft_best, iright_best, leyes, reyes); #endif } #if TRACE_IMAGES TraceEyeMouthImg(cimg, detpar, ileft_best, iright_best, imouth_best); #endif }
void DetectEyesAndMouth( // use OpenCV detectors to find the eyes and mouth DetPar& detpar, // io: eye and mouth fields updated, other fields untouched const Image& img) // in: ROI around face (already rotated if necessary) { Rect facerect(cvRound(detpar.x - detpar.width/2), cvRound(detpar.y - detpar.height/2), cvRound(detpar.width), cvRound(detpar.height)); // possibly get the eyes detpar.lex = detpar.ley = INVALID; // mark eyes as unavailable detpar.rex = detpar.rey = INVALID; vec_Rect leyes, reyes; int ileft_best = -1, iright_best = -1; // indices into leyes and reyes if (!leye_det_g.empty()) // do we need the eyes? (depends on model estart field) { DetectAllEyes(leyes, reyes, img, detpar.eyaw, facerect); SelectEyes(ileft_best, iright_best, detpar.eyaw, leyes, reyes, EyeInnerRect(detpar.eyaw, facerect)); if (ileft_best >= 0) RectToImgFrame(detpar.lex, detpar.ley, leyes[ileft_best]); if (iright_best >= 0) RectToImgFrame(detpar.rex, detpar.rey, reyes[iright_best]); } // possibly get the mouth detpar.mouthx = detpar.mouthy = INVALID; // mark mouth as unavailable if (!mouth_det_g.empty()) // do we need the mouth? (depends on model estart field) { vec_Rect mouths; DetectAllMouths(mouths, img, detpar.eyaw, facerect, ileft_best, iright_best, leyes, reyes); if (!mouths.empty()) { int imouth_best = -1; SelectMouth(imouth_best, ileft_best, iright_best, leyes, reyes, mouths, MouthInnerRect(facerect, detpar.eyaw, ileft_best, iright_best, leyes, reyes)); if (imouth_best >= 0) { TweakMouthPosition(mouths, leyes, reyes, ileft_best, iright_best, imouth_best, detpar); RectToImgFrame(detpar.mouthx, detpar.mouthy, mouths[imouth_best]); } } } }