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

📄 asmsearch.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// $masm\asmsearch.cpp 1.5 milbo$ active shape routines for searching// Warning: this is raw research code -- expect it to be quite messy.// milbo dec05 durban//-----------------------------------------------------------------------------// 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"//-----------------------------------------------------------------------------// This returns the distance between ProfDiff = Prof - AvProf,// using the inverted covar mat Covar.// The efficiency of this routine is crucial to ASM search speed.//// ProfDiff is a row vector.  In math textbooks, vectors are column vectors// So we take tranposes differently from the formulae you see in textbooks.// Also, Covar is actually the inverted covariance matrix.static double GetProfDist (const Vec &ProfDiff, 		// in: Prof-AvProf						   const Mat &Covar, const SparseMat *pSparseCovar, const unsigned SubProfSpec, const int nTrimCovar){DASSERT(CONF_fStandardProfDist + CONF_fAbsProfDiff + CONF_fExperimentalProfDist == 1);	// only one of these should be setdouble Dist;#if CONF_fStandardProfDist //------------------------------------------------------// Following code implements Dist = (Prof - AvProf) * Covar * (Prof - AvProf).t()// but is faster than just using the standard matrix routines.if (pSparseCovar != NULL)	Dist = Sparse_xAx(ProfDiff, *pSparseCovar);else if (nTrimCovar)													// only needed for old format .asm files	Dist = Trimmed_xAx(ProfDiff, Covar, SubProfSpec, nTrimCovar);else	Dist = xAx(ProfDiff, Covar);static bool fWarned = false;if (!fWarned && Dist < 0)	{	Warn("NegDist %g %x", Dist, SubProfSpec);	// this happens if the covar mat is not pos def	fWarned = true;	}#elif CONF_fAbsProfDiff  //----------------------------------------------------// weighted sum of differences (see my Feb06 notebook p37) (TODO doesn't give better results)// TODO also tried various sigmoid scalings of this result and also sigmoids on QuadProfDist result without improvementDist = 0;for (int i = 0; i < Prof.nelems(); i++)	for (int j = 0; j < Prof.nelems(); j++)		{		double x = Prof(i) - AvProf(i);		double y = Prof(j) - AvProf(j);		double w = Covar(i, j); 							// weight#if 1 // methodA (see notebook)		double Result = fabs(fabs(w) * x + w * y);#elif 0 // methodB		double Result;		bool fAdd = (fPos(x) == fPos(y));					// add if both elements have same sign		if (fAdd)			Result = w * (x + y);		else			Result = w * (x - y);		bool fPosResult = (fAdd? fPos(w): !fPos(w));		// true if sign of result must be positive		if ((fPosResult && Result < 0) || (!fPosResult && Result > 0))			Result = -Result;		DASSERT(fPos(Result) == fPos(w * x * y));			// check that sign of result is same as using xAx#elif 0 // same as CONF_fStandardProfDist xAx		double Result = w * x * y;#endif		// Result /= (1 + fabs(Result));					// sigmoid scaling		Dist += Result;		}#elif CONF_fExperimentalProfDist  //-------------------------------------------DASSERT(Covar.nelems());//TODO this will be faster if we precalculate various elements of this// (Covar * AvProf.t()).print("Covar * AvProf.t()\n", "%g ");// (.5 * AvProf  * Covar * AvProf.t()).print("(.5 * AvProf  * Covar * AvProf.t())\n", "%g ");//Dist = OneElemToDouble(.5 * AvProf  * Covar * AvProf.t() - Prof * Covar * AvProf.t());// Results for following piece of code m3.asm CONF_nProfWidth1d (5 * 2 + 1)=11//// DENOM = 100// ALL   N=50   A         SDev      B         SDev      T       TProb  ChangeBtoA  BetterA WorseB   Base  ChangeBaseToA// Fit         0.053     0.019     0.054     0.022     -0.97    0.248      3.4%      44%    44%     0.094   77.8%// LEyeFit     0.043     0.026     0.046     0.028     -1.33    0.162      5.4%      42%    54%     0.058   35.4%// REyeFit     0.050     0.034     0.054     0.037     -1.67    0.099      8.5%      42%    58%     0.072   45.0%// MouthFit    0.045     0.025     0.046     0.025     -0.11    0.394      0.6%      38%    50%     0.105  132.0%// PointFit35  0.441     0.518     0.441     0.516      0.00    0.397     -0.0%      52%    48%     0.464    5.3%// Max         0.136               0.146                                   7.8%//// DENOM = 50// ALL   N=50   A         SDev      B         SDev      T       TProb  ChangeBtoA  BetterA WorseB   Base  ChangeBaseToA// Fit         0.056     0.023     0.054     0.022      1.03    0.232     -2.8%      56%    36%     0.094   67.2%// LEyeFit     0.045     0.023     0.046     0.028     -0.22    0.387      1.3%      48%    50%     0.058   30.1%// REyeFit     0.056     0.042     0.054     0.037      0.45    0.358     -2.7%      54%    38%     0.072   30.0%// MouthFit    0.045     0.024     0.046     0.025     -0.19    0.390      0.7%      52%    42%     0.105  132.2%// PointFit35  0.435     0.513     0.441     0.516     -0.10    0.395      1.3%      46%    54%     0.464    6.6%// Max         0.149               0.146                                  -1.7%//// DENOM = 1000// ALL   N=50   A         SDev      B         SDev      T       TProb  ChangeBtoA  BetterA WorseB   Base  ChangeBaseToA// Fit         0.054     0.020     0.054     0.022     -0.54    0.342      1.6%      50%    44%     0.094   74.7%// LEyeFit     0.046     0.026     0.046     0.028      0.06    0.396     -0.3%      44%    52%     0.058   28.1%// REyeFit     0.053     0.037     0.054     0.037     -0.53    0.344      2.1%      50%    44%     0.072   36.4%// MouthFit    0.042     0.022     0.046     0.025     -1.72    0.092      8.3%      36%    58%     0.105  149.7%// PointFit35  0.440     0.517     0.441     0.516     -0.01    0.397      0.1%      50%    50%     0.464    5.4%// Max         0.151               0.146                                  -2.9%//// DENOM 500// ALL   N=50   A         SDev      B         SDev      T       TProb  ChangeBtoA  BetterA WorseB   Base  ChangeBaseToA// Fit         0.053     0.018     0.054     0.022     -0.89    0.265      2.7%      44%    50%     0.094   76.6%// LEyeFit     0.044     0.024     0.046     0.028     -0.55    0.340      2.8%      46%    48%     0.058   32.1%// REyeFit     0.050     0.035     0.054     0.037     -1.60    0.111      7.3%      38%    60%     0.072   43.4%// MouthFit    0.043     0.023     0.046     0.025     -1.15    0.204      5.5%      36%    58%     0.105  143.3%// PointFit35  0.436     0.516     0.441     0.516     -0.09    0.395      1.1%      34%    66%     0.464    6.4%// Max         0.146               0.146                                   0.1%//// DENOM 200// ALL   N=50   A         SDev      B         SDev      T       TProb  ChangeBtoA  BetterA WorseB   Base  ChangeBaseToA// Fit         0.053     0.019     0.054     0.022     -0.73    0.303      2.3%      50%    44%     0.094   75.9%// LEyeFit     0.045     0.028     0.046     0.028     -0.47    0.356      1.8%      46%    52%     0.058   30.8%// REyeFit     0.050     0.035     0.054     0.037     -1.95    0.061      8.5%      40%    56%     0.072   44.9%// MouthFit    0.044     0.022     0.046     0.025     -0.91    0.261      3.9%      54%    42%     0.105  139.6%// PointFit35  0.436     0.517     0.441     0.516     -0.09    0.395      1.1%      44%    56%     0.464    6.4%// Max         0.148               0.146                                  -1.1%#define DENOM 1000double Trace = Covar.trace();Mat Covar1(Covar);for (int i = 0; i < Covar.nrows(); i++)	for (int j = 0; j < Covar.ncols(); j++)		if (i != j && ABS(Covar(i, j)) < Trace / DENOM)			Covar1(i,j) = 0;Vec Diff(Prof - AvProf);Dist = OneElemToDouble(Diff * Covar1 * Diff.t());static bool fWarned = false;if (!fWarned  && Dist < 0)	{	Warn("NegDist %g", Dist);	// this happens if the covar mat is not pos def	fWarned = true;	}#else   //---------------------------------------------------------------------SysErr("GetProfDist")			// no distance method specified#endif   //--------------------------------------------------------------------return Dist;}//-----------------------------------------------------------------------------// ix and iy are the offset and orthogonal offset wrt iPoint of the desired profile// Returns the fit//// This routine need to be very efficient because it is called a LOT during search.double GetProfileFit (tSearchImages &SearchImgs, 										// in except SearchImgs.ProgressImg is modified					  const int iPoint, const int ix, const int iy,					  const tAsmLev &AsmLev, const SHAPE &Shape, const tLand Lands[],	// in					  const unsigned ProfSpec, const int nTrimCovar){static Vec Prof;	// it is slightly quicker to allocate this statically and call dimClear() each time					// because most of the time the dimension is the same as the previous profiledouble Fit = 0;int nSubProfs = nSubProfsForProfSpec(ProfSpec);for (int iSub = 0; iSub < nSubProfs; iSub++)	{	Prof.dimClear(1, AsmLev.Profs[iPoint][iSub].ncols());	int nProfileWidth = nGetProfWidthFromModel(iPoint, iSub, AsmLev);	bool fSuccess = true;	if (AsmLev.ProfSpecs[iPoint] & PROF_2d)		// two dimensional profile?		Get2dProf(Prof, AsmLev.ProfSpecs[iPoint], iSub, SearchImgs.Img, SearchImgs.Grads, Shape, iPoint, ix, iy, nProfileWidth, false);	else		Get1dProf(Prof, AsmLev.ProfSpecs[iPoint], SearchImgs.Img, iPoint, ix, 0, false);	double Weight = (iSub > 0? CONF_CombineProfWeight: 1.0);	unsigned SubProfSpec = GetSubProfSpec(ProfSpec, iSub);	int nTrimCovar1 = ((SubProfSpec & PROF_2d)? nTrimCovar: 0);	const SparseMat *pSparseCovar = //TODO tidy this up, see ReadAsmLev()			((AsmLev.Covars[iPoint][iSub].nrows() > 1)? NULL: &AsmLev.SparseCovars[iPoint][iSub]);	Prof -= AsmLev.Profs[iPoint][iSub];	// for efficiency, use operator-= rather than operator-	Fit += Weight * GetProfDist(Prof, AsmLev.Covars[iPoint][iSub], pSparseCovar, SubProfSpec, nTrimCovar1);	AccumulateFeats(ix, iy, iSub, Fit, Prof, ProfSpec);		// only does anything if -G flag was specified	}return Fit;}//-----------------------------------------------------------------------------// Read header of .asm filestatic void ReadAsmHeader (int &nPoints, int &nLevs,							// out							double &PyrRatio,									// out							int &PyrReduceMethod,								// out							bool &fExplicitPrevNext, double &NormalizedProfLen, // out							int	 &nScaledFaceWidth, bool &fBilinearRescale,		// out							int	 &nTrimCovar, double &SigmoidScale,				// out							const char sAsmFile[], FILE *pAsmFile)				// in{// expect something like this: ASM0 [../asm/ms.asm]char s[SLEN], sFile[SLEN];int nVersion = -1;Fgets(s, SLEN-1, pAsmFile);nPoints = -1;if (strncmp(s, "ASM", 3) != 0)			// check ASM file magic number	Err("%s is not an ASM file (first three chars are not \"ASM\")", sAsmFile);if (sscanf(s+3, "%d %s", &nVersion, sFile) != 2)	SysErr("Bad format ASM file header: %s", s);if (nVersion != CONF_nAsmFileVersion)	SysErr("Bad version number %d in ASM file header", nVersion);//TODO should create functions for the repeated code belowchar sToken[SLEN];Fgets(s, SLEN-1, pAsmFile);int Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "Points"))	SysErr("Can't read Points from ASM file");if (Temp < 1 || Temp > 1000)	SysErr("Bad number of Points %d in ASM file header", Temp);nPoints = Temp;Fgets(s, SLEN-1, pAsmFile);Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "Levs") || Temp < 0)	SysErr("Can't read Levs from ASM file");if (Temp < 1 || Temp > CONF_nMaxLevs)	SysErr("Bad number of levels %d in ASM file header", Temp);nLevs = Temp;Fgets(s, SLEN-1, pAsmFile);float DTemp = -1.0;if (2 != sscanf(s, "%s %g", sToken, &DTemp) || 0 != strcmp(sToken, "PyramidRatio") || DTemp <= 0 || DTemp > 1000)	// 1000 is arbitrary	SysErr("Can't read PyramidRatio from ASM file");PyrRatio = DTemp;Fgets(s, SLEN-1, pAsmFile);Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "PyramidReduceMethod"))	SysErr("Can't read PyramidReduceMethod from ASM file");if (Temp < IM_NEAREST_PIXEL || Temp > IM_AVERAGE_ALL)	SysErr("Bad PyramidReduceMethod %d in ASM file header", Temp);PyrReduceMethod = Temp;Fgets(s, SLEN-1, pAsmFile);Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "ExplicitPrevNext") 		|| (Temp != 0 && Temp != 1))	SysErr("Can't read ExplicitPrevNext from ASM file");fExplicitPrevNext = (Temp == 1);Fgets(s, SLEN-1, pAsmFile);DTemp = -1.0;if (2 != sscanf(s, "%s %g", sToken, &DTemp) || 0 != strcmp(sToken, "NormalizedProfLen") 		|| DTemp <= 0 || DTemp > 1000)	// 1000 is arbitrary	SysErr("Can't read NormalizedProfLen from ASM file");NormalizedProfLen = DTemp;Fgets(s, SLEN-1, pAsmFile);Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "ScaledFaceWidth") 		|| Temp < 0 || Temp > 1000)	// 1000 is arbitrary	SysErr("Can't read ScaledFaceWidth from ASM file");nScaledFaceWidth = Temp;Fgets(s, SLEN-1, pAsmFile);Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "BilinearRescale") 		|| (Temp != 0 && Temp != 1))	SysErr("Can't read BilinearRescale from ASM file");fBilinearRescale = (Temp == 1);Fgets(s, SLEN-1, pAsmFile);Temp = -1;if (2 != sscanf(s, "%s %d", sToken, &Temp) || 0 != strcmp(sToken, "TrimCovar")		|| Temp < 0 || Temp > 1000)	// 1000 is arbitrary	SysErr("Can't read TrimCovar from ASM file");nTrimCovar = Temp;Fgets(s, SLEN-1, pAsmFile);DTemp = -1.0;if (2 != sscanf(s, "%s %g", sToken, &DTemp) || 0 != strcmp(sToken, "SigmoidScale")		|| DTemp <= 0 || DTemp > 1e10)	// 1e10 is arbitrary	SysErr("Can't read SigmoidScale from ASM file");SigmoidScale = DTemp;lprintf("\nnPoints %d nLevs %d PyrRatio %g PyrReduce %d fExplicitPrevNext %d NormalizedProfLen %g\n"		"nScaledFaceWidth %d fBilinearRescale %d nTrimCovar %d SigmoidScale %g",	nPoints, nLevs,	PyrRatio, PyrReduceMethod, fExplicitPrevNext, NormalizedProfLen,	nScaledFaceWidth, fBilinearRescale, nTrimCovar, SigmoidScale);}//-----------------------------------------------------------------------------// Read and check header of a level within an .asm file// No results are kept, this just checks that the header is goodstatic void CheckAsmLevHeader (const char sAsmFile[], FILE *pAsmFile, int iLev){// expect something like this: Lev 0 FirstShape xExtent 210 yExtent 243char s[SLEN], sLev[SLEN], sFirstShape[SLEN];int nLev;if (!Fgets(s, SLEN-1, pAsmFile))	SysErr("Can't read level %d header from %s", iLev, sAsmFile);

⌨️ 快捷键说明

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