📄 facebase.cpp
字号:
}
CPerson* CFaceBase::GetPerson( int index )
{
ASSERT( index >= 0 );
POSITION pos = m_base.FindIndex( index );
return pos ? m_base.GetAt( pos ) : 0;
}
CPerson* CFaceBase::FindPersonByName( const CString& name )
{
POSITION pos = m_base.GetHeadPosition();
while( pos )
{
CPerson* person = m_base.GetNext(pos);
if( person && name.CompareNoCase( person->GetName()) == 0 ) return person;
}
return 0;
}
int CFaceBase::GetPersonIndex( CPerson* person )
{
POSITION pos = m_base.GetHeadPosition();
int i;
for( i = 0; pos != 0; i++ )
{
CPerson* p = m_base.GetNext(pos);
if( p == person ) return i;
}
return -1;
}
void CFaceBase::Draw( int index, CImage& img, SIZE win_size, int y_pos,
SIZE base_size, SIZE delta )
{
ASSERT( delta.cx > base_size.cx && delta.cy > base_size.cy );
int nx = MAX((win_size.cx + delta.cx - base_size.cx)/delta.cx,1);
int row = y_pos/delta.cy;
int idx0 = row*nx;
int x, y;
POSITION pos;
CPersonImgList* list = 0;
int count;
if( index >= 0 )
{
CPerson* person = GetPerson( index );
if( !person ) return;
list = &person->GetImgList();
count = list->GetCount();
}
else
{
count = m_base.GetCount();
}
if( !img.GetImage() || idx0 >= count ) return;
if( list )
{
pos = list->FindIndex( idx0 );
}
else
{
pos = m_base.FindIndex( idx0 );
}
for( y = row*delta.cy - y_pos + (delta.cy - base_size.cy)/2;
y < win_size.cy ; y += delta.cy )
{
for( x = (delta.cx - base_size.cx)/2; ; )
{
CPersonImage* src_img = 0;
if( list )
{
src_img = list->GetNext( pos );
}
else
{
CPerson* person = m_base.GetNext( pos );
if( person )
{
CPersonImgList& l = person->GetImgList();
if( !l.IsEmpty())
{
src_img = l.GetHead();
}
}
}
if( src_img )
{
src_img->Draw( img, win_size, CPoint( x, y ), base_size );
}
if( !pos ) return;
x += delta.cx;
if( x + base_size.cx > win_size.cx ) break;
}
}
}
void CFaceBase::UpdateTrainedImage()
{
if( m_base_view )
{
m_base_view->InvalidateRect(0);
m_base_view->UpdateWindow();
}
}
void CFaceBase::DeleteHMMInfo()
{
POSITION pos = m_base.GetHeadPosition();
while( pos )
{
CPerson* person = m_base.GetNext(pos);
if( person )
{
person->DeleteHMMInfo();
}
}
}
/****************************************************************************************\
* CPerson class *
\****************************************************************************************/
CPerson::CPerson( CFaceBase* parent )
{
m_modified = false;
m_trained = false;
m_parent = parent;
ASSERT( parent != 0 );
}
CPerson::~CPerson()
{
Unload();
}
void CPerson::SetName( const CString& name )
{
m_name = name;
SetModified();
}
void CPerson::SetFolder( const CString& folder )
{
m_folder = folder;
SetModified();
}
bool CPerson::GetPersonFullImageName( const char* root, int root_len,
const char* image, char* full_image_name )
{
char buffer[STR_BUF_SIZE];
char drive[STR_BUF_SIZE];
int len;
strcpy( buffer, image );
len = strlen( buffer );
if( len == 0 ) return false;
_splitpath( buffer, drive, 0, 0, 0 );
if( strlen( drive ) > 0 ) return false;
if( root != full_image_name )
{
strcpy( full_image_name, root );
}
strcpy( full_image_name + root_len, buffer );
return true;
}
void CPerson::ExtractPersonImageName( const char* full_image_name, char* image )
{
char buffer[STR_BUF_SIZE];
char name[STR_BUF_SIZE];
char ext[STR_BUF_SIZE];
strcpy( buffer, full_image_name );
_splitpath( buffer, 0, 0, name, ext );
strcpy( image, name );
strcat( image, ext );
}
bool CPerson::Load()
{
FILE* f = 0;
char buffer[STR_BUF_SIZE];
char root[STR_BUF_SIZE];
int root_len;
bool error = false;
CPersonImage* image = 0;
RECT roi;
bool already_read = false;
strcpy( root, m_folder );
root_len = m_folder.GetLength();
strcpy( root + root_len, "info.txt" );
f = fopen( root, "rt" );
if( !f ) return false;
m_imgs.RemoveAll();
// read header
if( !fgets( buffer, STR_BUF_SIZE, f ) || strcmp(buffer,person_signature))
return false;
if( !fgets( buffer, STR_BUF_SIZE, f ))
return false;
m_name = chomp( buffer );
// skip one line after the base name
fgets( buffer, STR_BUF_SIZE, f );
// create image list for the person and load the first image
for(;;)
{
if( !already_read && !fgets( buffer,STR_BUF_SIZE, f )) break;
already_read = false;
if( strlen(buffer) == 0 || buffer[0] == '#' ) continue;
chomp( buffer );
if( !GetPersonFullImageName( root, root_len, buffer, root ))
continue;
image = new CPersonImage;
image->SetFileName( root );
/* read ROI coordinates */
while( fgets( buffer,STR_BUF_SIZE, f ))
{
if( strlen(buffer) > 0 && buffer[0] == '#' ) continue;
already_read = true;
if( sscanf( buffer, "%u%u%u%u", &roi.left, &roi.top,
&roi.right, &roi.bottom ) == 4 )
{
roi.right += roi.left;
roi.bottom += roi.top;
image->SetRoiInFile( roi );
already_read = false;
}
break;
}
if( m_imgs.IsEmpty() && !image->Load() )
{
delete image;
error = true;
continue;
}
m_imgs.AddTail( image );
}
fclose(f);
//load hmm if present
strcpy( root + root_len, "hmm.txt" );
f = fopen(root,"rt");
if( !f ) m_trained = false;
else
{
fclose(f);
SetModified( error );
m_trained = m_hmm.Load( root );
}
return true;
}
void CPerson::Unload()
{
Save();
while( !m_imgs.IsEmpty() )
{
CPersonImage* image = m_imgs.RemoveHead();
delete image;
}
}
bool CPerson::Save()
{
if( IsModified() )
{
char buffer[STR_BUF_SIZE];
POSITION pos = m_imgs.GetHeadPosition();
while( pos )
{
CPersonImage* image = m_imgs.GetNext( pos );
image->Save();
}
strcpy( buffer, m_folder );
strcat( buffer, "info.txt" );
FILE* f = fopen( buffer, "wt" );
if( !f ) return false;
fputs( person_signature, f );
fputs( m_name, f );
fputs( "\n\n", f );
pos = m_imgs.GetHeadPosition();
// write image names and ROI coordinates
while( pos )
{
CPersonImage* image = m_imgs.GetNext( pos );
const CString& str = image->GetFileName();
CRect r = image->GetRoiInFile();
ExtractPersonImageName( str, buffer );
fprintf( f, "%s\n", buffer );
if( !r.IsRectEmpty() )
{
fprintf(f, "%5u%5u%5u%5u\n", r.left, r.top, r.Width(), r.Height() );
}
}
fclose(f);
}
if (IsTrained())
{
char buffer[STR_BUF_SIZE];
//save hmm
strcpy( buffer, m_folder );
strcat( buffer, "hmm.txt" );
m_hmm.Save( buffer );
}
else
{
char buffer[STR_BUF_SIZE];
strcpy( buffer, m_folder );
strcat( buffer, "hmm.txt" );
remove( buffer );
}
SetModified(false);
return true;
}
void CPerson::LoadRest()
{
// load all the face images starting from second (first is always loaded)
POSITION pos = m_imgs.FindIndex(1);
while( pos )
{
POSITION tmp_pos = pos;
CPersonImage* image = m_imgs.GetNext( pos );
if( !image->Load())
{
m_imgs.RemoveAt(tmp_pos);
SetModified();
delete image;
}
}
}
void CPerson::UnloadRest()
{
// load all the face images starting from second (first is always loaded)
POSITION pos = m_imgs.FindIndex(1);
while( pos )
{
CPersonImage* image = m_imgs.GetNext( pos );
image->Unload();
}
}
void CPerson::GenerateFileName( const char* base, char* filename )
{
char path[STR_BUF_SIZE];
int base_len = base ? strlen(base) : 0;
int i = 0;
if( base_len > 0 )
{
strcpy( filename, base );
}
else
{
char ext[STR_BUF_SIZE];
strcpy( path, m_folder );
// remove slash
path[m_folder.GetLength()-1] = '\0';
// use folder name as a base
_splitpath( path, 0, 0, filename, ext );
strcat( filename, ext );
base_len = strlen( filename );
}
for(;;)
{
FILE* f = 0;
for( ; i < 10000; i++ )
{
GetPersonFullImageName( m_folder, m_folder.GetLength(), filename, path );
sprintf( path + strlen(path), "%04d.bmp", i );
f = fopen( path, "rb" );
if( !f ) break;
fclose(f);
}
if( i == 10000 )
{
ASSERT(0);
return;
}
// try to open for writing. If success, output name
f = fopen( path, "wb" );
if( !f ) continue;
fclose(f);
remove( path );
strcpy( filename, path );
break;
}
}
void NormalizeIntensity(IplImage* ipl_image, int level)
{
CvSize roi;
int step;
uchar* img;
ASSERT( (level>0) && (level <=255) );
cvGetImageRawData(ipl_image, &img, &step, &roi);
int width = roi.width;
int height = roi.height;
int mean = (int)cvMean( ipl_image );
// normalize to 128
for( int i = 0; i < height; i++, img+=step )
{
for( int j = 0; j < width; j++ )
{
int newval = img[j] + level - mean;
newval = (newval < 0) ? 0 : newval;
newval = (newval > 255) ? 255 : newval;
img[j] = newval;
}
}
}
void NormalizeImageForHMM( IplImage* ipl_scaled, IplImage* normalized_image )
{
iplFixedFilter( ipl_scaled, normalized_image, IPL_SOBEL_3x3_H );
}
void ExtractDCT( float* src, float* dst, int num_vec, int dst_len )
{
float* src_ = src+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -