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

📄 facebase.cpp

📁 基于OpenCV的计算机视觉技术实现.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*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 + -