📄 facebase.cpp
字号:
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 + -