void PinnedStartShapeAndRoi( // use the pinned landmarks to init the start shape Shape& startshape, // out: the start shape (in ROI frame) Image& face_roi, // out: ROI around face, possibly rotated upright DetPar& detpar_roi, // out: detpar wrt to face_roi DetPar& detpar, // out: detpar wrt to img Shape& pinned_roi, // out: pinned arg translated to ROI frame const Image& img, // in: the image (grayscale) const vec_Mod& mods, // in: a vector of models, one for each yaw range const Shape& pinned) // in: manually pinned landmarks { double rot, yaw; EstRotAndYawFrom5PointShape(rot, yaw, As5PointShape(pinned, mods[0]->MeanShape_())); const EYAW eyaw = DegreesAsEyaw(yaw, NSIZE(mods)); const int imod = EyawAsModIndex(eyaw, mods); // select ASM model based on yaw if (trace_g) lprintf("%-6.6s yaw %3.0f rot %3.0f ", EyawAsString(eyaw), yaw, rot); pinned_roi = pinned; // use pinned_roi as a temp shape we can change Image workimg(img); // possibly flipped image if (IsLeftFacing(eyaw)) // left facing? (our models are for right facing faces) { pinned_roi = FlipShape(pinned_roi, workimg.cols); FlipImgInPlace(workimg); } const Mod* mod = mods[ABS(imod)]; startshape = PinMeanShape(pinned_roi, mod->MeanShape_()); startshape = mod->ConformShapeToMod_Pinned_(startshape, pinned_roi); detpar = PseudoDetParFromStartShape(startshape, rot, yaw, NSIZE(mods)); if (IsLeftFacing(eyaw)) detpar.rot *= -1; FaceRoiAndDetPar(face_roi, detpar_roi, workimg, detpar, false); startshape = ImgShapeToRoiFrame(startshape, detpar_roi, detpar); pinned_roi = ImgShapeToRoiFrame(pinned_roi, detpar_roi, detpar); // following line not strictly necessary because don't actually need eyes/mouth InitDetParEyeMouthFromShape(detpar_roi, startshape); if (IsLeftFacing(eyaw)) { detpar = FlipDetPar(detpar, img.cols); detpar.rot = -detpar.rot; detpar_roi.x += 2. * (face_roi.cols/2. - detpar_roi.x); } }
void FaceRoiAndDetPar( // get ROI around the face, rotate if necessary Image& face_roi, // out DetPar& detpar_roi, // out: detpar wrt the ROI const Image& img, // in: original image const DetPar& detpar, // in: wrt img frame, only x,y,w,h,rot used bool flip, // in: mirror the ROI? double botfrac, // in: default ROI_FRAC double leftfrac, // in: dist from center to left margin double topfrac, // in double rightfrac) // in { Rect rect_roi = RoiRect(detpar, img.cols, img.rows, flip, botfrac, leftfrac, topfrac, rightfrac); detpar_roi = ImgDetParToRoiFrame(detpar, rect_roi); // following "if"s are for efficiency (avoid rotation etc. when possible). if (detpar.rot == 0 && IsRoiEntireImg(rect_roi, img.cols, img.rows)) face_roi = img; else if (!Valid(detpar.rot) || detpar.rot == 0) face_roi = Image(img, rect_roi); else // rotate image so face is upright, results go into face_roi warpAffine(Image(img, rect_roi), face_roi, getRotationMatrix2D(cv::Point2f(float(detpar_roi.x), float(detpar_roi.y)), -detpar.rot, 1.), cv::Size(face_roi.cols, face_roi.rows), cv::INTER_AREA, cv::BORDER_REPLICATE); // TODO For efficiency could combine this flip with above rot img when possible? if (flip) FlipImgInPlace(face_roi); }
static void StartShapeAndRoi( // we have the facerect, now get the rest Shape& startshape, // out: the start shape we are looking for Image& face_roi, // out: ROI around face, possibly rotated upright DetPar& detpar_roi, // out: detpar wrt to face_roi DetPar& detpar, // io: detpar wrt to img (has face rect on entry) const Image& img, // in: the image (grayscale) const vec_Mod& mods, // in: a vector of models, one for each yaw range // (use only estart, and meanshape) StasmCascadeClassifier cascade) { PossiblySetRotToZero(detpar.rot); // treat small rots as zero rots FaceRoiAndDetPar(face_roi, detpar_roi, // get ROI around face img, detpar, false); DetectEyesAndMouth(detpar_roi, // use OpenCV eye and mouth detectors face_roi, cascade); // Some face detectors return the face rotation, some don't (in // the call to NextFace_ just made via NextStartShapeAndRoi). // If we don't have the rotation, then estimate it from the eye // angle, if the eyes are available. if (!Valid(detpar.rot)) // don't have the face rotation? { detpar_roi.rot = EstRotFromEyeAngle(detpar_roi); PossiblySetRotToZero(detpar_roi.rot); detpar.rot = detpar_roi.rot; if (detpar.rot != 0) { // face is rotated: rotate ROI and re-get the eyes and mouth // TODO: Prevent bogus OpenCV assert fail face_roi.data == img.data. face_roi = Image(0,0); FaceRoiAndDetPar(face_roi, detpar_roi, img, detpar, false); DetectEyesAndMouth(detpar_roi, // use OpenCV eye and mouth detectors face_roi, cascade); } } if (trace_g) lprintf("%-6.6s yaw %3.0f rot %3.0f ", EyawAsString(detpar_roi.eyaw), detpar_roi.yaw, detpar_roi.rot); else logprintf("%-6.6s yaw %3.0f rot %3.0f ", EyawAsString(detpar_roi.eyaw), detpar_roi.yaw, detpar_roi.rot); // select an ASM model based on the face's yaw const Mod* mod = mods[ABS(EyawAsModIndex(detpar_roi.eyaw, mods))]; const ESTART estart = mod->Estart_(); CV_Assert(estart == ESTART_EYES || estart == ESTART_EYE_AND_MOUTH); startshape = StartShapeFromDetPar(detpar_roi, face_roi, mod->MeanShape_(), estart); if (IsLeftFacing(detpar_roi.eyaw)) FlipImgInPlace(face_roi); JitterPointsAt00(startshape); }