Beispiel #1
0
static Shape AlignMeanShapeToFaceDetRect(
    const DetPar& detpar,                 // in
    const Shape&  meanshape,              // in
    double        scale,                  // in: scale the face rectangle
    const Image&  img)                    // io: the image (grayscale)
{
    if (trace_g)
        lprintf("AlignToFaceDetBox                ");

    DetPar detpar1(detpar);

    if (IsLeftFacing(detpar.eyaw))
        detpar1 = FlipDetPar(detpar, img.cols);

    CV_Assert(meanshape.rows > 0 && meanshape.cols == 2);

    const double xscale = detpar1.width  * scale / DET_FACE_WIDTH;
    const double yscale = detpar1.height * scale / DET_FACE_WIDTH;

    Shape startshape = AlignShape(meanshape,
                                     xscale,      0, detpar1.x,
                                          0, yscale, detpar1.y);

    return startshape;
}
Beispiel #2
0
static void FlipIfLeftFacing(
    Shape& shape,             // io
    EYAW   eyaw,              // in
    int    ncols)             // in
{
    if (IsLeftFacing(eyaw))
        shape = FlipShape(shape, ncols);
}
Beispiel #3
0
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);
    }
}
Beispiel #4
0
Shape RoiShapeToImgFrame(     // return shape in image frame
    const Shape&  shape,      // in: shape in roi frame
    const Image&  face_roi,   // in
    const DetPar& detpar_roi, // in: detpar wrt the ROI
    const DetPar& detpar)     // in: detpar wrt the image
{
    Shape outshape(shape.clone());
    if (IsLeftFacing(detpar.eyaw))
        outshape = FlipShape(outshape, face_roi.cols);
    if (Valid(detpar.rot) && detpar.rot)
    {
        const MAT rotmat =
            getRotationMatrix2D(cv::Point2f(float(detpar_roi.x),
                                            float(detpar_roi.y)),
                                detpar.rot, 1.);
        TransformShapeInPlace(outshape, rotmat);
    }
    return ShiftShape(outshape, detpar.x - detpar_roi.x,
                                detpar.y - detpar_roi.y);
}
Beispiel #5
0
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);

}