⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 masm.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		SumShapes(NewAvShape, Shapes[iShape], AltShape);		}	// constrain new average shape by aligning it to the ref shape	AlignShape(NewAvShape, RefShape);	double Distance = AvShape.distSquared(NewAvShape);	if (Distance < CONF_MaxShapeAlignDist)		break;	// converged	AvShape = NewAvShape;	}if (iPass > CONF_nMaxAlignPasses)	Err("Didn't align in %d passes", CONF_nMaxAlignPasses);// align all the shapes to the average shapefor (iShape = 0; iShape < nShapes; iShape++)	AlignShape(Shapes[iShape], AvShape);		//TODO was was CentralizeShape(Shapes[iShape])#if CONF_fShowDebugImagesShowCentralizedShapes(Shapes, AvShape);#endif}//-----------------------------------------------------------------------------// Print the angle wrt horizontal of the line joining the eye pupils in Shapestatic void PrintEyeAngle (SHAPE &Shape, char sFormat[]){const tLand *pLand = pSelectLand(Shape.nrows());		// landmark informationif (iTranslatedPoint(MLEye) < Shape.nrows()	&& iTranslatedPoint(MREye) < Shape.nrows()	&& fPointUsed(Shape, iTranslatedPoint(MLEye))	&& fPointUsed(Shape, iTranslatedPoint(MREye)))	{	lprintf(sFormat,		Degrees(atan2(Shape(iTranslatedPoint(MREye), VY) - Shape(iTranslatedPoint(MLEye), VY),					  Shape(iTranslatedPoint(MREye), VX) - Shape(iTranslatedPoint(MLEye), VX))));	}}//-----------------------------------------------------------------------------static void AlignTrainingShapes (tShapes &Shapes,	// io: Shapes field and AvShape updated								 int iRefShape)		// in{char *sShapeName = &Shapes.TagStrings[iRefShape][FNAME_OFFSET];lprintf("Aligning shapes to %s",  sShapeName);DASSERT(iRefShape < Shapes.nShapes);int nPoints = Shapes.Shapes[iRefShape].nrows();Shapes.AvShape.dimKeep(nPoints, 2);SHAPE RefShape(Shapes.Shapes[iRefShape]);#if CONF_fStraightenBeforeAligningStraightenAndCentralizeShape(RefShape);#elseCentralizeShape(RefShape);#endifif (CONF_GenSubModel == SM_All || CONF_GenSubModel == SM_20)	PrintEyeAngle(Shapes.AvShape, " (eye angle %.2f degrees)");AlignShapes(Shapes.Shapes, Shapes.AvShape, RefShape);if (CONF_GenSubModel == SM_All || CONF_GenSubModel == SM_20)	PrintEyeAngle(Shapes.AvShape, ", aligned eye angle %.2f degrees");lprintf(" %s\n", sSecsElapsed());// sanity check: not necessary but prevents slip-ups during classifier evaluation#if CONF_nReducedNbrPoints == 0if (Shapes.nUsedLandmarks[iRefShape] != CONF_nPointsXm2vts &&	Shapes.nUsedLandmarks[iRefShape] != CONF_nPoints84)	{	Warn("The reference shape (%s shape number %d) has an unusual number %d of landmarks",			sShapeName, iRefShape, Shapes.nUsedLandmarks[iRefShape]);	}#elseif (Shapes.nUsedLandmarks[iRefShape] != CONF_nReducedNbrPoints)	Err("The reference shape (%s shape number %d) has %d landmarks, expected same number of landmarks as XMTVTS or M4",		sShapeName, iRefShape, Shapes.nUsedLandmarks[iRefShape]);#endif}//-----------------------------------------------------------------------------// if CONF_fMasmGaussianNoise is true, return a gaussian rand value with a std dev of Range//									(i.e. 68% iof the values will be between -Range and +Range)//// else return a rand value between -Range and +Range, uniform distributionstatic double Rand1 (double Range){#if CONF_fMasmGaussianNoisereturn RandGauss(Range);#elsereturn Range * (RandDouble(2) - 1);#endif}//-----------------------------------------------------------------------------// This calculates the eigen vecs and vals for Shapes.// There is a twist: we only the shapes that have the same number of used landmarks as the first shape.// TODO One day it would be nice to include all shapesstatic void CalcShapeEigs (Mat &EigVals, Mat &EigVecs, 						   									// out						 const ShapeVec &Shapes, SHAPE &AvShape, size_t nShapes, const IntVec &nUsedLandmarks)	// in{int	nPoints = AvShape.nrows(); int nShapesWithAllLandmarks = 0;for (int iShape = 0; iShape < nShapes; iShape++)	if (nUsedLandmarks[iShape] == nUsedLandmarks[0])		nShapesWithAllLandmarks++;if (nShapesWithAllLandmarks != nShapes)	Warn("Only %d of %d shapes used in CalcShapeEigs because of missing landmarks", nShapesWithAllLandmarks, nShapes);Mat ShapeDelta(nShapesWithAllLandmarks, 2 * nPoints);VecView AvShapeAsRow(AvShape.viewAsRow()); 	// view all coords for shape as a single row vector, first x coords then y coordsint iShape1 = 0;for (iShape = 0; iShape < nShapes; iShape++)	if (nUsedLandmarks[iShape] == nUsedLandmarks[0])		{		SHAPE Shape(Shapes[iShape]);#if CONF_fRecentralizeShapes			// TODO why does centralizing here give different results (A+3.6% B-4.4% m+1.3%)#if CONF_fStraightenBeforeAligning		StraightenAndCentralizeShape(Shape);#else		CentralizeShape(Shape);#endif#endif		if (CONF_GenSubModel == SM_All &&				CONF_xStretchShape != 0.0 || CONF_xRhsStretchShape != 0.0 || CONF_ShapeNoise != 0.0)			{			// add noise to the shape			double xStretch = Rand1(CONF_xStretchShape);		// rand val, 68% of values between +- CONF_xStretchShape			double xDist    = Rand1(CONF_xRhsStretchShape);			for (int iRow = 0; iRow < Shape.nrows(); iRow++)				{				if (Shape(iRow, VX) > 0)						// stretch rhs of shape horizontally					Shape(iRow, VX) *= (1 + xDist);				Shape(iRow, VX) *= (1 + xStretch);				// stretch entire shape horizontally				Shape(iRow, VX) += Rand1(CONF_ShapeNoise);		// add noise to both x and y				Shape(iRow, VY) += Rand1(CONF_ShapeNoise);				}			}		ShapeDelta.row(iShape1) = Shape.viewAsRow() - AvShapeAsRow;		iShape1++;		}DASSERT(iShape1 == nShapesWithAllLandmarks);Mat Covar((ShapeDelta.t() * ShapeDelta) / nShapesWithAllLandmarks);	// dimensions are 2*nPoints x 2*nPointsEigVecs = GetEigsForSymMat(Covar, EigVals);							// returns eig vecs sorted on eig vals// For improved consistency between _DEBUG and release versions, set// very small eig vals and their corresponding eig vecs to 0.// These small values are the unpredictable result of numerical errors but it's not// clear why the GSL generates slightly different vals for _DEBUG and release versions.for (int iEig = 0; iEig < EigVals.nrows(); iEig++)	if (EigVals(iEig) < EigVals(0) / 1E6)		{		EigVals(iEig) = 0;		EigVecs.col(iEig).fill(0);		}}//-----------------------------------------------------------------------------// Print first n eig vals, up to and including the first small value. But no more than 10 of them.static void ShowShapeEigs (const Mat &EigVals){char s[PLEN];int iPrint = 0;double MinEig = EigVals(0) / 1000;while (iPrint < EigVals.nelems() && EigVals(iPrint) > MinEig && iPrint < 10-1)	iPrint++;if (iPrint < EigVals.nelems() + 1)	// show first small eig value, for context	iPrint++;sprintf(s, "%s%d eig vals: ", (iPrint < EigVals.nelems()? "First ": ""), iPrint);EigVals.t().print(s, "%.1f ", NULL, NULL, iPrint);if (fabs(EigVals(0)) < 0.1)			// number is somewhat arbitrary	Warn("Eigen data invalid (not enough variation in shape file)");}//-----------------------------------------------------------------------------// Reserve space in the shape Statsstatic void AllocStats (tStats &Stats, 			// io						char sProfSpecs[],		// in						const tShapes &Shapes)	// in{DASSERT(fOdd(CONF_nProfWidth1d));DASSERT(fOdd(CONF_nProfWidth2d));int nPoints = Shapes.nPoints;int nMaxProfsPerPoint = Shapes.nShapes;	// max nbr of profs per landmark, not all used if some landmarks rejected by Shapes.TagStrings[iShape]Stats.nProfs.resize(CONF_nLevs);Stats.Covars.resize(CONF_nLevs);Stats.Profs.resize(CONF_nLevs);Stats.AvProfs.resize(CONF_nLevs);static unsigned LastProfSpec = 0;sProfSpecs[0] = 0;for (int iLev = 0; iLev < CONF_nLevs; iLev++)	{	Stats.nProfs[iLev].resize(nPoints, 0);	Stats.Covars[iLev].resize(nPoints, 0);	Stats.Profs[iLev].resize(nPoints, 0);	Stats.AvProfs[iLev].resize(nPoints, 0);	for (int iPoint = 0; iPoint < nPoints; iPoint++)		if (fPointUsed(Shapes.AvShape, iPoint))	// not all points are used if we are generating a submodel			{			// Here we make the assumption that all sub profs need no more space than SubProf0.			// This can waste space but is otherwise harmless.			unsigned ProfSpec = GetGenProfSpec(iLev, iPoint);			int nSubProfs = nSubProfsForProfSpec(ProfSpec);			int nSubProfPoints = nGenelemsPerSubProf(GetSubProfSpec(ProfSpec, 0));			AllocMatVec(Stats.Covars[iLev][iPoint],  nSubProfs, nSubProfPoints,    nSubProfPoints);			AllocMatVec(Stats.Profs[iLev][iPoint],   nSubProfs, nMaxProfsPerPoint, nSubProfPoints);			AllocMatVec(Stats.AvProfs[iLev][iPoint], nSubProfs, 1, 		  		   nSubProfPoints);			if (LastProfSpec != ProfSpec)				{				char s[SLEN]; sprintf(s, "%d,%d:%8.8x ", iLev, iPoint, ProfSpec);				strcat(sProfSpecs, s);				LastProfSpec = ProfSpec;				}			}	}}//-----------------------------------------------------------------------------// Compact Profs by keeping elements that are in used, discarding the rest.// fUsed tells us which elements are used.#if CONF_fMultiEdit || CONF_fCondense || CONF_fReducestatic void CompactProfs (int &nProfs, Mat &Profs, Vec *pProfs, CharVec *pLabs,	// io						  const BoolVec &fUse, char sTitle[], bool fVerbose=false)		// in{int ncols = Profs.ncols();int iProfNew = 0;for (int iProf = 0; iProf < nProfs; iProf++)	{	if (fUse[iProf])	// profile used?		{		for (int i = 0; i < ncols; i++)			Profs(iProfNew, i) = Profs(iProf, i);		iProfNew++;		}	}Profs.dimKeep(iProfNew, ncols);DASSERT(iProfNew > 0);nProfs = iProfNew;}#endif CONF_fMultiEdit || CONF_fCondense || CONF_fReduce//-----------------------------------------------------------------------------// This routine is for debugging.  It shows the image with the shape and// whiskers superimposed.  We call this just before sampling profiles so we can// see that what we are sampling is correct i.e the whiskers are in the right places etc.#if CONF_fShowSampledImageWithShapesstatic void ShowSampledImageWithShapes (int iLev, int iShape, Image &ScaledImg, 				SHAPE &ScaledShape, SHAPE &ScaledAlignedAvShape, const tShapes &Shapes){if (CONF_fShowSampledImageAllLevs || iLev == 0)	{	double Scale = pow(2,iLev);	#define MAG 1.0	RgbImage RgbImg(MAG * ScaledImg.width, MAG * ScaledImg.height);	Scale *= MAG;	DrawShape1(RgbImg, ScaledImg, ScaledShape, NULL /* &ScaledAlignedAvShape */,		C_DRED, Scale, IM_NO_CONNECT_DOTS,		(MAG > 1? IM_ANNOTATE: IM_NO_ANNOTATE), IM_NO_WHISKERS, 0, IM_TRANSPARENT, IM_NO_CROP_TO_FACE,		gLandTabAll, &ScaledAlignedAvShape, IM_NO_DRAW_CIRCLES);#if CONF_fCropImageToShape	CropImageToFace(RgbImg, ScaledAlignedAvShape, Scale);#endif	char sDrive[_MAX_DRIVE], sDir[_MAX_DIR], sFname[_MAX_FNAME], sExt[_MAX_EXT], sPath[SLEN];	_splitpath(&Shapes.TagStrings[iShape][FNAME_OFFSET], sDrive, sDir, sFname, sExt);	sprintf(sPath, "%s/%s_%d", CONF_sOutDir, sFname, iLev);	WriteBmp(RgbImg, sPath, VERBOSE);	}}#endif//-----------------------------------------------------------------------------static void CollectProfForOneLandmark (tStats &Stats,								// io					int iShape, int iLev, int iPoint, const tLand *pLand,			// in					const Image &ScaledImg, 										// in					const SHAPE &ScaledShape, const SHAPE &ScaledAlignedAvShape,	// in					const MatVec &Grads)											// in{unsigned ProfSpec = GetGenProfSpec(iLev, iPoint);if ((ProfSpec & PROF_2d) == 0)		// 1D prof? if so save time for multiple iOffsets by pre-preparing profile	PrepareProf1D(ScaledImg, ScaledShape, ProfSpec, pLand, ScaledAlignedAvShape,					iPoint, CONF_nProfWidth1d, 0, 0);int iProf = Stats.nProfs[iLev][iPoint];		// start where we left off last timeconst int iOrthOffset = 0;					// constant for now (will need multiple iOffsets for nearest neighbors when I implement it TODO)const int iOffset = 0;						// dittobool fSuccess = true;if (ProfSpec & PROF_2d)						// two dimensional prof?	{#if CONF_fDebug2dProfs	lprintf("\n2dProf at iPoint %d: ", iPoint);	// draw a square around the landmark and show the image	static int iBmp = 0; char s[SLEN]; sprintf(s, "out/Img%2.2d.bmp", iBmp++);	SHAPE SubShape(5, 2);	int x = ScaledShape(iPoint, VX), y = ScaledShape(iPoint, VY), Half = (CONF_nProfWidth2d-1)/2 + 1;	SubShape(0, VX) = x - Half; SubShape(0, VY) = y - Half;	SubShape(1, VX) = x - Half; SubShape(1, VY) = y + Half;	SubShape(2, VX) = x + Half; SubShape(2, VY) = y + Half;	SubShape(3, VX) = x + Half; SubShape(3, VY) = y - Half;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -