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

📄 prof.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// $masm\prof.cpp 1.5 milbo$ functions for profiles around landmarks// Warning: this is raw research code -- expect it to be quite messy.// milbo durban jan06//-----------------------------------------------------------------------------// 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"bool fgExplicitPrevNext;	// train:set from CONF_fGenExplicitPrevNext							// search:read from ASM filedouble gNormalizedProfLen;	// train:set from CONF_GenNormalizedProfLen							// search:read from ASM file//-----------------------------------------------------------------------------// See header for PROF_ defines in prof.hppunsigned GetSubProfSpec (unsigned Prof, unsigned iSub){DASSERT(iSub < CONF_nMaxSubProfs);return (((Prof >> (iSub * 8)) & 0xff) | (Prof & 0xff000000));}//-----------------------------------------------------------------------------unsigned nSubProfsForProfSpec (unsigned ProfSpec){DASSERT(CONF_nMaxSubProfs <= 3);				// this routine can count up to 3DASSERT((ProfSpec & PROF_2d) || (ProfSpec & 0x00ffff00) == 0);											// 1d profiles can have only one subprofileunsigned nSubProfs = 1;if (ProfSpec & 0xff00)	{	nSubProfs++;	if (ProfSpec & 0xff0000)		nSubProfs++;	}return nSubProfs;}//-----------------------------------------------------------------------------// This is only needed when GENERATING a model.// When USING the model (i.e. during search), use nGetProfWidth() instead.int nGenelemsPerSubProf (unsigned ProfSpec){if ((ProfSpec & PROF_2d) == 0)				// one dimensional profile?	return CONF_nProfWidth1d;return CONF_nProfWidth2d * CONF_nProfWidth2d;}//-----------------------------------------------------------------------------static void WriteMatAsBmp (const Mat &m, const char sPath[],							bool fNormalizeBmp, bool fVerbose){Mat Norm;if (fNormalizeBmp)		// normalize elems to 0..255?	{	double Max = m.maxElem();	double Min = m.minElem();	Norm = (m - Min) * 255.0 / (Max - Min);	}else	Norm = m;Image Img(m.ncols(), m.nrows());for (int iRow = 0; iRow < m.nrows(); iRow++)	for (int iCol = 0; iCol < m.ncols(); iCol++)		Img(iCol, iRow) = Norm(iRow, iCol);WriteBmp(Img, sPath, fVerbose);}//-----------------------------------------------------------------------------// Print the matrix, laid out in the same way as an image// i.e. top left corner of print is top left corner of imagevoid PrintBmpAsMat (const Image &Img, const char sMsg[], const char sFormat[]){Mat m(Img.height, Img.width);for (int iRow = 0; iRow < m.nrows(); iRow++)	for (int iCol = 0; iCol < m.ncols(); iCol++)		m(iRow, iCol) = Img(iCol, iRow);if (sFormat == NULL)	sFormat = "%3.0f ";m.print(sMsg, sFormat);}//-----------------------------------------------------------------------------void Write2dProfAsBmp (const Vec &Prof, char sPath[], bool fNormalizeBmp, bool fVerbose){MatView Square(Prof.viewAsSquare());Mat Norm;if (fNormalizeBmp)		// normalize elems to 0..255?	{	double Max = Square.maxElem();	double Min = Square.minElem();	if (Max - Min == 0)		Norm.dimClear(Square.nrows(), Square.ncols());	else		Norm = (Square - Min) * 255.0 / (Max - Min);	}else	Norm = Square;Image Img(Square.ncols(), Square.nrows());for (int iRow = 0; iRow < Square.nrows(); iRow++)	for (int iCol = 0; iCol < Square.ncols(); iCol++)		{		int iPix = Norm(iRow, iCol);		DASSERT(iPix >= 0 && iPix < 256);		Img(iCol, iRow) = iPix;		}WriteBmp(Img, sPath, fVerbose);}//-----------------------------------------------------------------------------// Debugging stuffconst char *pgCurImageName;	// for debugging it is useful to know which is the current imageint igCurShape;bool fgStepSizeErr;// just a little hack for finding out which shapes are causing pixel out-of-range errors#if CONF_fFindOffRangePixelsstatic bool fgPixelOffRange[CONF_nMaxImages];static void GetPixelFail (int ix, int iy){DASSERT(igCurShape < CONF_nMaxImages);if (pgCurImageName)	{ 	if (!fgPixelOffRange[igCurShape])		{		fgPixelOffRange[igCurShape] = true;		Warn("Offrange %s %dx%d", pgCurImageName, ix, iy);		}	}}#endif//-----------------------------------------------------------------------------// Get pixel in Img, ix and iy in SHAPE coords, with range checking.//// SHAPE coords: 0,0 is center of image,//				 image spans -width/2 to width/2, -height/2 to height/2//// Returns 255 if pixel is white; 0 if pixel is black or out-of-rangestatic int iGetPixel (const Image &Img, int ix, int iy){int width = Img.width, height = Img.height;ix += width/2;		// convert SHAPE to Image coordsiy += height/2;#if CONF_fFindOffRangePixelsif (ix < 0 || ix > width-1 || iy < 0 || iy > height-1)	{	GetPixelFail(ix, iy);#if CONF_fPrintOffRangePixels	Warn("GetPix %dx%d", ix, iy);#endif	}#endifif (ix < 0)	ix = 0;if (ix > width-1)	ix = width-1;if (iy < 0)	iy = 0;if (iy > height-1)	iy = height-1;int iPix = Img(ix, (height - 1 - iy));		// height-1-iy min is 0 when iy at max=height-1#if CONF_fFindOffRangePixels// This code is used to help decide which images are unsuitable for training because// the face is too close to the border.  There has to be a margin around the face// so the whiskers don't go off the image.//// If the lprintf below occurs during training, we know that the training face is too// near the border.//// LoadAndTranslateImage can leave black borders around the image (if fTranslate is true).// Here we check to see if we are on a black border.  This will also (incorrectly) pick// up correct black pixels in the image, so we filter (most) of those out by checking for// three black pixels in a row, and by making sure the pixel is near the edge of the image.static int iLastPix1 = 255;static int iLastPix2 = 255;if (iPix == 0 && iLastPix1 == 0 && iLastPix2 == 0		&& (ix < width/4  || ix > 3 * width/4)		&& (iy < height/4 || ix > 3 * height/4))	{	Warn("GetPix zero %s %dx%d", pgCurImageName, ix, iy);	}iLastPix2 = iLastPix1;iLastPix1 = iPix;#endifreturn iPix;}//-----------------------------------------------------------------------------// Same as iGetPixel for Image, but here the image is represented by a Mat// We have to swap ix,iy at the right place.static double GetPixel (const Mat &m, int ix, int iy){int width = m.ncols(), height = m.nrows();ix += width/2;		// convert SHAPE to Image coordsiy += height/2;#if CONF_fFindOffRangePixelsif (ix < 0 || ix > width-1 || iy < 0 || iy > height-1)	{	GetPixelFail(ix, iy);#if CONF_fPrintOffRangePixels	Warn("GetPix_%dx%d", ix, iy);#endif	}#endifif (ix < 0)	ix = 0;if (ix > width-1)	ix = width-1;if (iy < 0)	iy = 0;if (iy > height-1)	iy = height-1;double Pix = m(height - 1 - iy, ix);		// x,y back to front to iGetPixel(Image)#if CONF_fFindOffRangePixels// This code is used to help decide which images are unsuitable for training because// the face is too close to the border.  There has to be a margin around the face// so the whiskers don't go off the image.//// If the lprintf below occurs during training, we know that the training face is too// near the border.//// LoadAndTranslateImage can leave black borders around the image (if fTranslate is true).// Here we check to see if we are on a black border.  This will also (incorrectly) pick// up correct black pixels in the image, so we filter (most) of those out by checking for// three black pixels in a row, and by making sure the pixel is near the edge of the image.static double LastPix1 = 255;static double LastPix2 = 255;if (Pix == 0 && LastPix1 == 0 && LastPix2 == 0		&& (ix < width/4  || ix > 3 * width/4)		&& (iy < height/4 || ix > 3 * height/4))	{	Warn("GetPix zero %s %dx%d", pgCurImageName, ix, iy);	}LastPix2 = LastPix1;LastPix1 = Pix;#endifreturn Pix;}//-----------------------------------------------------------------------------// AlignedAvShape is used only if there are missing iPrev and iNext landmarks in Shape// and fgExplicitPrevNext is true.// In such a case, we approximate the position of iPrev and iNext from AlignedAvShape//// ProfAngle is the angle of the whisker relative to the orthogonal.  Make 0 to get// a conventional orthogonal whisker.//// *pDeltaX is along whisker, *pDeltaY is orthogonal to whiskervoid GetProfStepSize (double *pDeltaX, double *pDeltaY, 				// out					  const SHAPE &Shape, int iPoint, double ProfAngle,					  const tLand Lands[], const SHAPE &AlignedAvShape)	// in{DASSERT(fPointUsed(Shape, iPoint));int nPoints = Shape.nrows();// Use Lands prev and next points if Lands explictly specifies them.//// If these are unused on Shape, get the best approximation for them from AlignedAvShape.// This can only happen if not all landmarks are used in Shape (e.g. a BioId or AR shape).//// If Lands doesn't explicitly specify prev and next landmarks, use the// one-less and one-more index in Shape to select prev and next landmarks.// This is the classic Cootes method.int iPrev, iNext;static Vec PrevRow; PrevRow.dim(Shape.ncols(), ROWVEC);static Vec NextRow; NextRow.dim(Shape.ncols(), ROWVEC);if (fgExplicitPrevNext)	{	iPrev = Lands[iPoint].iPrev;	if (iPrev < 0)		iPrev = (iPoint + nPoints - 1) % nPoints;	PrevRow = Shape.row(iPrev);	if (!fPointUsed(Shape, iPrev))		{		DASSERT(fPointUsed(AlignedAvShape, iPrev));		PrevRow = AlignedAvShape.row(iPrev);		}	iNext = Lands[iPoint].iNext;	if (iNext < 0)		iNext = (iPoint + 1) % nPoints;	NextRow = Shape.row(iNext);	if (!fPointUsed(Shape, iNext))		{		DASSERT(fPointUsed(AlignedAvShape, iNext));		NextRow = AlignedAvShape.row(iNext);		}	}else // classic Cootes method, but skip over unused points in Shape	{	iPrev = iPoint;	do		{		if (--iPrev < 0)			iPrev = nPoints-1;		}	while (!fPointUsed(Shape, iPrev));	PrevRow = Shape.row(iPrev);	iNext = iPoint;	do		{		if (++iNext >= nPoints)			iNext = 0;		}	while (!fPointUsed(Shape, iNext));	NextRow = Shape.row(iNext);	}static Vec Whisker;Whisker.assign(GetBisector(PrevRow, Shape.row(iPoint), NextRow, ProfAngle));*pDeltaX = Whisker(VX);*pDeltaY = Whisker(VY);// Normalise so we take single pixel steps.// After this either *pDeltaX or *pDeltaY will be +-1, and the other will be less than 1.double AbsDeltaX = fabs(*pDeltaX);double AbsDeltaY = fabs(*pDeltaY);if (AbsDeltaX < 1e-10 && AbsDeltaY < 1e-10)	// I fixed this in GetBisector, but left check in	{	static bool fWarned = false;	if (!fWarned)		{		Warn("StepSizeErr %s %d %d", pgCurImageName, igCurShape, iPoint);		fWarned = true;		}	return;	}if (AbsDeltaX >= AbsDeltaY)	{	*pDeltaY /= AbsDeltaX;	*pDeltaX /= AbsDeltaX;	}else	{	*pDeltaX /= AbsDeltaY;	*pDeltaY /= AbsDeltaY;	}}//-----------------------------------------------------------------------------// Variables for PrepareProf and GetProf routines// Max number of elems in a profile including nPixSearch on each end// If this is too small you'll get a SysErr, it won't silently failstatic const CONF_nMaxProfWidth1D = 50;static Vec    		gProf(CONF_nMaxProfWidth1D, CONF_nMaxProfWidth1D);static int	  		ngProfWidth;static int 	  		igProfPoint;	// for sanity checkingstatic const byte	*pgProfImage;	// dittostatic unsigned		gSubProfSpec;	// ditto#if CONF_fRawProfsstatic Vec    		gRawProf(CONF_nMaxProfWidth1D, CONF_nMaxProfWidth1D);static FILE 		*pgRawProfFile;#endif//-----------------------------------------------------------------------------// If you want multiple profiles along one whisker, then

⌨️ 快捷键说明

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