📄 facebase.cpp
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/// FaceBase.cpp: implementation of the CFaceBase class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MainFrm.h"
#include "HMMDemo.h"
#include "FaceBase.h"
#include "direct.h"
#include <math.h>
#include <float.h>
#include <process.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// globals
static const char* base_signature = "FACE DATABASE\n";
static const char* person_signature = "PERSONAL INFO\n";
void ConvertNameToFolder( const char* name, char* folder )
{
int i, j = 0;
int len = strlen(name);
for( i = 0; i < len; i++ )
{
if( name[i] == ' ' )
{
if( j == 0 || folder[j-1] != '.' )
{
folder[j++] = '.';
}
}
else
{
folder[j++] = name[i];
}
}
folder[j] = '\0';
}
/***************************************************************************************\
Face data base structure:
<root_folder>\
<person_folder_1>\
<image_11>
<image_12>
<image_13>
...
info.txt
<person_folder_2>\
<image_21>
<image_22>
<image_23>
...
info.txt
<person_folder_3>\
<image_21>
<image_22>
<image_23>
...
info.txt
...
<index_file>
( names in <> brackets can be arbitrary ).
e.g.
NNBase\
Abrosimov.Dmirty\
ad_1.bmp
ad_near_window.bmp
ad_smiling.bmp
index.txt
Oblomov.Sergey\
serg.bmp
photo_3.bmp
index.txt
NNBaseIndex.txt
Main base index file contains name of the base followed by list of personal folders.
Format is the following:
line content
--------------------------------
1 FACE DATABASE (signature)
2 base name/description
3 <empty line>
4 <person_folder1>
5 <person_folder2>
... ...
In every personal folder there is a file with predefined name: info.txt
It contains person name followed by list of images for that person.
line content
--------------------------------
1 PERSONAL INFO (signature)
2 person name/description
3 <empty line>
4 <image_name1>
5 [<roi1>]
6 <image_name2>
7 [<roi2>]
... ...
Every image name may be followed by four numbers which are represent coordinates of
top-left corner of the face rectangle in the image and width and height
of the rectnagle, if no roi is specified, the entire image is considered as a face.
lines, started with #, are comments, and skipped when file is readed.
\***************************************************************************************/
static char* chomp( char* str )
{
int l = strlen( str );
if( l > 0 && str[l-1] == '\n' )
{
str[l-1] = '\0';
}
return str;
}
const int STR_BUF_SIZE = 1000;
/****************************************************************************************\
* CFaceBase class *
\****************************************************************************************/
// CFaceBase
CFaceBase::CFaceBase()
{
//default parameters
m_stnum[0] = 5;
m_stnum[1] = 3;
m_stnum[2] = 6;
m_stnum[3] = 6;
m_stnum[4] = 6;
m_stnum[5] = 3;
for( int i = 0; i < 128; i++ )
{
m_mixnum[i] = 3;
}
m_modified = false;
m_trained_index = -1;
m_base_view = 0;
SetImageSize( CSize(100,120) );
m_delta = cvSize(4,4);
m_obsSize = cvSize(3,3);
m_dctSize = cvSize(12,12);
m_useWidth = FALSE;
m_useHeight = FALSE;
m_scaleWidth = 0;
m_scaleHeight = 0;
m_suppress_intensity = FALSE;
}
CFaceBase::~CFaceBase()
{
Unload();
}
void CFaceBase::SetFileName( const CString& filename )
{
m_filename = filename;
SetModified();
}
void CFaceBase::SetName( const CString& name )
{
m_basename = name;
SetModified();
}
void CFaceBase::GetRootFolder( char* root_folder, int* root_path_len )
{
char buffer[STR_BUF_SIZE];
// construct root folder path
_splitpath( m_filename, root_folder, buffer, 0, 0 );
strcat( root_folder, buffer );
if( root_path_len ) *root_path_len = strlen( root_folder );
}
bool CFaceBase::GetPersonFolder( const char* root_folder, int root_folder_len,
const char* person_folder, char* folder )
{
char buffer[STR_BUF_SIZE];
char drive[STR_BUF_SIZE];
int len;
strcpy( buffer, person_folder );
len = strlen( buffer );
if( len == 0 ) return false;
// add slash (if absent)
if( buffer[len-1] != '\\')
{
buffer[len] = '\\';
buffer[len+1] = '\0';
}
_splitpath( buffer, drive, 0, 0, 0 );
if( strlen( drive ) > 0 ) return false;
if( root_folder != folder )
{
strcpy( folder, root_folder );
}
strcpy( folder + root_folder_len, buffer );
return true;
}
void CFaceBase::GetPersonSubFolder( const char* folder, char* subfolder )
{
char buffer[STR_BUF_SIZE];
char name[STR_BUF_SIZE];
char ext[STR_BUF_SIZE];
strcpy( buffer, folder );
ASSERT( buffer[strlen(buffer)-1] == '\\' );
// delete slash
buffer[strlen(buffer)-1] = '\0';
_splitpath( buffer, 0, 0, name, ext );
strcpy( subfolder, name );
strcat( subfolder, ext );
}
bool CFaceBase::Load()
{
FILE* f = 0;
char buffer[STR_BUF_SIZE];
char root_folder[STR_BUF_SIZE];
int root_path_len;
bool error = false;
if( m_filename.GetLength() == 0 ) return false;
f = fopen( m_filename, "rt" );
if( !f ) return false;
m_base.RemoveAll();
if( !fgets( buffer, STR_BUF_SIZE, f ) || strcmp( buffer, base_signature ))
return false;
// read header
if( !fgets( buffer, STR_BUF_SIZE, f )) return false;
m_basename = chomp( buffer );
// construct root folder path
GetRootFolder( root_folder, &root_path_len );
// skip one line after the base name
fgets( buffer, STR_BUF_SIZE, f );
// load all the people data
for(;;)
{
CPerson* person;
if( !fgets( buffer,STR_BUF_SIZE, f )) break;
if( strlen(buffer) == 0 || buffer[0] == '#' ) continue;
chomp( buffer );
if( !GetPersonFolder( root_folder, root_path_len, buffer, root_folder ))
continue;
person = new CPerson( this );
person->SetFolder( root_folder );
if( !person->Load() )
{
delete person;
error = true;
continue;
}
m_base.AddTail( person );
}
fclose(f);
SetModified( error );
return true;
}
void CFaceBase::Unload()
{
Save();
while( !m_base.IsEmpty() )
{
CPerson* person = m_base.RemoveHead();
delete person;
}
}
bool CFaceBase::Save()
{
if( m_filename.GetLength() > 0 )
{
POSITION pos = m_base.GetHeadPosition();
while( pos )
{
CPerson* person = m_base.GetNext( pos );
person->Save();
}
if( IsModified() )
{
FILE* f = fopen( m_filename, "wt" );
char subfolder[STR_BUF_SIZE];
if( !f ) return false;
fputs( base_signature, f );
fputs( m_basename, f );
fputs( "\n\n", f );
pos = m_base.GetHeadPosition();
while( pos )
{
CPerson* person = m_base.GetNext( pos );
const CString& str = person->GetFolder();
GetPersonSubFolder( str, subfolder );
fprintf( f, "%s\n", subfolder );
}
fclose(f);
}
SetModified(false);
//save config file
CString cfg_name;
cfg_name = GetFileName();
cfg_name.Replace( ".txt", "CFG.txt" );
//save parameters (HMM, Sampling etc.) for whole application
CHMMDemoApp* app = (CHMMDemoApp*)AfxGetApp();
//check if any trained person
BOOL save_config = TRUE;//FALSE;
/*for( int i = 0; i < m_base.GetPersonList().GetCount(); i++ )
{
CPerson* person = m_base.GetPerson(i);
if ( person->IsTrained() )
{
save_config = TRUE;
break;
}
}*/
if ( save_config ) app->SaveConfig( cfg_name );
else remove( cfg_name );
}
return true;
}
CPerson* CFaceBase::AddPerson( const char* name, const char* folder, bool import_data )
{
char temp_folder[STR_BUF_SIZE];
char root_folder[STR_BUF_SIZE];
CPerson* person = 0;
int len;
if( !import_data )
{
ASSERT( strlen( name ) > 0 );
if( !folder )
{
ConvertNameToFolder( name, temp_folder );
folder = temp_folder;
}
}
else
{
ASSERT( strlen( folder ) > 0 && name == 0 );
}
GetRootFolder( root_folder, &len );
GetPersonFolder( root_folder, len, folder, root_folder );
person = new CPerson( this );
person->SetFolder( root_folder );
if( import_data )
{
if( !person->Load())
{
delete person;
person = 0;
}
}
else
{
_mkdir( root_folder );
person->SetName( name );
person->SetModified();
}
if( person )
{
m_base.AddTail( person );
SetModified();
}
return person;
}
void CFaceBase::RemovePerson( POSITION pos )
{
CPerson* person = m_base.GetAt( pos );
if( person )
{
person->Unload();
m_base.RemoveAt( pos );
delete person;
SetModified();
}
}
void CFaceBase::SetImageSize( CSize size )
{
m_baseImgSize = size;
SetModified();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -