📄 atland.cpp
字号:
// $masm\atland.cpp 1.5 milbo$// Warning: this is raw research code -- expect it to be quite messy.//-----------------------------------------------------------------------------// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// A copy of the GNU General Public License is available at// http://www.r-project.org/Licenses///-----------------------------------------------------------------------------#include "all.hpp"static int igLandmarks[CONF_nMaxLandmarks]; // igLandmarks[iNewLandmark] = iOldLandmark: iNewLandmark 0..nWantedLandmarks, iOldLandmark 0..OrgShape.nrows()static int igTranslatedLandmarks[CONF_nMaxLandmarks]; // igTranslatedLandmarks[iOldLandmark] = iNewLandmarkstatic tLand gLandTab[CONF_nMaxLandmarks]; // gLandTab[iLandmark] gives details of iLandmarkstatic int ngInitWantedPoints; // parameters used to initialize above tablesstatic int ngPointsInit;//-----------------------------------------------------------------------------// check for coding errs in the landmark tablestatic void CheckLandmarks (const tLand Lands[], int nPoints) // io{// check consistency of partner pointsfor (int iPoint = 0; iPoint < nPoints; iPoint++) { int iPartner = Lands[iPoint].iPartner; if (iPartner >= 0) { DASSERT(iPartner < nPoints); DASSERT(iPoint == Lands[iPartner].iPartner); // make sure my partner points back to me // make sure partner has same attributes as me unsigned Bits = (Lands[iPoint].Bits & (FA_Beard|FA_Mustache|FA_Glasses)); unsigned Bits1 = (Lands[iPartner].Bits & (FA_Beard|FA_Mustache|FA_Glasses)); ASSERT(Bits == Bits1); } }}//-----------------------------------------------------------------------------// Return an integral random number in the range 0 .. n-1// We use our own random number generator so we can see it to different values// without affecting other random number generators elsewhere.// The random number generator doesn't have to be very good so this strategy is ok.//// This code was lifted from the MSC run time library rand().//// TODO replace this routine with my generic rand routine#if CONF_fShuffleLandmarksstatic int ngHoldRand = CONF_nRandSeedForShuffle;static int RandForShuffleLandmarks (int n){return (((ngHoldRand = ngHoldRand * 214013L + 2531011L) >> 16) & 0x7fff) % n;}#endif//-----------------------------------------------------------------------------// This just calls the STL random_shuffle() on the given integer array#if CONF_fShuffleLandmarksstatic void ShuffleLandmarks (int iNew[], // out const int iOld[], int nPoints) // in{IntVec v; v.resize(nPoints);for (int i = 0; i < nPoints; i++) v[i] = iOld[i];random_shuffle(v.begin(), v.end(), pointer_to_unary_function<int, int>(RandForShuffleLandmarks));for (i = 0; i < nPoints; i++) iNew[i] = v[i];}#endif//-----------------------------------------------------------------------------// init igLandmarks and gLandTabvoid InitLandTabs (int nWantedPoints, int nPoints){if (ngInitWantedPoints != nWantedPoints || ngPointsInit != nPoints) // tables not yet initialized? { DASSERT(nWantedPoints <= CONF_nMaxLandmarks); // don't want overflow in igLandmarks DASSERT(nWantedPoints < sizeof(igTransM6) / sizeof(igTransM6[0])); // nWantedPoints < nbr elems of igTransM6 ngPointsInit = nPoints; ngInitWantedPoints = nWantedPoints; CheckLandmarks(&gLandTabAll[0], sizeof(gLandTabAll)/sizeof(gLandTabAll[0])); // check for coding errs in the landmark table#if CONF_fShuffleLandmarks ShuffleLandmarks(igLandmarks, igTransM6, nPoints);#else memcpy(igLandmarks, igTransM6, nWantedPoints * sizeof(int));#endif for (int i = 0; i < nWantedPoints; i++) gLandTab[i] = gLandTabAll[igLandmarks[i]]; // structure assignment for (i = 0; i < CONF_nMaxLandmarks; i++) igTranslatedLandmarks[i] = -1; // out of range value to indicate an unused point for (i = 0; i < nWantedPoints; i++) igTranslatedLandmarks[igLandmarks[i]] = i; }}//-----------------------------------------------------------------------------const tLand *pSelectLand (int nPoints) // in{DASSERT(ngInitWantedPoints && ngPointsInit); // check that info tabs are already initializedreturn &gLandTab[0];}//-----------------------------------------------------------------------------const int iTranslatedPoint (int iPoint){DASSERT(ngInitWantedPoints && ngPointsInit); // check that info tabs are already initializedreturn igTranslatedLandmarks[iPoint];}//-----------------------------------------------------------------------------// Translate Shape from file format to internal format.// This also intializes igLandmarks and gLandTab.//// It's assumed that Shape was read from a shape file, and landmarks may not correspond our internal scheme.// We move the points from the file format to out internal format,// and set points not available in our internal format to 0,0 (which means "unused").//// If nSynthesizedEyePoints is nonzero, we generate generate extra right eye points using// left eye points. This is for using the extra M4 left eye landmarks.// The default value is 0, to not synthesize points. nWantedPoints includes nSynthesizedEyePoints.bool fConvertShapeToInternalFormat (Mat &Shape, // io int nWantedPoints, eSubModel iSubModel, // in int nSynthesizedEyePoints, // in StringVec *pTagStrings, int iShape) // in: TODO for debugging, can be removed{bool fChanged = false;InitLandTabs(nWantedPoints, Shape.nrows()); // init igLandmarks and gLandTab#if CONF_nGenLandmarksUsedInternally != 0// select a translation tableconst int *pTransTab;int nrows = Shape.nrows();if (nrows == CONF_nPointsXm2vts + CONF_nFencePosts || nrows == CONF_nPoints84) pTransTab = igLandmarks;else if (nrows == CONF_nPointsBioid20 || nrows == CONF_nPointsBioid22) //TODO correct? { DASSERT(!CONF_fShuffleLandmarks); // CONF_fShuffleLandmarks currently only tested for XM2VTS and M4 pTransTab = igTransBioId; }else if (nrows == NBR_AR_POINTS) { DASSERT(!CONF_fShuffleLandmarks); pTransTab = igTransAr; }else if (nrows > CONF_nMaxLandmarks) Err("fConvertShapeToInternalFormat illegal nrows %d\n", nrows);else pTransTab = igLandmarks;// do the translation, moving points from ShapeOrg to their new positions in ShapeMat ShapeOrg(Shape);Shape.dimClear(nWantedPoints, 2); // resize and clear to zero, unused points will remain at 0if (nWantedPoints != nrows) fChanged = true;for (int iPoint = 0; iPoint < nWantedPoints; iPoint++) { int iOrgPoint = pTransTab[iPoint]; if (iOrgPoint >= 0 && iOrgPoint < nrows) { Shape(iPoint, VX) = ShapeOrg(iOrgPoint, VX); Shape(iPoint, VY) = ShapeOrg(iOrgPoint, VY); if (iPoint != iOrgPoint) fChanged = true; } }// Do a possible 2nd translation to the submodel// This simply sets landmarks that aren't used in the submodel to 0,0 to indicate "unused landmark"if (iSubModel != SM_All) { pTransTab = gSubModelTrans[iSubModel]; for (int iPoint = 0; iPoint < nWantedPoints; iPoint++) if (pTransTab[iPoint] < 0) { Shape(iPoint, VX) = 0; Shape(iPoint, VY) = 0; } }#else // CONF_nGenLandmarksUsedInternally == 0if (Shape.nrows() != nWantedPoints) Err("CONF_nGenLandmarksUsedInternally is false " "yet tried to change nLandmarks from %d to %d", Shape.nrows(), nWantedPoints);#endif // CONF_nGenLandmarksUsedInternallyif (nSynthesizedEyePoints) { const int nBasicEyePoints = MLEye-MLEyeOuter; const int nExtendedEyePoints = MLEye7-MLEye0+1; ASSERT(nSynthesizedEyePoints == nExtendedEyePoints); SHAPE LEye(Shape.submat(MLEyeOuter, 0, nBasicEyePoints, 2)); SHAPE REye(Shape.submat(MREyeOuter, 0, nBasicEyePoints, 2)); if (fPointUsed(Shape, MLEye0) && !fPointUsed(Shape, MREye0)) { // synthesize additional points for the right eye from the extra left eye points Mat Pose = AlignShape_Affine(LEye, REye); SHAPE NewShape(TransformShape(Shape, Pose)); // Shape aligned so left eye is where right eye was for (int iPoint = MREye0; iPoint <= MREye7; iPoint++) Shape.row(iPoint) = NewShape.row(iPoint - nExtendedEyePoints); } else if (fPointUsed(Shape, MREye0) && !fPointUsed(Shape, MLEye0)) { // synthesize additional points for the left eye from the extra right eye points Mat Pose = AlignShape_Affine(REye, LEye); SHAPE NewShape(TransformShape(Shape, Pose)); // Shape aligned so right eye is where left eye was for (int iPoint = MLEye0; iPoint <= MLEye7; iPoint++) Shape.row(iPoint) = NewShape.row(iPoint + nExtendedEyePoints);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -