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)); }
static Shape AlignMeanShapeToBothEyesMouth( const DetPar& detpar, // in const Shape& meanshape) // in { if (trace_g) lprintf("AlignToBothEyesMouth "); 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.; const Shape shape17(Shape17(meanshape)); mean_tri(0, IX) = shape17(L17_LPupil, IX); // left eye mean_tri(0, IY) = shape17(L17_LPupil, IY); mean_tri(1, IX) = shape17(L17_RPupil, IX); // right eye mean_tri(1, IY) = shape17(L17_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 TransformShape(meanshape, AlignmentMat(mean_tri, det_tri)); }