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; }
Shape ConformShapeToMod( // Return a copy of inshape conformed to the model VEC& b, // io: eigvec weights, 2n x 1 const Shape& inshape, // in: the current position of the landmarks const Shape& meanshape, // in: n x 2 const VEC& eigvals, // in: neigs x 1 const MAT& eigvecs, // in: 2n x neigs const MAT& eigvecsi, // in: neigs x 2n, inverse of eigvecs const double bmax, // in: for LimitB const VEC& pointweights) // in: contribution of each point to the pose { Shape shape(inshape.clone()); // estimate the pose which transforms the shape into the model space // (use the b from previous iterations of the ASM) MAT modelshape(AsColVec(meanshape) + eigvecs * b); modelshape = DimKeep(modelshape, shape.rows, 2); // redim back to 2 columns const MAT pose(AlignmentMat(modelshape, shape, Buf(pointweights))); // transform the shape into the model space modelshape = TransformShape(shape, pose.inv(cv::DECOMP_LU)); // update shape model params b to match modelshape, then limit b b = eigvecsi * AsColVec(modelshape - meanshape); LimitB(b, eigvals, bmax); // generate conformedshape from the model using the limited b // (we generate as a column vec, then redim back to 2 columns) const Shape conformedshape(DimKeep(eigvecs * b, shape.rows, 2)); // back to image space return JitterPointsAt00(TransformShape(meanshape + conformedshape, pose)); }