📄 facebase.cpp
字号:
// calculate bottom-right coordinates
dr.right += dr.left;
dr.bottom += dr.top;
// rough clipping
if( !(dr.right < 0 || dr.bottom < 0 || dr.left > win_size.cx || dr.top > win_size.cy))
{
// fine clipping
if( dr.left < 0 )
{
sr.left = -dr.left * div_k/mul_k;
dr.left = 0;
}
if( dr.top < 0 )
{
sr.top = -dr.top * div_k/mul_k;
dr.top = 0;
}
if( dr.right > win_size.cx )
{
sr.right -= (dr.right - win_size.cx) * div_k/mul_k;
dr.right = win_size.cx;
}
if( dr.bottom > win_size.cy )
{
sr.bottom -= (dr.bottom - win_size.cy) * div_k/mul_k;
dr.bottom = win_size.cy;
}
if( !(sr.Width() <= 0 || sr.Height() <= 0 ||
dr.Width() <= 0 || dr.Height() <= 0))
{
src_rect = sr;
dst_rect = dr;
}
}
}
void CPersonImage::Draw( CImage& img, SIZE win_size, POINT pos, SIZE base_size )
{
IplImage* dst = img.GetImage();
IplImage* src = m_img.GetImage();
IplROI *src_roi_tmp, *dst_roi_tmp;
IplROI src_roi, dst_roi;
ASSERT( dst != 0 );
CRect sr, dr;
if( !src ) return;
src_roi_tmp = src->roi;
dst_roi_tmp = dst->roi;
src->roi = &src_roi;
dst->roi = &dst_roi;
CalcRect( win_size, pos, base_size, sr, dr );
if( !sr.IsRectEmpty() && !dr.IsRectEmpty())
{
// set ROIs
src_roi = RectToROI( sr );
dst_roi = RectToROI( dr );
iplResize( src, dst, dst_roi.width, src_roi.width,
dst_roi.height, src_roi.height, IPL_INTER_LINEAR );
}
src->roi = src_roi_tmp;
dst->roi = dst_roi_tmp;
}
void CFaceBase::TrainPerson(int index, bool loaded)
{
CPerson* person = GetPerson( index );
ASSERT( person );
if (!person) return;
if (person->IsTrained() ) return;
CPersonImgList& imgs = person->GetImgList();
int num_img = imgs.GetCount();
if ( !loaded )
{
person->LoadRest();
person->TrainHMM();
person->UnloadRest();
}
else
person->TrainHMM();
}
void CFaceBase::TrainAll(int flag)
{
for( POSITION pos = m_base.GetHeadPosition(); pos ; )
{
CPerson* person = m_base.GetNext(pos);
if ((flag == TRAIN_UNTRAINED) && person->IsTrained() ) continue;
person->LoadRest();
person->TrainHMM();
person->UnloadRest();
}
Save();
}
int CFaceBase::RecognizeBatch(CStringList* image_list)
{
int images_processed = 0;
int right_recognized = 0;
int wrong_recognized = 0;
POSITION pos = image_list->GetHeadPosition();
while( pos )
{
CString path = image_list->GetNext(pos);
//check if person exists in base
char drive[1024], dir[1024], fname[256], ext[32];
_splitpath( path, drive, dir, fname, ext );
CString input_name = fname;
input_name.Delete( input_name.GetLength() - 4, 4 );
//find person with such name
if ( !FindPersonByName( input_name ) ) continue;
CImage img;
img.Load( path, 0 );
//do recognition
int pers_ind[2048];
int num = RecognizePerson( img, CRect(0,0,0,0), pers_ind );
ASSERT( num );
CPerson* person = GetPerson( pers_ind[0] );
ASSERT( person );
CString person_name = person->GetName();
//compare recognized person name and input file name
if( person_name == input_name )
{
right_recognized++;
}
else
{
wrong_recognized++;
}
images_processed++;
}
//output results
CString message;
message.Format("Total images processed %d\nRight recognized %d\nReco rate is %.1f%% ",
images_processed, right_recognized, 100*(float)right_recognized/(float)images_processed );
MessageBox( 0, message, "Batch recognition results", MB_OK );
return 1;
}
int CFaceBase::RecognizePerson(CImage& image, CRect rect, int* three_first)
{
if ( rect == CRect( 0,0,0,0 ) )
{
rect.bottom = image.Height();
rect.right = image.Width();
}
float like_array[1000]; ASSERT( m_base.GetCount() < 1000 );
CImage gray_img;
gray_img.CopyOf( image, 0 );
IplImage* ipl = gray_img.GetImage();
cvSetImageROI( ipl, RectToCvRect( rect ));
int code = 1;
bool doRescale = false;
int new_height = 0;
int new_width = 0;
if ( m_useWidth )
{
doRescale = true;
new_width = m_scaleWidth;
}
if ( m_useHeight )
{
doRescale = true;
new_height = m_scaleHeight;
}
//recompute width or height if any is absent
IplImage* ipl_scaled;
if ( doRescale )
{
if ( !new_width )
{
new_width = new_height * ipl->roi->width / ipl->roi->height;
}
else if ( !new_height )
{
new_height = new_width * ipl->roi->height / ipl->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 cvroi = cvSize( ipl_scaled->roi ? ipl_scaled->roi->width : ipl_scaled->width,
ipl_scaled->roi ? ipl_scaled->roi->height : ipl_scaled->height);
CvSize num_obs;
CvImgObsInfo* info;
CV_COUNT_OBS( &cvroi, &m_dctSize, &m_delta, &num_obs );
int vect_len = m_obsSize.height*m_obsSize.width;
if( m_suppress_intensity )
{
vect_len--;
}
info = cvCreateObsInfo( num_obs, vect_len );
if( 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, m_dctSize, m_obsSize, m_delta );
ExtractDCT( observations, info->obs, num_obs.height * num_obs.width, vect_len );
free( observations);
}
else
{
//IplImage* normalized_image = cvCreateImage( cvroi, IPL_DEPTH_8U, 1 );
//NormalizeImageForHMM( ipl_scaled, normalized_image );
cvImgToObs_DCT( /*normalized_image*/ipl_scaled, info->obs, m_dctSize, m_obsSize, m_delta );
//cvReleaseImage(&normalized_image);
}
if ( doRescale )
{
cvReleaseImage( &ipl_scaled );
}
float max_like = -100000000;
//int recognized = -1;
for( int i = 0 ; i < m_base.GetCount(); i++ )
{
CPerson* person = m_base.GetAt( m_base.FindIndex(i) );
CvEHMM* hmm = 0;
if( !person->IsTrained() )
{
code = 0;
break;
}
hmm = person->GetHMM().GetIppiEHMM();
if (!hmm) //person not trained
{
code = 0;
break;
}
cvEstimateObsProb( info, hmm );
like_array[i] = cvEViterbi( info, hmm );
}
cvReleaseObsInfo( &info );
gray_img.Destroy();
if( !code ) return code;
for( i = 0; i < MIN(3,m_base.GetCount()) ; i++ )
{
float maxl = -FLT_MAX;
int maxind = -1;
for( int j = 0; j < m_base.GetCount(); j++ )
{
if (like_array[j] > maxl) { maxl = like_array[j]; maxind = j; }
}
three_first[i] = maxind;
like_array[maxind] = -FLT_MAX;
}
return MIN(3,m_base.GetCount());
}
CContEHMM& CPerson::GetHMM()
{
return m_hmm;
}
int CFaceBase::SetParams( //sampling params
CvSize dctSize,
CvSize obsSize,
CvSize delta,
//HMM params
int* states, int mix,
//image scaling params
BOOL use_width, int width,
BOOL use_height, int height,
BOOL suppress_intens, BOOL leave_hmm_alive)
{
BOOL clearHMM = FALSE;
//sampling params
if ( (dctSize.height != m_dctSize.height) || (dctSize.width != m_dctSize.width) ||
(obsSize.height != m_obsSize.height) || (obsSize.width != m_obsSize.width) ||
(delta.height != m_delta.height) || (delta.width != m_delta.width) ||
(m_suppress_intensity != suppress_intens ) )
{
clearHMM = TRUE;
}
m_dctSize = dctSize;
m_obsSize = obsSize;
m_delta = delta;
m_suppress_intensity = suppress_intens;
//hmm params
BOOL dochange = FALSE;
for( int i = 0; i <= states[0]; i++ )
{
if ( m_stnum[i] != (states[i]) )
{
dochange = TRUE;
break;
}
}
if ( mix != m_mixnum[0] )
dochange = TRUE;
if ( dochange )
{
//change hmm params
int counter = 0;
for( int i = 0; i <= states[0]; i++ )
{
m_stnum[i] = (states[i]);
for( int j = 0; j < states[i]; j++, counter++ )
{
m_mixnum[counter] = mix;
}
}
clearHMM |= dochange;
}
//image scaling params
if ( (m_useWidth != use_width) ||
(m_useHeight != use_height) )
{
clearHMM = TRUE;
}
else if ( ( m_useWidth && (width != m_scaleWidth) ) ||
( m_useHeight && (height != m_scaleHeight) ) )
{
clearHMM = TRUE;
}
m_useWidth = use_width;
m_useHeight = use_height;
m_scaleWidth = width;
m_scaleHeight = height;
if( clearHMM && (!leave_hmm_alive) )
{
for ( int i = 0; i < m_base.GetCount(); i++ )
{
CPerson* person = GetPerson( i );
person->ClearHMM();
person->SetModified(true);
}
}
return clearHMM;
}
void CPerson::ClearHMM()
{
m_hmm.Release();
m_trained = false;
}
int CFaceBase::RecognizeOtherBase(CFaceBase* other)
{
CWaitCursor wait;
int total = 0;
int right = 0;
int wrong = 0;
//iterate through all persons and all images
for( int i = 0; i < other->GetPersonList().GetCount(); i++ )
{
CPerson* other_person = other->GetPerson( i );
CPerson* this_person = FindPersonByName( other_person->GetName() );
//match person with original base
if ( this_person )
{
other_person->LoadRest();
//iterate images
CPersonImgList& list = other_person->GetImgList();
POSITION pos = list.GetHeadPosition();
while ( pos )
{
int indices[2048]; //2 kilomen
CPersonImage* img = list.GetNext(pos);
RecognizePerson( img->GetImage(), CRect(0,0,0,0), indices );
if ( GetPerson( indices[0] ) == this_person )
{
right++;
}
else
{
wrong++;
}
total++;
//write number of already processed images to status bar
//CString RecogResult;
char RecogResult[64];
CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
frame->GetStatusBar()->SetPaneText(0, "");
//RecogResult.Format("Processed %d images", total );
sprintf( RecogResult, "Processed %d images", total );
frame->GetStatusBar()->SetPaneText(0, RecogResult);
// frame->GetStatusBar()->RedrawWindow();
frame->RedrawWindow();
}
other_person->UnloadRest();
}
}
//message
CString message;
ASSERT( total == (right + wrong) );
message.Format("Total images processed %d\nRight recognized %d\nReco rate is %.1f%% ",
total, right, 100*(float)right/(float)total );
MessageBox( 0, message, "Batch recognition results", MB_OK );
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -