Пример #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;
}
Пример #2
0
static Shape AlignMeanShapeToBothEyesNoMouth(
    const DetPar& detpar,                      // in
    const Shape&  meanshape)                   // in
{
    if (trace_g)
        lprintf("AlignToBothEyesNoMouth           ");

    CV_Assert(NSIZE(meanshape) > 0 && PointUsed(meanshape, 0));
    CV_Assert(Valid(detpar.lex));
    CV_Assert(Valid(detpar.rex));

    Shape meanline(2, 2), detline(2, 2);       // line from eye to eye

    meanline(0, IX) = meanshape(L_LPupil, IX); // left eye
    meanline(0, IY) = meanshape(L_LPupil, IY);
    meanline(1, IX) = meanshape(L_RPupil, IX); // right eye
    meanline(1, IY) = meanshape(L_RPupil, IY);

    detline(0, IX) = detpar.lex;               // left eye
    detline(0, IY) = detpar.ley;
    detline(1, IX) = detpar.rex;               // right eye
    detline(1, IY) = detpar.rey;

    return AlignShape(meanshape, AlignmentMat(meanline, detline));
}
Пример #3
0
static Shape AlignMeanShapeToRightEyeAndMouth(
    const DetPar& detpar,                             // in
    const Shape&  meanshape)                          // in
{
    if (trace_g)
        lprintf("AlignToRightEyeAndMouth          ");

    CV_Assert(NSIZE(meanshape) > 0 && PointUsed(meanshape, 0));
    CV_Assert(!Valid(detpar.lex));   // left eye invalid? (else why are we here?)
    CV_Assert(Valid(detpar.rex));    // right eye valid?
    CV_Assert(Valid(detpar.mouthx)); // mouth valid?

    const double x_meanmouth =
       (meanshape(L_CTopOfTopLip, IX) + meanshape(L_CBotOfBotLip, IX)) / 2;

    const double y_meanmouth =
       (meanshape(L_CTopOfTopLip, IY) + meanshape(L_CBotOfBotLip, IY)) / 2;

    Shape meanline(2, 2), detline(2, 2);              // line from eye to mouth

    meanline(0, IX) = meanshape(L_RPupil, IX);        // right eye
    meanline(0, IY) = meanshape(L_RPupil, IY);
    meanline(1, IX) = x_meanmouth;                    // mouth
    meanline(1, IY) = y_meanmouth;

    detline(0, IX) = detpar.rex;                      // right eye
    detline(0, IY) = detpar.rey;
    detline(1, IX) = detpar.mouthx;                   // mouth
    detline(1, IY) = detpar.mouthy;

    return AlignShape(meanshape, AlignmentMat(meanline, detline));
}
Пример #4
0
//-----------------------------------------------------------------------------
void GetStartShapeFromPreviousSearch (SHAPE &StartShape,     // out
        const SHAPE &PrevShape,     // in: final shape from previous search
        const SHAPE &MeanShape)     // in
{
if (MeanShape.nrows() == PrevShape.nrows())
    StartShape = PrevShape;
else if (MeanShape.nrows() < PrevShape.nrows())
    {
    StartShape = PrevShape;
    StartShape.dimKeep(MeanShape.nrows(), 2);
    }
else    // MeanShape.nrows() > PrevShape.nrows()
    {
    // The algorithm below is: use points from PrevShape where possible,
    // but of a point is unused in PrevShape, use the point from the
    // aligned MeanShape instead.

    // use "assign" not "=" because dims may be different
    StartShape.assign(MeanShape);
    SHAPE Combined(PrevShape);
    Combined.dimKeep(MeanShape.nrows(), 2);
    AlignShape(StartShape, Combined);
    const int nRows = PrevShape.nrows();
    for (unsigned iRow = 0; iRow < unsigned(nRows); iRow++)
        if (fPointUsed(StartShape, iRow))
            StartShape.row(iRow) = PrevShape.row(iRow);
    }
}
Пример #5
0
static Shape AlignMeanShapeToBothEyesEstMouth(
    const DetPar& detpar,                      // in
    const Shape&  meanshape)                   // in
{
    // .48 was tested to give slightly better worse case results than .50
    static double EYEMOUTH_TO_FACERECT_RATIO = .48;

    if (trace_g)
        lprintf("AlignToBothEyesNoMouth(EstMouth) ");

    CV_Assert(NSIZE(meanshape) > 0 && PointUsed(meanshape, 0));
    CV_Assert(Valid(detpar.lex));
    CV_Assert(Valid(detpar.rex));

    // estimate the mouth's position

    double x_eyemid = 0;
    switch (detpar.eyaw)
    {
        case EYAW00:                                 //  mid point
            x_eyemid = .50 * detpar.lex + .50 * detpar.rex;
            break;
        // TODO The constants below have not been empirically optimized.
        case EYAW_45:                                // closer to left eye
            x_eyemid = .30 * detpar.lex + .70 * detpar.rex;
            break;
        case EYAW_22:                                // closer to left eye
            x_eyemid = .30 * detpar.lex + .70 * detpar.rex;
            break;
        case EYAW22:                                 // closer to right eye
            x_eyemid = .30 * detpar.lex + .70 * detpar.rex;
            break;
        case EYAW45:                                 // closer to right eye
            x_eyemid = .30 * detpar.lex + .70 * detpar.rex;
            break;
        default:
            Err("AlignMeanShapeToBothEyesEstMouth: Invalid eyaw %d", detpar.eyaw);
            break;
    }
    const double y_eyemid = (detpar.ley + detpar.rey) / 2;

    Shape mean_tri(3, 2), det_tri(3, 2);             // triangle of eyes and mouth

    mean_tri(0, IX) = meanshape(L_LPupil, IX);       // left eye
    mean_tri(0, IY) = meanshape(L_LPupil, IY);
    mean_tri(1, IX) = meanshape(L_RPupil, IX);       // right eye
    mean_tri(1, IY) = meanshape(L_RPupil, IY);
    mean_tri(2, IX) = meanshape(L_CBotOfBotLip, IX); // mouth
    mean_tri(2, IY) = meanshape(L_CBotOfBotLip, IY);

    det_tri(0, IX) = detpar.lex;                     // left eye
    det_tri(0, IY) = detpar.ley;
    det_tri(1, IX) = detpar.rex;                     // right eye
    det_tri(1, IY) = detpar.rey;
    det_tri(2, IX) = x_eyemid;                       // mouth
    det_tri(2, IY) = y_eyemid + EYEMOUTH_TO_FACERECT_RATIO * detpar.width;

    return AlignShape(meanshape, AlignmentMat(mean_tri, det_tri));
}
Пример #6
0
SHAPE
ConformShapeToModel (Vec &b,                    // io
                     const SHAPE &Shape,        // in
                     const ASM_MODEL &Model,    // in
                     int iLev,                  // in
                     bool fShapeModelFinalIter) // in
{
Vec MeanShape(Model.AsmLevs[iLev].MeanShape);

// For calculations below we need to see shapes (nrows x 2) as vectors (1 x 2*nrows).
// Note that this is a "view" so if you change MeanShapeAsVec you
// are changing MeanShape too, and vice versa.

VecView MeanShapeAsVec(MeanShape.viewAsCol());

// find y, the model shape that best fits Shape

SHAPE OutShape(Shape);
int nEigs = Model.AsmLevs[iLev].nEigs;
double BMax = Model.AsmLevs[iLev].BMax;
if (fShapeModelFinalIter)
    {
    // final iter in main ASM search loop so loosen up the model
    nEigs = Model.AsmLevs[iLev].nEigsFinal;
    BMax = Model.AsmLevs[iLev].BMaxFinal;
    }
ASSERT(BMax > 0);
ASSERT(nEigs > 0);
SHAPE x(Shape.nrows(), 2);
x.viewAsCol() = MeanShapeAsVec + Model.EigVecs * b; // generate a model shape x
Mat Pose(AlignShape(x, Shape));
SHAPE y(TransformShape(Shape, Pose.inverse())); // project Shape into model space

// update model params b to match y
// We limit b to ensure we stay within model limits

b = Model.EigInverse * (y.viewAsCol() - MeanShapeAsVec);
LimitB(b, Model.AsmLevs[iLev].EigVals, nEigs, BMax);

// generate OutShape from the model using our calculated b,
// and align OutShape to Shape

OutShape.viewAsCol() = Model.EigVecs * b;
OutShape = TransformShape(Model.AsmLevs[iLev].MeanShape + OutShape, Pose);
return OutShape;
}
Пример #7
0
AAM_Shape AAMFit::InitShape( const AAM_Shape& pMeanShape, CvRect *pR, int pType = 0 )
{
	AAM_Shape detShape;
	AAM_Shape startShape;

	detShape.resize(2);
	detShape[0].x = pR->x;
	detShape[0].y = pR->y;
	detShape[1].x = detShape[0].x + pR->width;
	detShape[1].y = detShape[0].y + pR->height;

	if( pType == AAM_FIT_FACE )
		AdjustFaceShape(detShape);
	else if( pType == AAM_FIT_MOUTH )
		AdjustMouthShape(detShape);

	AlignShape(startShape, detShape, pMeanShape);

	return startShape;
}
Пример #8
0
static Shape PinMeanShape(  // align mean shape to the pinned points
    const Shape& pinned,    // in: at least two of these points must be set
    const Shape& meanshape) // in
{
    CV_Assert(pinned.rows == meanshape.rows);

    int ipoint, nused = 0;  // number of points used in pinned
    for (ipoint = 0; ipoint < meanshape.rows; ipoint++)
        if (PointUsed(pinned, ipoint))
            nused++;

    if (nused < 2)
        Err("Need at least two pinned landmarks");

    // Create an anchor shape (the pinned landmarks) and an alignment shape (the
    // points in meanshape that correspond to those pinned landmarks).  Do that by
    // copying the used points in pinned to pinned_used, and the corresponding
    // points in meanshape to meanused.

    Shape pinned_used(nused, 2), mean_used(nused, 2);
    int i = 0;
    for (ipoint = 0; ipoint < meanshape.rows; ipoint++)
        if (PointUsed(pinned, ipoint))
        {
            pinned_used(i, IX) = pinned(ipoint, IX);
            pinned_used(i, IY) = pinned(ipoint, IY);
            mean_used(i, IX)   = meanshape(ipoint, IX);
            mean_used(i, IY)   = meanshape(ipoint, IY);
            i++;
        }
    CV_Assert(i == nused);

    // transform meanshape to pose generated by aligning mean_used to pinned_used
    Shape TransformedShape(
                    AlignShape(meanshape, AlignmentMat(mean_used, pinned_used)));

    return JitterPointsAt00(TransformedShape);
}
Пример #9
0
static Shape AlignMeanShapeToBothEyesAndMouth(
    const DetPar& detpar,                      // in
    const Shape&  meanshape)                   // in
{
    if (trace_g)
        lprintf("AlignToBothEyesAndMouth          ");

    CV_Assert(NSIZE(meanshape) > 0 && PointUsed(meanshape, 0));
    CV_Assert(Valid(detpar.mouthx));
    CV_Assert(Valid(detpar.lex));
    CV_Assert(Valid(detpar.rex));

    Shape mean_tri(3, 2), det_tri(3, 2);       // triangle of eyes and mouth

    const double x_meanmouth =
       (meanshape(L_CTopOfTopLip, IX) + meanshape(L_CBotOfBotLip, IX)) / 2.;

    const double y_meanmouth =
       (meanshape(L_CTopOfTopLip, IY) + meanshape(L_CBotOfBotLip, IY)) / 2.;

    mean_tri(0, IX) = meanshape(L_LPupil, IX); // left eye
    mean_tri(0, IY) = meanshape(L_LPupil, IY);
    mean_tri(1, IX) = meanshape(L_RPupil, IX); // right eye
    mean_tri(1, IY) = meanshape(L_RPupil, IY);
    mean_tri(2, IX) = x_meanmouth;             // mouth
    mean_tri(2, IY) = y_meanmouth;

    det_tri(0, IX) = detpar.lex;               // left eye
    det_tri(0, IY) = detpar.ley;
    det_tri(1, IX) = detpar.rex;               // right eye
    det_tri(1, IY) = detpar.rey;
    det_tri(2, IX) = detpar.mouthx;            // mouth
    det_tri(2, IY) = detpar.mouthy;

    return AlignShape(meanshape, AlignmentMat(mean_tri, det_tri));
}