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

📄 lgmm.cpp

📁 动态场景中运动目标检测提取与跟踪 对新手很有用
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			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 + -