📄 lgmm.cpp
字号:
if(!m_ptr[i]->m_background)//false->true
{
if(i == match)
{
if(m_ptr[i]->m_time == 0)
{
m_ptr[i]->m_time = clock();
}
else if(clock() - m_ptr[i]->m_time > 5000)
{
m_ptr[i]->m_background = true;
m_ptr[i]->m_time &= 0;
}
}
}
else//true->true
{
m_ptr[i]->m_time &= 0;
}
if(wsum > T)
{
break;
}
}
for(i++; i<m_num; i++)
{
if(m_ptr[i]->m_background)//true->false
{
if(i != match)
{
if(m_ptr[i]->m_time == 0)
{
m_ptr[i]->m_time = clock();
}
else if(clock() - m_ptr[i]->m_time > 5000)
{
m_ptr[i]->m_background = false;
m_ptr[i]->m_time &= 0;
}
}
}
else//false->false
{
m_ptr[i]->m_time &= 0;
}
}
return !m_ptr[match]->m_background;
}
*/
return !m_ptr[1]->m_background;
}
void LGMM::Init_Process(float *value)
{
int i, match = -1;
float dist[4], minDist[4];
minDist[3] = 1000000.0;
for(i=0; i<m_num; i++)
{
// if(dist[3] < minDist[3] && m_ptr[i]->IsValid(value, dist))
if( m_ptr[i]->IsValid(value, dist) && dist[3] < minDist[3] )
{
memcpy(minDist,dist,4*sizeof(float));
match = i;
//break;
}
}
if(match == -1)//没有匹配
{
m_ptr[m_num-1]->Init(value, 1.0);
return;
}
else//有匹配
{
//更新模型参数
float sum = 0.0;//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for(i=0; i<m_num; i++) sum += m_ptr[i]->m_weight;//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sum = (float)(sum + 1.0);//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
m_ptr[match]->Init_Update(minDist, sum);
//模型按weight/variance排序
LGM *temp;
for(i=match; i>0; i--)
{
if(m_ptr[i]->m_weight > m_ptr[i-1]->m_weight)
{
temp = m_ptr[i];
m_ptr[i] = m_ptr[i-1];
m_ptr[i-1] = temp;
}
else
{
break;//其它顺序肯定不变,可跳出
}
}
}
}
void LGMM::Norm(void)
{
int i, j;
float sum = 0.0;
for(i=0; i<m_num; i++)
{
sum += m_ptr[i]->m_weight;
}
for(i=0; i<m_num; i++)
{
m_ptr[i]->m_weight = m_ptr[i]->m_weight / sum;
for(j=0;j<m_ptr[i]->m_size;j++)
m_ptr[i]->m_variance[j] = (float)((m_ptr[i]->m_variance[j] < 2.0 ? 2.0 : m_ptr[i]->m_variance[j]));
}
//确定新的背景模型
float wsum=0.0;
for(i=0; i<m_num; i++)
{
wsum += m_ptr[i]->m_weight;
m_ptr[i]->m_background = true;
if(wsum >= LT)
{
break;
}
}
for(i++; i<m_num; i++)
{
m_ptr[i]->m_background = false;
}
}
CCameraVideo::CCameraVideo(CvCapture* pCapture,CString pathname)
{
ASSERT(pCapture!=NULL);
m_bg_Image = NULL;
curImage=NULL; //初试化图像指针
hsvcurImage=NULL;
m_videocapture=NULL;
bgModel=NULL; //初试化GMM指针
bgModel_S=NULL;
if(pathname!="")
{
m_videocapture=pCapture;
}
else
{
m_camcapture=pCapture;
}
int i=GetLastError();
}
CCameraVideo::~CCameraVideo()
{
if(curImage)cvReleaseImage(&curImage);
if(hsvcurImage)cvReleaseImage(&hsvcurImage);
cvDestroyAllWindows();
if(bgModel) delete[] bgModel;
if(bgModel_S) delete[] bgModel_S;
}
void CCameraVideo::process()
{
GetParameters();
learnBgModel_video();
//learnBgModel_S_video();
// cvDestroyAllWindows();
//07.10 learnBgModel_S_video();
fast_segment_runGmmCut_video();
}
BOOL CCameraVideo::GetParameters()//此函数要重写
//读取对话框里的参数,赋给P0~P6
{
CDlgParameters dlg;
dlg.DoModal();
P0=dlg.P0;
P1=dlg.P1;
P2=dlg.P2;
P3=dlg.P3;
P4=dlg.P4;
P5=dlg.P5;
P6=dlg.P6;
P_RateMIN=dlg.P_RateMIN;
P_RateMAX=dlg.P_RateMAX;
P_eval_S=dlg.P_eval_S;
return true;
}
void CCameraVideo::learnBgModel_S_video()
{
int i, j, k, c;
float value[3],valuebg[3];
uchar* BYTEvalue_hsv;
long i1, ideta;//i2, ideta2;
float isum=0;//isum2=0;
CString numb;
IplImage *cur_frame=NULL, *cur_Image=NULL,*hsvcur_frame;
cur_frame = cvQueryFrame( m_videocapture );
if( !cur_frame )
{
AfxMessageBox("从文件抓图像出错!");
cvReleaseImage(&cur_frame);
return;
}
m_imageWidth = cur_frame->width;
m_imageHeight = cur_frame->height;
cvNamedWindow("cur_Image", CV_WINDOW_AUTOSIZE);
cvShowImage("cur_Image", cur_frame);
cvWaitKey(1);
// IplImage *initbgImage,*hsvinitbgImage; //初始化的背景图像RGB数据
m_bg_Image_S=NULL;
m_bg_Image_S = cvLoadImage(directoryname+"\\bg.bmp");
if (!m_bg_Image_S)
{
AfxMessageBox("请先学习背景模型!");
cvReleaseImage(&cur_frame);
return;
}
hsvcurImage= cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCvtColor( m_bg_Image_S, hsvcurImage, CV_BGR2HSV );
cvConvertImage( hsvcurImage, m_bg_Image_S, CV_CVTIMG_FLIP); //临时用m_bg_Image_S翻转图像显示
cvReleaseImage(&hsvcurImage);
bgModel = new LGMM[m_imageWidth*m_imageHeight];
bgModel_S = new LGMM[m_imageWidth*m_imageHeight];
hsvcur_frame= cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCvtColor( cur_frame, hsvcur_frame, CV_BGR2HSV );
for(i=0; i<m_imageWidth; i++) //初始化GMM模型
for(j=0; j<m_imageHeight; j++)
{
// BYTEvalue_hsv=cvGetpixelHSV(hsvcur_frame,i,j);
BYTEvalue_hsv=&((uchar*)(hsvcur_frame->imageData + hsvcur_frame->widthStep*j))[i*3];
// 3sizeof_uchar=3*sizeof(uchar);
// memcpy(value,BYTEvalue_hsv,3sizeof_uchar);
value[0]=float(BYTEvalue_hsv[0]<<1);
value[1]=float(BYTEvalue_hsv[1]);
value[2]=float(BYTEvalue_hsv[2]);
bgModel[i * m_imageHeight + j].Init(4, 3, value);
// BYTEvalue_hsv=cvGetpixelHSV(m_bg_Image_S,i,j);
// value[0]=float(BYTEvalue_hsv[0]*2);
// value[1]=float(BYTEvalue_hsv[1]);
// value[2]=float(BYTEvalue_hsv[2]);
memset(value,1 , sizeof(float)*3);
bgModel_S[i * m_imageHeight + j].Init(3, 3, value);
}
// int eval=80;
// CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;
i1=GetTickCount();
for(k=1;;k++) //学习GMM模型
{
cur_frame=NULL;
cur_frame = cvQueryFrame( m_videocapture );
//抓出的BGR图像是倒置的,cvShowImage时自动翻转,但训练时的HSV图像一直是倒置的
if( !cur_frame )break;
cvShowImage("cur_Image", cur_frame);
cvCvtColor( cur_frame, hsvcur_frame, CV_BGR2HSV );
c=cvWaitKey(1);
for(i=0; i<m_imageWidth; i++)
for(j=0; j<m_imageHeight; j++)
{
// BYTEvalue_hsv=cvGetpixelHSV(hsvcur_frame,i,j);
BYTEvalue_hsv=&((uchar*)(hsvcur_frame->imageData + hsvcur_frame->widthStep*j))[i*3];
value[0]=float(BYTEvalue_hsv[0]<<1);
value[1]=float(BYTEvalue_hsv[1]);
value[2]=float(BYTEvalue_hsv[2]);
// BYTEvalue_hsv=cvGetpixelHSV(m_bg_Image_S,i,j);
BYTEvalue_hsv=&((uchar*)(m_bg_Image_S->imageData + m_bg_Image_S->widthStep*j))[i*3];
valuebg[0]=float(BYTEvalue_hsv[0]<<1);
valuebg[1]=float(BYTEvalue_hsv[1]);
valuebg[2]=float(BYTEvalue_hsv[2]);
bgModel[i * m_imageHeight + j].Init_Process(value);
// eval = Habs(rc,rb)*rhmin(gc,gb)/255+fabs(gc-gb)+fabs(bc-bb);
if ((value[2]/valuebg[2]<P_RateMAX)&&(value[2]/valuebg[2]>P_RateMIN)&&(P_eval_S>(Habs(value[0],valuebg[0])*rhmin(value[1],valuebg[1])/255+fabs(value[1]-valuebg[1])+fabs(value[2]-valuebg[2]))))
{
bgModel_S[i * m_imageHeight + j].Init_Process(value);
}
/************************************************************************/
/************************************************************************/
}
numb.Format("%d",k);
// pMain->m_wndStatusBar.SetPaneText(0,numb,true);
if( c == 27 ) //按下Esc键
{
while (1)
{
c=cvWaitKey(10);
if (c == 97)break; //按下a键
}
}
}
ideta=GetTickCount()-i1;
isum=(float)(ideta/(k-1));
numb.Format("%7.0fms,k=%7.0d,%d,%d,%d,%d,%d,%d",isum,k-1,P1,P2,P3,P4,P5,P6);
// pMain->m_wndStatusBar.SetPaneText(0,numb,true);
cvDestroyWindow( "cur_Image" );
/************************************************************************/
//显示并保存背景模型图像
IplImage *hsvcur_frame1;
IplImage *hsvcur_frame2;
IplImage *bgImage;
IplImage *bgImage1;
IplImage *bgImage2;
float value1[3];
float value2[3];
hsvcur_frame1 = cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
hsvcur_frame2 = cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCopy(hsvcur_frame,hsvcur_frame2,NULL);
cvCopy(hsvcur_frame,hsvcur_frame1,NULL);
cvReleaseImage(&hsvcur_frame);
long count = 0;
for(j=0; j<m_imageHeight; j++) //显示并保存背景模型图像
{
for(i=0; i<m_imageWidth; i++)
{
bgModel[i * m_imageHeight + j].Norm();
bgModel_S[i * m_imageHeight + j].Norm();
LGMM *temp = bgModel_S + i * m_imageHeight + j;
// GMM *temp = bgModel + i * m_imageHeight + j;
memcpy(value, temp->m_ptr[0]->m_mean, sizeof(float)*3);
memcpy(value1, temp->m_ptr[1]->m_mean, sizeof(float)*3);
memcpy(value2, temp->m_ptr[2]->m_mean, sizeof(float)*3);
// cvSetPixelHSV(hsvcur_frame,i,j,int(value[0]),int(value[1]),int(value[2]));
cvSetPixelHSV(m_bg_Image_S,i,j,int(value[0]),int(value[1]),int(value[2]));
cvSetPixelHSV(hsvcur_frame1,i,j,int(value1[0]),int(value1[1]),int(value1[2]));
cvSetPixelHSV(hsvcur_frame2,i,j,int(value2[0]),int(value2[1]),int(value2[2]));
if(temp->m_ptr[0]->m_weight>0.9999) count++;
}
}
numb.Format(numb+",weight numb=%ld",count);
// pMain->m_wndStatusBar.SetPaneText(0,numb,true);
bgImage = cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCvtColor( m_bg_Image_S, bgImage, CV_HSV2BGR );
cvConvertImage( bgImage, m_bg_Image_S, CV_CVTIMG_FLIP); //临时用hsvcur_frame翻转图像显示
cvSaveImage( directoryname+"\\bg_S.bmp", m_bg_Image_S);
cvNamedWindow("bg_Image", CV_WINDOW_AUTOSIZE);
cvShowImage("bg_Image", m_bg_Image_S);
cvWaitKey(1);
cvReleaseImage(&m_bg_Image_S);
cvReleaseImage(&bgImage);
bgImage1 = cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCvtColor( hsvcur_frame1, bgImage1, CV_HSV2BGR );
cvConvertImage( bgImage1, hsvcur_frame1, CV_CVTIMG_FLIP);
cvSaveImage( directoryname+"\\bg1_S.bmp", hsvcur_frame1);
cvNamedWindow("bg_Image1", CV_WINDOW_AUTOSIZE);
cvShowImage("bg_Image1", hsvcur_frame1);
cvWaitKey(1);
cvReleaseImage(&hsvcur_frame1);
cvReleaseImage(&bgImage1);
bgImage2 = cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCvtColor( hsvcur_frame2, bgImage2, CV_HSV2BGR );
cvConvertImage( bgImage2, hsvcur_frame2, CV_CVTIMG_FLIP);
cvSaveImage( directoryname+"\\bg2_S.bmp", hsvcur_frame2);
cvNamedWindow("bg_Image2", CV_WINDOW_AUTOSIZE);
cvShowImage("bg_Image2", hsvcur_frame2);
cvWaitKey(1);
cvReleaseImage(&hsvcur_frame2);
cvReleaseImage(&bgImage2);
// cvDestroyAllWindows();
}
void CCameraVideo::learnBgModel_video()
{
int i, j, k, c;
float value[3];// valuebg[3];
uchar* BYTEvalue_hsv;
long i1,ideta;//i2,ideta2;
float isum=0;//isum2=0;
CString numb;
IplImage *cur_frame=NULL, *cur_Image=NULL,*hsvcur_frame;
cur_frame = cvQueryFrame( m_videocapture );
if( !cur_frame )
{
AfxMessageBox("从文件抓图像出错!");
cvReleaseImage(&cur_frame);
return;
}
m_imageWidth = cur_frame->width;
m_imageHeight = cur_frame->height;
cvNamedWindow("cur_Image", CV_WINDOW_AUTOSIZE);
cvShowImage("cur_Image", cur_frame);
cvWaitKey(1);
bgModel = new LGMM[m_imageWidth*m_imageHeight];
hsvcur_frame= cvCreateImage(cvSize(m_imageWidth, m_imageHeight), IPL_DEPTH_8U, 3 );
cvCvtColor( cur_frame, hsvcur_frame, CV_BGR2HSV );
for(i=0; i<m_imageWidth; i++) //初始化GMM模型
for(j=0; j<m_imageHeight; j++)
{
// BYTEvalue_hsv=cvGetpixelHSV(hsvcur_frame,i,j);
BYTEvalue_hsv=&((uchar*)(hsvcur_frame->imageData + hsvcur_frame->widthStep*j))[i*3];
value[0]=float(BYTEvalue_hsv[0]<<1);
value[1]=float(BYTEvalue_hsv[1]);
value[2]=float(BYTEvalue_hsv[2]);
bgModel[i * m_imageHeight + j].Init(4, 3, value);
}
// CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;
i1=GetTickCount();
for(k=1;;k++) //学习GMM模型
{
cur_frame=NULL;
cur_frame = cvQueryFrame( m_videocapture );
//抓出的BGR图像是倒置的,cvShowImage时自动翻转,但训练时的HSV图像一直是倒置的
if( !cur_frame )break;
cvShowImage("cur_Image", cur_frame);
cvCvtColor( cur_frame, hsvcur_frame, CV_BGR2HSV );
c=cvWaitKey(1);
for(i=0; i<m_imageWidth; i++)
for(j=0; j<m_imageHeight; j++)
{
// BYTEvalue_hsv=cvGetpixelHSV(hsvcur_frame,i,j);
BYTEvalue_hsv=&((uchar*)(hsvcur_frame->imageData + hsvcur_frame->widthStep*j))[i*3];
value[0]=float(BYTEvalue_hsv[0]<<1);
value[1]=float(BYTEvalue_hsv[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -