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

📄 caam.cpp

📁 face recognition test source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
end:	
	pSammon = lvq.sammon;
	delete lvq.pconfusion;
	LVQEnd(&lvq);
	delete pCategorizeMat;
	delete pCategorizeCmp;
	Msg(-1, str_AAM_CATEGORIZE_DONE, lCatFace);

	if (bMet == FALSE)
		{
		pMetDB = NULL;
		}
	
	return 0;
	}

void NChar(char *buf, int n)
	{
	int i;
	if (strlen(buf) > n)
		{
		buf[n] = 0;
		}
	else
		{
		i = strlen(buf);
		while (i < n)
			{
			buf[i] = ' ';
			buf[i+1] = 0;
			i++;
			}
		}
   }
   
CFaceDB *CAAM::GetCategorizeDB()
	{
	if (pCategorizeDB == NULL)
		pCategorizeDB = new CFaceDB();
		
	return pCategorizeDB;
	}

CFaceDB *CAAM::GetTrainingDB()
	{
	if (pTrainingDB == NULL)
		pTrainingDB = new CFaceDB();
		
	return pTrainingDB;
	}

CFaceDB *CAAM::GetEigenDB()
	{
	if (pEFace == NULL)
		pEFace = new CFaceDB();
		
	return pEFace;
	}

CFaceDB *CAAM::GetReconstructionDB()
	{
	if (pReconstructionDB == NULL)
		pReconstructionDB = new CFaceDB();
		
	return pReconstructionDB;
	}

CFaceDB *CAAM::GetRecognitionDB()
	{
	if (pRecognizeDB == NULL)
		pRecognizeDB = new CFaceDB();
		
	return pRecognizeDB;
	}

CFaceDB *CAAM::GetMetDB()
	{
	if (pMetDB == NULL)
		pMetDB = new CFaceDB();
		
	return pMetDB;
	}

CFaceDB *CAAM::GetReconstructedDB()
	{return pReconstructedDB;}

CFaceDB *CAAM::GetRecognizedDB()
	{return pRecognizedDB;}

CMatrix *CAAM::GetReconstructedMat()
	{return pReconstructedMat;}

CMatrix *CAAM::GetMetMat()
	{
	if (pMetMat == NULL)
		{
		pMetMat = new CMatrix();							/*Construct the eigenvector matrix*/
		}
		
	return pMetMat;
	}

CMatrixPtr *CAAM::GetEigenMat()
	{
	if (pEVect == NULL)
		{
		pEVect = new CMatrixPtr();							/*Construct the eigenvector matrix*/
		}
		
	return pEVect;
	}

CDiag *CAAM::GetEigenVal()
	{
	if (pEVal == NULL)
		{
		pEVal = new CDiag();
		}
		
	return pEVal;
	}

CMatrixPtr *CAAM::GetMeetCmp()
	{return pMetCmp;}

CMatrix *CAAM::GetReconstructionCmp()
	{return pReconstructionCmp;}

CMatrix *CAAM::GetRecognitionCmp()
	{return pRecognizeCmp;}

BOOL CAAM::IsCommand(int cmd)
	{
	if (cmd >= 0 && cmd < CMD_MAX)
		return bCommand[cmd];
	else
		return FALSE;
	}

/*****************************************************************************************
* Compute the composant of a set of face. The composants of the face n (in pFaceMat) is in 
* the column n (of pCmpMat). 
* Therefore pFaceMat must have the same number of columns than pCmpMat.
* The number of rows of pCmpMat must be the number of eigenvectors of the memory.
*****************************************************************************************/
void CAAM::FaceToCmp(CMatrix *pCmpMat, CMatrix *pFaceMat)
	{
	pEVect->SetTranspose(TRUE);
	pCmpMat->Multiply(pEVect, pFaceMat);
	pEVect->SetTranspose(FALSE);
	Msg(0, str_AAM_F2CMP);
	}

/*****************************************************************************************
* Compute a set of faces from a set of composants. 
* pFaceMat must have the same number of columns than pCmpMat, in other words the number of
* composant vectors is equal to the number of recalled faces.
* pCmpMat must have the same number of rows than the number of eigenvectors of the memory.
*****************************************************************************************/
void CAAM::CmpToFace(CMatrix *pFaceMat, CMatrix *pCmpMat)		
	{
	pFaceMat->Multiply(pEVect, pCmpMat);
	Msg(0, str_AAM_CMP2F);
	}
	
/*=======================================================================================*/

/*****************************************************************************************
* Copy the pointer of the faces' data into the one of the columns' matrix
******************************************************************************************/
void DBtoMat(CMatrixPtr *pMat, CFaceDB *pDB)
	{
	long l;
	long lCol = pDB->GetNumFace();
	
	for (l = 1; l <= lCol; l++)
		{													/*Copy the pointer of the faces' data into the one of the columns' matrix*/
		pMat->SetColumn(l, pDB->GetFaceMem(l));
		}
	}

void DBtoDiag(CDiag *pDiag, CFaceDB *pDB)
	{
	long l;
	long lCol = pDB->GetNumFace();
	
	pDiag->Lock();
	
	for (l = 1; l <= lCol; l++)
		{													
		pDiag->SetAt(l, atof(pDB->GetFaceName(l)));
		}
	pDiag->Unlock();
	}

/*****************************************************************************************
* Put in the diagonal matrix pCos, the cosine of the angle between the vectors of the
* matrices pMat1 and pMat2
* The Cosine of the angle between the column vector n of pMat1 (nth column of pMat1) and
* the column vector n of pMat2 (nth column of pMat2) is stored in the nth element of pCos 
*****************************************************************************************/
void ComputeCos(CDiag *pCos, CMatrix *pMat1, CMatrix *pMat2)
	{
	pMat1->SetTranspose(TRUE);
	pCos->Multiply(pMat1, pMat2);
	pMat1->SetTranspose(FALSE);
	Msg(0, str_AAM_COS_DONE);
	}

/*****************************************************************************************
* RecognizeCmp make an association between several column vectors of one matrix to other
* vectors of another matrix. It takes each column vector of pSourceCmp and associate it to
* the most similar vector of pKnownCmp. 
* The definition of "most similar vector" must be understood in a large way : the nElect vectors
* of the pKownCmp Matrix nearest (in term of euclidian distance) to a particular vector of 
* pSourceCmp are found. Then, those vectors vote. Their vote is their name found in the Face 
* Database pMetDB. The vector whose name win the election is associated to the vector of 
* pSourceCmp. This operation is done for every vector of pSourceCmp.
*
* 		CMatrixPtr *pDestCmp : 	This fct will copy the vector which is associated to the ith vector 
*										of pSourceCmp to the ith column of this matrix.
*		CMatrix *pSourceCmp	:	The source matrix, from which the column vectors which have to be
*										associated to one vector of the matrix pKonwnCmp, are extracted.
*		CMatrixPtr *pKnownCmp:	This matrix contains the column vectors which will be associated to.
*		CMatrix *pAssociation:	This is the output of this fct. This fct will store in the ith 
*										element of its first vector, the number of the column of the matrix 
*										pKnownCmp which is associated to the ith vector of pSourceCmp, and
*										in its second column the probability of the association.
*		int nElect				:	The number of electors the user wants to have.
*		CFaceDB* pMetDB		:	Used to know the name of each vector of pKnownCmp.
*****************************************************************************************/
void RecognizeCmp(CMatrixPtr *pDestCmp, CMatrix *pSourceCmp, CMatrixPtr *pKnownCmp, CMatrix *pAssociation, 
	int nElect, CFaceDB* pMetDB)
	{
	long lsource, lknown, *lrec, lcolsource, lcolknown, lrow, r;
	float d, *dmin;
	CMemory mem1, mem2, mem3;
	int i, j, nwin, *nvote;
	
	mem1.Allocate(nElect*sizeof(float));
	mem2.Allocate(nElect*sizeof(long));
	mem3.Allocate(nElect*sizeof(int));
	dmin = (float*)mem1.GetPtr();
	lrec = (long*)mem2.GetPtr();
	nvote = (int*)mem3.GetPtr();
	
	Msg(1, str_AAM_RECOG_CLASS);
	
	lcolknown =  pKnownCmp->GetCol();
	lcolsource  = pSourceCmp->GetCol();
	lrow = pSourceCmp->GetLi();
	
	pSourceCmp->Lock();
	pKnownCmp->Lock();
	if (pAssociation != NULL)
		pAssociation->Lock();
	
	for (lsource = 1; lsource <= lcolsource; lsource++)
		{
		for (i = 0; i < nElect; i++)
			{
			dmin[i] = MAXFLOAT;
			lrec[i] = 0;
			}
		
		for (lknown = 1; lknown <= lcolknown; lknown++)
			{
			d = 0.0;
			for (r = 1; r <= lrow; r++)
				{
				d += pow(pKnownCmp->GetAt(r, lknown) - pSourceCmp->GetAt(r, lsource), 2.0);
				}
			d = sqrt(d);
			
			if (d < dmin[nElect-1])
				{
				i = nElect-1;
				while (i >= 0 && d < dmin[i])          /*Look if lknown must be in the five elector*/
					{
					i--;
					}
				i++;
				if (i < nElect)
					{												/*lknown must be in the five elector, its place is i*/
					for (j = nElect-1; j > i; j--)
						{
						dmin[j] = dmin[j-1];
						lrec[j] = lrec[j-1];
						}
					dmin[i] = d;
					lrec[i] = lknown;
					}
				}
			}
			
		if (pAssociation != NULL)
			{														
			if (nElect > 1)
				{													/*Make the electors vote*/
				for (i = 0; i < nElect; i++)
					{    											/*Count the number of votes for each elector*/
					nvote[i] = 0;
					for (j = i; j < nElect; j++)
						{
						if (strcmp(pMetDB->GetFaceName(lrec[i]), pMetDB->GetFaceName(lrec[j])) == 0)
							nvote[i]++;
						}
					}
				nwin = 0;
				for (i = 1; i < nElect; i++)
					{
					if (nvote[nwin] < nvote[i])
						nwin = i;
					}
					
				if (nvote[nwin] > 1)
					{
					pAssociation->SetAt(lsource, 1, lrec[nwin]);
					pAssociation->SetAt(lsource, 2, (float)nvote[nwin]/float(nElect)*100.0);
					}
				else
					pAssociation->SetAt(lsource, 1, INDETERMINATE);             
					
				pDestCmp->SetColumn(lsource, pKnownCmp->GetColumn(lrec[nwin]));
				}
			else
				{													/*No need to vote*/
				pAssociation->SetAt(lsource, 1, lrec[0]);
				pAssociation->SetAt(lsource, 2, -1);
				pDestCmp->SetColumn(lsource, pKnownCmp->GetColumn(lrec[0]));
				}
			}
		}
	
	pSourceCmp->Unlock();
	pKnownCmp->Unlock();
	
	mem1.ReleasePtr();
	mem2.ReleasePtr();
	mem3.ReleasePtr();
	
	if (pAssociation != NULL)
		pAssociation->Unlock();
	Msg(-1, str_AAM_RECOG_CLASS_DONE);
	}

/*****************************************************************************************
* Sort the eigenvectors and the eigenvalues acording to the eigenvalue (descending order)
* This fct checks also that there doesn't exist any null eigenvalue, if it finds one, it
* discards the eigenvalue and the eigenvector;
*****************************************************************************************/
long Sort(CMatrixPtr *pMat, CVect *pVect)
	{
	long lcol, l, l2, maxl;
	float maxval, val;
	int number = 0;
	
	lcol = pVect->GetLi();
	
	pVect->Lock();
	
	for (l = 1L; l <= lcol; l++)
		{
		maxval = pVect->GetAt(l);
		
		if (maxval < 1E-7)									/*A null eigenvalue has been found (because*/
			{														/*There were two equal vectors in the training set*/
			number++;											/*So discard the eigenvector*/
			pVect->Discard(l);								/*and the eigenvalue*/
			pMat->Discard(l);
			l--;
			lcol--;
			}
		else
			{
			for (l2 = l+1L; l2 <= lcol; l2++)
				{
				val = pVect->GetAt(l2);
				if (val > maxval)
					{
					maxval = val;
					maxl = l2;
					}
				}
				
			if (maxval != pVect->GetAt(l))
				{	/*A bigger value has been found, the order must be changed*/
				pMat->SwapCol(maxl, l);
				pVect->SwapCol(maxl, l);
				}
			}
		}
	
	pVect->Unlock();
	
	return number;
	}

⌨️ 快捷键说明

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