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

📄 facebase.cpp

📁 基于OpenCV的计算机视觉技术实现.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    float* dst_ = dst;

    for( int i = 0; i < num_vec; i++ )
    {
        memcpy( dst_, src_, dst_len * sizeof(float) );
        src_+= dst_len+1;
        dst_+= dst_len;
    }
}                            
		

void  CPerson::AddImage( const char* filename, CImage* import_image, CRect rect )
{
    char root[STR_BUF_SIZE];
    CPersonImage* image;
    int root_len;

    strcpy( root, m_folder );
    root_len = m_folder.GetLength();

    if( !filename )
    {
        ASSERT( import_image != 0 );
        GenerateFileName( 0, root );
    }
    else
    {
        GetPersonFullImageName( root, root_len, filename, root );
    }

    image = new CPersonImage;
    image->SetFileName( root );

    if( import_image )
    {
        CImage& dst_img = image->GetImage();
        IplImage* src_img = import_image->GetImage();
        IplROI* temp_roi;
        IplROI  roi;
        ASSERT( src_img != 0 );

        temp_roi = src_img->roi;
    
        if( rect.IsRectEmpty() )
        {
            src_img->roi = 0;
        }
        else
        {
            src_img->roi = &roi;
            roi = RectToROI( rect );
        }

        dst_img.CopyOf( *import_image, 0 );
        src_img->roi = temp_roi;
        image->SetRoiInFile( CRect(0,0,0,0));
        image->SetModified();

        // to reserve file name
        image->Save();
    }
    else
    {
        image->SetRoiInFile( rect );
        image->Load();
    }

    m_imgs.AddTail( image );
    SetModified();
}


void  CPerson::RemoveImage( POSITION pos )
{
    CPersonImage* image = m_imgs.GetAt( pos );
    if( image )
    {
        m_imgs.RemoveAt( pos );
        image->Unload();
        remove( image->GetFileName() );
        delete image;
        SetModified();
    }
}


void  CPerson::MoveToTop( POSITION pos )
{
    CPersonImage* image = m_imgs.GetAt( pos );
    if( image )
    {
        m_imgs.RemoveAt( pos );
        CPersonImage* old_head = m_imgs.GetHead();
        if( old_head ) old_head->Unload();
        m_imgs.AddHead( image );
        image->Load();
        SetModified( true );
    }
}


void CPerson::DeleteHMMInfo()
{
    m_trained = false;
    CString str = GetFolder() + "hmm.txt";
    remove( str );
}

void LightingCorrection(IplImage* ipl_image)
{
    CvSize roi;
    int step;
    uchar* img;
    
    cvGetImageRawData(ipl_image, &img, &step, &roi);
    
    int i, j;
    int width = roi.width;
    int height = roi.height;
    
    float x1, x2, y1, y2;
    int f[3] = {0, 0, 0};
    float a[3] = {0, 0, 0};
    
    float h1;
    float h2;
    
    float c1,c2;
    
    float min = FLT_MAX;
    float max = -FLT_MAX;
    float correction;
    
    float* float_img = (float*)malloc( width * height * sizeof(float) );
    
    x1 = width * (width + 1) / 2.0f; // Sum (1, ... , width)
    x2 = width * (width + 1 ) * (2 * width + 1) / 6.0f; // Sum (1^2, ... , width^2)
    y1 = height * (height + 1)/2.0f; // Sum (1, ... , width)
    y2 = height * (height + 1 ) * (2 * height + 1) / 6.0f; // Sum (1^2, ... , width^2)
    
    
    // extract grayvalues
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            f[2] = f[2] + j * img[i*step + j];
            f[1] = f[1] + i * img[i*step + j];
            f[0] = f[0] +     img[i*step + j];
        }
    }
    
    h1 = (float)f[0] * (float)x1 / (float)width;
    h2 = (float)f[0] * (float)y1 / (float)height;
    
    a[2] = ((float)f[2] - h1) / (float)(x2*height - x1*x1*height/(float)width);
    a[1] = ((float)f[1] - h2) / (float)(y2*width - y1*y1*width/(float)height);
    a[0] = (float)f[0]/(float)(width*height) - (float)y1*a[1]/(float)height - 
        (float)x1*a[2]/(float)width;
    
    for (i = 0; i < height; i++) 
    {    
        for (j = 0; j < width; j++)
        {
            
            correction = a[0] + a[1]*(float)i + a[2]*(float)j;
            
            float_img[i*width + j] = img[i*step + j] - correction;
            
            if (float_img[i*width + j] < min) min = float_img[i*width+j];
            if (float_img[i*width + j] > max) max = float_img[i*width+j];
        }
    }
    
    //rescaling to the range 0:255
    c2 = 0;
    if (max == min)
        c2 = 255.0f;
    else
        c2 = 255.0f/(float)(max - min);
    
    c1 = (-(float)min)*c2;
    
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            int value = (int)floor(c2*float_img[i*width + j] + c1);
            if (value < 0) value = 0;
            if (value > 255) value = 255;
            img[i*step + j] = (uchar)value;
        }
    }
    
    free( float_img );
    
}

void CPerson::TrainHMM()
{

    int color[24] = { RGB(255,128,128), RGB(255,255,128), RGB(128,255,128), RGB(128,255,255), RGB(0,128,255),
                      RGB(255,128,255), RGB(255,0,0), RGB(255,128,0), RGB(0,128,0), RGB(0,0,0), RGB(255,255,128),
                      RGB(255,0,128), RGB(255,128,128), RGB(255,255,128),RGB(128,255,128), RGB(128,255,255),
                      RGB(0,128,255),RGB(255,128,255),RGB(255,0,0),RGB(255,128,0),RGB(0,128,0), 
                      RGB(0,0,0),RGB(255,255,128), RGB(255,0,128)  };

    //training loop can be not converged
    const int max_iterations = 80;    

    CFaceBase* parent = GetParentBase();
    //CImage& segmentation = parent->GetTrainedImage();
    //segmentation.Create( 320, 320, 24 );

    int vect_len = parent->m_obsSize.height*parent->m_obsSize.width;

    //suppress first DCT coefficient
    if( parent->m_suppress_intensity)
    {
        vect_len--;
    }

    CvEHMM* hmm = m_hmm.GetIppiEHMM();
    if (!hmm) m_hmm.CreateHMM( parent->m_stnum, parent->m_mixnum, vect_len );

    hmm = m_hmm.GetIppiEHMM();

    //Create observation info
    int num_img = m_imgs.GetCount();

    
    CArray< CvImgObsInfo* , CvImgObsInfo* > obs_info;   
    obs_info.SetSize( num_img );

    CvImgObsInfo** obs_info_array = obs_info.GetData();

    for( int i = 0; i < num_img; i++ )
    {
        POSITION pos = m_imgs.FindIndex(i);
        IplImage* ipl = m_imgs.GetAt(pos)->GetImage().GetImage();

        bool doRescale = false;
        
        int new_height = 0;
        int new_width = 0;
 
        if ( parent->m_useWidth )
        {
            doRescale = true;
            new_width = parent->m_scaleWidth;
        }
        if ( parent->m_useHeight )
        {
            doRescale = true;
            new_height = parent->m_scaleHeight;
        }
        //recompute width or height if any is absent
        IplImage* ipl_scaled;
      
        CvSize image_roi = cvSize( ipl->roi ? ipl->roi->width : ipl->width, 
                                   ipl->roi ? ipl->roi->height : ipl->height );

        if ( doRescale )
        {
            if ( !new_width )
            {
                new_width  = new_height * image_roi.width / image_roi.height;
            }
            else if ( !new_height ) 
            {
                new_height  = new_width * image_roi.height / image_roi.width;
            }

            //rescale
            ipl_scaled = cvCreateImage( cvSize(new_width, new_height), IPL_DEPTH_8U, 1 );
                
            iplResizeFit(ipl, ipl_scaled, /*ipl_scaled->width, ipl->width, 
                      ipl_scaled->height, ipl->height,*/ IPL_INTER_NN);
                
        }
        else
            ipl_scaled = ipl;

        CvSize roi = cvSize( ipl_scaled->roi ? ipl_scaled->roi->width : ipl_scaled->width,
                               ipl_scaled->roi ? ipl_scaled->roi->height : ipl_scaled->height);


        CvSize num_obs;

        CV_COUNT_OBS( &roi, &(parent->m_dctSize), &(parent->m_delta), &num_obs ); 

              
        obs_info_array[i] = cvCreateObsInfo( num_obs, vect_len );

        CvImgObsInfo* info = obs_info_array[i];
               
        //IplImage* normalized_image = cvCreateImage( roi, IPL_DEPTH_8U, 1 );
        //NormalizeImageForHMM( ipl_scaled, normalized_image );

        if( parent->m_suppress_intensity )
        {
            float* observations = (float*)malloc( num_obs.height * num_obs.width * (vect_len+1) * sizeof(float) );
            cvImgToObs_DCT( /*normalized_image*/ipl_scaled, observations, parent->m_dctSize, parent->m_obsSize, parent->m_delta );
            ExtractDCT( observations, info->obs, num_obs.height * num_obs.width, vect_len );
            free( observations);
        }
        else
        {
            cvImgToObs_DCT( /*normalized_image*/ipl_scaled, info->obs, parent->m_dctSize, parent->m_obsSize, parent->m_delta );
        }
        
        if ( doRescale )
        {
            cvReleaseImage( &ipl_scaled );
        }

		//cvReleaseImage( &normalized_image );

        cvUniformImgSegm( info, hmm );

    }                                              

    cvInitMixSegm( obs_info_array, num_img, hmm );

    bool trained = false;
    float old_likelihood = 0;
    
    
    int counter = 0;

    while( (!trained) && (counter < max_iterations) )
    { 
        counter++;

        int j;
#if 0

        //segment images
        for( j = 0; j < 1; j++ )
        {       
            IplImage* ipl_segm = segmentation.GetImage();
            CvImgObsInfo* obs = obs_info_array[j];

            int counter=0;
            for(int k = 0; k < obs->obs_y; k++ )
            {
                for(int m = 0; m < obs->obs_x; m++,counter++ )
                {                       
                    cvCircle( ipl_segm, cvPoint( (parent->m_dctSize.width>>1) + 
                                               (parent->m_delta.width)* m ,
                                               (parent->m_dctSize.height>>1) + 
                                               (parent->m_delta.height)* k ), 3,
                                               color[obs->state[counter*2+1]], 1 );
                }
            } 

            parent->SetTrainedIndex(j);
            parent->UpdateTrainedImage();
            
        }        

#endif            

        cvEstimateHMMStateParams( obs_info_array, num_img, hmm);

        cvEstimateTransProb( obs_info_array, num_img, hmm); 
         
        float likelihood = 0;     
        for( j = 0; j < num_img; j++ )
        {           
            cvEstimateObsProb( obs_info_array[j], hmm );
            likelihood += cvEViterbi( obs_info_array[j], hmm );
        }
        likelihood /= num_img*obs_info_array[0]->obs_size;

        cvMixSegmL2( obs_info_array, num_img, hmm);

        trained = ( fabs(likelihood - old_likelihood) < 0.01 ); 
        old_likelihood = likelihood;                   
   }

   for(i = 0; i < num_img; i++ )
   {
        cvReleaseObsInfo( &(obs_info_array[i]) );
   }
   
   obs_info.RemoveAll();  
//   segmentation.Destroy();
 

   m_trained = true;
   Save();
   
}
          
/****************************************************************************************\
*                              CPersonImage class                                        *
\****************************************************************************************/

CPersonImage::CPersonImage()
{
    m_modified = false;
    m_roi_in_file = CRect(0,0,0,0);
}


CPersonImage::~CPersonImage()
{
    Unload();    
}


bool  CPersonImage::Load()
{
    bool res = m_img.LoadRect( m_filename, 0, m_roi_in_file ); // load as a grayscale image
    SetModified( false );
    return res;
}


void  CPersonImage::Unload()
{
    Save(); 
    m_img.Destroy();
}


bool  CPersonImage::Save()
{
    bool res = true;
    if( IsModified() )
    {
        res = m_img.Save( m_filename );
        SetModified( false );
    }
    return res;
}


void  CPersonImage::SetFileName( const CString& filename )
{
    m_filename = filename;
    SetModified( m_img.Width() != 0 );
}


void  CPersonImage::SetRoiInFile( CRect r )
{
    m_roi_in_file = r;
    SetModified( m_img.Width() != 0 );
}


void  CPersonImage::CalcRect( SIZE win_size, POINT pos, SIZE base_size,
                              CRect& src_rect, CRect& dst_rect )
{
    IplImage* src = m_img.GetImage();
    int  w, h;
    int  mul_k, div_k;
    CRect sr, dr;

    src_rect = dst_rect = CRect(0,0,0,0);
    
    w = src->width;
    h = src->height;

    sr.left = sr.top = 0;
    sr.right = w;
    sr.bottom = h;

    // calc scaling coefficients
    if( w*base_size.cy > h*base_size.cx )
    {
        mul_k = base_size.cx;
        div_k = w;
    }
    else
    {
        mul_k = base_size.cy;
        div_k = h;
    }

    // calc resultant width & height
    dr.right = w * mul_k/div_k;
    dr.bottom = h * mul_k/div_k;

    // calculate top-left coordinates
    dr.left = pos.x + (base_size.cx - dr.right)/2;
    dr.top = pos.y + (base_size.cy - dr.bottom)/2;

⌨️ 快捷键说明

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