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

📄 cfacedb.cpp

📁 face recognition test source code
💻 CPP
字号:
#include "stdafx.h"

#include "CFace.h"
#include "CFaceDB.h"
#include "error.h"
#include "str.h"
#include "utilcpp.h"
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <io.h>
#include <stdlib.h> 

CFaceDB::CFaceDB()
	{
	pArray = new CObArray();
	nNumFace = 0;
	}

CFaceDB::~CFaceDB()
	{
	int l, len = pArray->GetUpperBound();
	
	for (l = len; l >= 0; l--)
		{
		delete pArray->GetAt(l);
		pArray->RemoveAt(l);
	   }
	   
	delete pArray;															/*Deletes the objects of the area and the area itself*/
	}

/*********************************************************************************************
* Read the one face and append it to the databasee. 
* The character string parameter must contain the face's file name followed by the face's name.
* Between these two, there must be some tab characters.
*  
* It returns 0 if all was ok, a negatib\ve value in case of any errors
*********************************************************************************************/
int CFaceDB::AddFace(char *data)
	{
	int ret, index;
	long xlent, ylent;
	char *str_line = 0;
   char FileName[255];
   char FaceName[64];
   CFace *pFace = NULL, *pFace0 = NULL;
   int err = 0;
   	
	strcpy(FileName, "");
	strcpy(FaceName, "");
	GetLine(data, FileName, sizeof(FileName)/sizeof(char), FaceName, sizeof(FaceName)/sizeof(char));
	
	index = pArray->Add(new CFace(FileName, FaceName));
	nNumFace++;

	pFace = (CFace*)(pArray->GetAt(index));			/*Put the address of the face element in the pointer pFace*/
	if (pFace == NULL)
		{
		nNumFace--;
		return 0;
		}
	ret = pFace->Load();										/*Load the image data of the face from the disk*/
	if (ret < 0)
		{
		pArray->RemoveAt(index);
		delete pFace;
		nNumFace--;
		return 0;
		}
	
	pFace0 = (CFace*)(pArray->GetAt(0));				/*Put the address of the first face element in the pointer pFace*/
	xlen = pFace0->Getxlen();								/*gets the face's dimensions*/
	ylen = pFace0->Getylen();
	
	/*Verify that this faces have the same dimensions as the first one*/
	xlent = pFace->Getxlen();
	ylent = pFace->Getylen();
	if (xlent != xlen || ylent != ylen)
		{
		Msg(0, str_ERR_DIMENSION, pFace->GetFileName(), xlen, ylen, xlent, ylent);
		pArray->RemoveAt(index);							/*Remove the face from the array*/
		delete pFace;											/*delete the face object*/
		nNumFace--;												/*Decrease the number of faces in our database*/
		return 0;
		}		
	
	return 0; 
	}
	
/*********************************************************************************************
* Read the face database file. the character string parameter is a stream of lines. Each line
* contains the mac full path name of a face file of the database.
*  
* It returns 0 if all was ok, a negatib\ve value in case of any errors
*********************************************************************************************/
int CFaceDB::Load(char *data)
	{
	int ret, i;
	long xlent, ylent;
	char *str_line = 0;
   char FileName[255];
   char FaceName[64];
   CFace *pFace = 0;
   int err = 0;
   	
	while (isalpha(data[0]) == 0)
		data++;
		
	str_line = strtok(data, str_RET);
	while (str_line != NULL)
		{															/*while there are file name in the TRAINING directory*/
		strcpy(FileName, "");
		strcpy(FaceName, "");
		GetLine(str_line, FileName, sizeof(FileName)/sizeof(char), FaceName, sizeof(FaceName)/sizeof(char));
		if (FileName[0] != chr_PROJ_COMMENT)
			{       
			pArray->Add(new CFace(FileName, FaceName));
			nNumFace++;
			}
		str_line = strtok(NULL, str_RET);
		}                    
		
	for (i = 0; i < nNumFace; i++)
		{
		pFace = (CFace*)(pArray->GetAt(i));				/*Put the address of the ith face element in the pointer pFace*/
		ret = pFace->Load();									/*Load the image data of the face from the disk*/
#if 0
		if (ret == ERR_FILE_OPEN)
			{														/*Cannot open a file*/
																	/*probably because EOF was not detected*/
			break;												/*So there was one too much record in the face database*/
			}
#endif
		if (ret < 0)
			{
			pArray->RemoveAt(i);
			delete pFace;
			i--;
			nNumFace--;
			}
		}
	
	if (nNumFace == 0)
		return -1;
	
	pFace = (CFace*)(pArray->GetAt(0));					/*Put the address of the first face element in the pointer pFace*/
	xlen = pFace->Getxlen();								/*gets the face's dimensions*/
	ylen = pFace->Getylen();
	
	/*Verify that all the faces have the same dimensions*/
	for (i = 1; i < nNumFace; i++)
		{
		pFace = (CFace*)(pArray->GetAt(i));				/*Put the address of the ith face element in the pointer pFace*/
		xlent = pFace->Getxlen();
		ylent = pFace->Getylen();
		if (xlent != xlen || ylent != ylen)
			{
			Msg(0, str_ERR_DIMENSION, pFace->GetFileName(), xlen, ylen, xlent, ylent);
			pArray->RemoveAt(i);							/*Remove the face from the array*/
			delete pFace;									/*delete the face object*/
			i--;
			nNumFace--;										/*Decrease the number of faces in our database*/
			}		
		}
	
	return 0; 
	}
	
/**********************************************************************************************
* CFaceDB::GetLine gets a face database's line from the string str_temp. It separates the elements
* of the line into FileName (the file's name full path name), and FaceName (the face's name).
* lenFileName is the length of the char array FileName and lenFaceName is the one of FaceName.
* If a line is a comment, it put the comment character in the first character of filename
*
* it returns 0 if all is ok, a negative number in case of any errors.
**********************************************************************************************/
int CFaceDB::GetLine(char *str_temp, char *FileName, int lenFileName, char *FaceName, int lenFaceName)
	{
	int i;
	
	while(isalpha(str_temp[0]) == 0 && str_temp[0] != chr_PROJ_COMMENT && (str_temp[0] != chr_RT1 && str_temp[0] != chr_RT2) && str_temp[0] != 0)
		str_temp++;											/*look for the first alphabetic character*/
	
	if (str_temp[0] == 0)
		return -1;
	
	if (str_temp[0] == chr_PROJ_COMMENT)
		{
		FileName[0] = chr_PROJ_COMMENT;
		return 0;
		}
	
	i = GetStr(str_temp, FileName, lenFileName, str_TABRT);	/*put the file name (the first name in the line) in aName*/
	str_temp = str_temp + i;								/*increase the string*/
	
	while(isalpha(str_temp[0]) == 0 && (str_temp[0] != chr_RT1 && str_temp[0] != chr_RT2) && str_temp[0] != 0)
		str_temp++;											/*look for the first alphabetic character*/
	
	if (str_temp[0] == 0)
		return 0;
	
	if (str_temp[0] != chr_RT1 && str_temp[0] != chr_RT2)
		{													/*there is a face's name*/
		i = GetStr(str_temp, FaceName, lenFaceName, str_TABRT);
															/*put the face's name in fName*/
		str_temp = str_temp + i;							/*increase the string*/
		}
		
	return 0;
	}
	
/**********************************************************************************************
* GetStr get the first string, not containing any of the characters in Delimit, of the string 
* str_temp, put it in aName (which length is the integer lenaName, and increase the pointer str_temp 
* to the end of the word (copied into aName). So str_temp is changed by the fct, 
* therefore the ADDRESS of a pointer to a string must be passed.
* The calling function must keep a pointer to the beginning of str_temp, in order to keep the
* memory safe and not to lose anything.
* 	char *str_temp		pointer to the beginning of the string
*	char aName[]		array of char that will receive the word
*	int lenaName		length of aName
*	return nothing.
**********************************************************************************************/
int CFaceDB::GetStr(char *str_temp, char *aName, int lenaName, char *Delimit)
	{
	int i;
	
	i = 0;
	while (strchr(Delimit, str_temp[i]) == NULL && i < strlen(str_temp))					
		i++;														/*look for the end of the word*/
	strncpy(aName, str_temp, __min(i, lenaName));	/*copy the word*/
	aName[i] = 0;
	return i;								
	}
	
/**********************************************************************************************
* GetLong gets the first word (which must be a number) of the string str_temp, convert it into a 
* long value, increase the pointer str_temp to the end of the word, and return the value.
* The calling function must keep a pointer to the beginning of str_temp, in order to keep the
* memory safe and not to lose anything.
* 	char *str_temp		pointer to the beginning of the string
*	return the long value
**********************************************************************************************/
long CFaceDB::GetLong(char *str_temp)
	{
	int i;
	long ret;
	
	ret = atol(str_temp);
	
	i = 0;
	while (isdigit(str_temp[i]) == 0 && str_temp[i] != chr_RT1 && str_temp[i] != chr_RT2)					
		i++;												/*look for the end of the number*/
															/*increase the string*/
	
	return ret;
	}
	
/**********************************************************************************************
* Deletes all the faces in this database and puts the faces contained in the matrix by copying
* each column data to a CFace object. The Faces' names are the values contained in the diagonal
* matrix.
* Beware : it is only the value of the pointer which is copied, the actual data are NOT copied.
**********************************************************************************************/
int CFaceDB::Copy(CMatrixPtr *pMat, CDiag *pDiag)
	{
	long col, l;
	CFace *pFace = NULL;
	char name[10];
	int c, l2, len = pArray->GetUpperBound();
		
	/*first delete all the elements*/
	
	for (l2 = len; l2 >= 0; l2--)
		{
		delete pArray->GetAt(l2);
		pArray->RemoveAt(l2);
	   }
	   
	delete pArray;												/*Deletes the objects of the area and the area itself*/
	pArray = new CObArray();
	
	/*second iterates on all the columns*/
	col = pMat->GetCol();									/*Verify that the matrix and the vectors have the same number of columns*/
	l = pDiag->GetCol();
	if (l < col)
		{
		Msg(0, str_ERR_MAT_COPY);
		Fail(0);
		}
	
	pDiag->Lock();
	
	for (c = 1; c <= col; c++)
		{
		sprintf(name, "%.2E", pDiag->GetAt(c));
		pArray->Add(new CFace("", name));
		
		pFace = (CFace*)(pArray->GetAt(c-1));				/*Put the address of the ith face element in the pointer pFace*/
		pFace->Copy(pMat, c);								/*Copy the values in the CFace object*/
		nNumFace++;
		}
	
	pDiag->Unlock();
		
	pFace = (CFace*)(pArray->GetAt(0));					/*Put the address of the first face element in the pointer pFace*/
	xlen = pFace->Getxlen();								/*gets the face's dimensions*/
	ylen = pFace->Getylen();
	
	return 0;
	}
	
/**********************************************************************************************
* Saves in the full mac pathname str_dir, the whole face database
* Each face is saved in a PGM file
**********************************************************************************************/
int CFaceDB::Save(char *str_dir)
	{
	int len, n;
	char str_path[200], str_number[10], str_path_real[200];
	CFace *pFace;
	
	len = 0;
	while (str_dir[len] == ' ' || str_dir[0] == '\t')
		len++;
	strcpy(str_path, str_dir + len);
		 
	n = 0;
	len = pArray->GetSize();
	for (n = 0; n < len; n++)
		{
		pFace = (CFace*)(pArray->GetAt(n));
		
		strcpy(str_path_real, str_path);
		sprintf(str_number, "%i", n+1);
		strcat(str_path_real, str_number);
		pFace->SetFileName(str_path_real);
		pFace->Save();
		}
	
	return 0;
	}
	
void CFaceDB::Expand(int nFace, float *scale, float *shift, float dest_min, float dest_max)
	{
	CFace *pFace = (CFace*)(pArray->GetAt(nFace-1));/*Put the address of the ith face element in the pointer pFace*/
	pFace->Expand(scale, shift, dest_min, dest_max);
	}
	
long CFaceDB::Getxlen()
	{return xlen;}
	
long CFaceDB::Getylen()
	{return ylen;}
	
long CFaceDB::GetNumFace()
	{return nNumFace;}
	
long CFaceDB::GetNumPixel()
	{return Getxlen() * Getylen();}
	
CMemory* CFaceDB::GetFaceMem(int l)
	{
	CFace *pFace = (CFace*)(pArray->GetAt(l-1));		/*Put the address of the ith face element in the pointer pFace*/
	return pFace->GetMem();
	} 
	
char *CFaceDB::GetFaceName(int l)
	{
	CFace *pFace = (CFace*)(pArray->GetAt(l-1));		/*Put the address of the ith face element in the pointer pFace*/
	return pFace->GetName();
	}
	
typeface *CFaceDB::GetFaceData(int l)
	{
	CFace *pFace = (CFace*)(pArray->GetAt(l-1));		/*Put the address of the ith face element in the pointer pFace*/
	return pFace->GetData();
	} 
	
void CFaceDB::ReleaseFaceData(int l)
	{
	CFace *pFace = (CFace*)(pArray->GetAt(l-1));		/*Put the address of the ith face element in the pointer pFace*/
	pFace->ReleaseData();
	} 
	
CFace *CFaceDB::GetFace(int l)
	{
	return (CFace*)(pArray->GetAt(l-1));
	}

⌨️ 快捷键说明

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