📄 caam.cpp
字号:
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 + -