| 482 | // models are right facing and the face may be left facing.) |
| 483 | |
| 484 | static void StartShapeAndRoi( // we have the facerect, now get the rest |
| 485 | Shape& startshape, // out: the start shape we are looking for |
| 486 | Image& face_roi, // out: ROI around face, possibly rotated upright |
| 487 | DetectorParameter& detpar_roi, // out: detpar wrt to face_roi |
| 488 | DetectorParameter& detpar, // io: detpar wrt to img (has face rect on entry) |
| 489 | const Image& img, // in: the image (grayscale) |
| 490 | const vec_Mod& mods) // in: a vector of models, one for each yaw range |
| 491 | // (use only estart, and meanshape) |
| 492 | { |
| 493 | PossiblySetRotToZero(detpar.rot); // treat small rots as zero rots |
| 494 | |
| 495 | FaceRoiAndDetectorParameter(face_roi, detpar_roi, // get ROI around face |
| 496 | img, detpar, false); |
| 497 | |
| 498 | DetectEyesAndMouth(detpar_roi, face_roi); // use OpenCV eye and mouth detectors |
| 499 | |
| 500 | // Some face detectors return the face rotation, some don't (in |
| 501 | // the call to NextFace_ just made via NextStartShapeAndRoi). |
| 502 | // If we don't have the rotation, then estimate it from the eye |
| 503 | // angle, if the eyes are available. |
| 504 | |
| 505 | if (!Valid(detpar.rot)) // don't have the face rotation? |
| 506 | { |
| 507 | detpar_roi.rot = EyeAngle(detpar_roi); |
| 508 | if (!Valid(detpar_roi.rot)) // eye angle not available? |
| 509 | detpar_roi.rot = 0; |
| 510 | PossiblySetRotToZero(detpar_roi.rot); |
| 511 | detpar.rot = detpar_roi.rot; |
| 512 | if (detpar.rot != 0) |
| 513 | { |
| 514 | // face is rotated: rotate ROI and re-get the eyes and mouth |
| 515 | |
| 516 | // TODO: Prevent bogus OpenCV assert fail face_roi.data == img.data. |
| 517 | face_roi = Image(0,0); |
| 518 | |
| 519 | FaceRoiAndDetectorParameter(face_roi, detpar_roi, img, detpar, false); |
| 520 | DetectEyesAndMouth(detpar_roi, face_roi); // use OpenCV eye and mouth detectors |
| 521 | } |
| 522 | } |
| 523 | TraceEyesMouth(face_roi, detpar_roi); |
| 524 | if (trace_g) |
| 525 | lprintf("%-6.6s yaw %3.0f rot %3.0f ", |
| 526 | EyawAsString(detpar_roi.eyaw), detpar_roi.yaw, detpar_roi.rot); |
| 527 | else |
| 528 | logprintf("%-6.6s yaw %3.0f rot %3.0f ", |
| 529 | EyawAsString(detpar_roi.eyaw), detpar_roi.yaw, detpar_roi.rot); |
| 530 | |
| 531 | // select an ASM model based on the face's yaw |
| 532 | const Mod* mod = mods[std::abs(EyawAsModIndex(detpar_roi.eyaw, mods))]; |
| 533 | |
| 534 | const ESTART estart = mod->Estart_(); |
| 535 | |
| 536 | startshape = StartShapeFromDetPar(detpar_roi, |
| 537 | face_roi, mod->MeanShape_(), estart); |
| 538 | |
| 539 | detpar.lex = detpar_roi.lex; |
| 540 | |
| 541 | if (IsLeftFacing(detpar_roi.eyaw)) |
no test coverage detected