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

📄 cbgseg.cpp

📁 用高斯和离子滤波来跟踪视频图像中的移动对象
💻 CPP
字号:
#include <stdio.h>
#include "CBGSeg.h"

void CBGSeg::Initialize()
{
	capture = NULL;
	tmp_frame = NULL;
	Start_Fr=0;
	End_Fr=0;
	malloc_flag=0;

	buf=0;
	last=0;
	Fr=0;
	mhi = 0;
	filter = CV_GAUSSIAN_5x5;
}

void CBGSeg::BGSegment(char* VideoPath,int Start_Frame, int End_Frame, const int Format, int Parameter)
{
	Start_Fr = Start_Frame;
	End_Fr   = End_Frame;

	//capture video from file
	capture = cvCaptureFromFile(VideoPath);
	cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, Start_Fr);
	tmp_frame = cvQueryFrame(capture);
	if(!tmp_frame)return;

	if (malloc_flag==0)
	{
		foreground = (IplImage**)malloc((End_Fr-Start_Fr+1)*sizeof(IplImage*));
		memset( foreground, 0, (End_Fr-Start_Fr+1)*sizeof(foreground[0]));
		
		for(int i = 0; i <= End_Fr-Start_Fr; i++ ) 
		{
			foreground[i] = cvCreateImage( cvSize(tmp_frame->width,tmp_frame->height), tmp_frame->depth, tmp_frame->nChannels );
			cvZero( foreground[i] );
		}
		malloc_flag=1;
	}

	switch(Format)
	{
	case GAUSSIAN:
		Gaussian_Tracking();break;
	case PARTICLE:
		Partical_Tracking(Parameter);break;
	default:
		break;
	}
}

void CBGSeg::Gaussian_Tracking()
{
	int i,j;
	CvBGStatModel* bg_model;
	//create windows to show background and foreground images
	cvNamedWindow("Background", 1);
	cvNamedWindow("Foreground Mask", 1);

	//for all frames in the video
	for(Fr = Start_Fr; Fr<=End_Fr; tmp_frame = cvQueryFrame(capture),Fr++ ) 
	{
		//update BG model
		if (Fr==Start_Fr)
		{
			//create BG model
			bg_model = cvCreateGaussianBGModel( tmp_frame );
		}
		bg_model->update( tmp_frame, bg_model );
		bg_model->foreground->origin = bg_model->background->origin = 1;
		for (i=0;i<bg_model->foreground->height;i++)
			for (j=0;j<bg_model->foreground->width;j++)
			{
				if ((bg_model->foreground->imageData+i*bg_model->foreground->width)[j]==0)
				{
					(tmp_frame->imageData+i*3*tmp_frame->width)[3*j]=0;
					(tmp_frame->imageData+i*3*tmp_frame->width)[3*j+1]=0;
					(tmp_frame->imageData+i*3*tmp_frame->width)[3*j+2]=0;
				}
			}
		cvCopy( tmp_frame,foreground[Fr-Start_Fr],  NULL);
		foreground[Fr-Start_Fr]->origin=1;	
		cvShowImage("Background", bg_model->background);
		cvShowImage("Foreground Mask", foreground[Fr-Start_Fr]);
		int k = cvWaitKey(50);
		if( k == 27 ) break;
	}

	//release BG model
	bg_model->release( &bg_model );

	//release capture
	cvDestroyWindow("Background");
	cvDestroyWindow("Foreground Mask");
}

void CBGSeg::Partical_Tracking(int diff_threshold)
{
	IplImage* motion = 0; 
	cvNamedWindow( "Foreground", 1 );
	cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, Start_Fr);
	for(Fr=Start_Fr;Fr<=End_Fr;Fr++)
	{
		if( !cvGrabFrame( capture ))
			break;
		tmp_frame = cvRetrieveFrame( capture );
		if( tmp_frame )
		{
			if( !motion )
			{
				motion = cvCreateImage( cvSize(tmp_frame->width,tmp_frame->height), 8, 1 );
				cvZero( motion );
				motion->origin = tmp_frame->origin;
			}
		}
		update_mhi( tmp_frame, motion,diff_threshold);
		cvCopy( tmp_frame,foreground[Fr-Start_Fr],  NULL);
		foreground[Fr-Start_Fr]->origin=1;
		cvShowImage( "Foreground", foreground[Fr-Start_Fr]);
		if( cvWaitKey(50) >= 0 )break;
	}
}

void CBGSeg::update_mhi(IplImage *img, IplImage *dst, int diff_threshold)
{
	double timestamp = clock()/100.; // get current time in seconds
    CvSize size = cvSize(img->width,img->height); // get current frame size
    int i,j, idx1, idx2;
    IplImage* silh;
    IplImage* pyr = cvCreateImage( cvSize((size.width & -2)/2, (size.height & -2)/2), 8, 1 );

	CvMemStorage *stor;
    CvSeq *cont;//*result;
	int min_x,min_y,max_x,max_y;
	//	int pre_min_x,pre_min_y,pre_max_x,pre_max_y;
	int counter=0;

    if( !mhi || mhi->width != size.width || mhi->height != size.height ) 
    {
        if( buf == 0 ) 
        {
            buf = (IplImage**)malloc(N*sizeof(buf[0]));
            memset( buf, 0, N*sizeof(buf[0]));
        }    
        for( i = 0; i < N; i++ ) 
        {
            cvReleaseImage( &buf[i] );
            buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
            cvZero( buf[i] );
        }
        cvReleaseImage( &mhi );
        mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 );
        cvZero( mhi ); // clear MHI at the beginning
    } // end of if(mhi)
    cvCvtColor( img, buf[last], CV_BGR2GRAY ); // convert frame to grayscale
    idx1 = last;
    idx2 = (last + 1) % N; // index of (last - (N-1))th frame 
    last = idx2;
    // 做帧差
    silh = buf[idx2];
    cvAbsDiff( buf[idx1], buf[idx2], silh ); // get difference between frames
	silh->origin=1;	
    // 对差图像做二值化
    cvThreshold( silh, silh, 30, 255, CV_THRESH_BINARY ); // and threshold it
    cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ); // update MHI
    cvCvtScale( mhi, dst, 255./MHI_DURATION, (MHI_DURATION - timestamp)*255./MHI_DURATION );    
    cvCvtScale( mhi, dst, 255./MHI_DURATION, 0 );      
    // 中值滤波,消除小的噪声
    cvSmooth( dst, dst, CV_MEDIAN, 3, 0, 0, 0 );   
    // 向下采样,去掉噪声
    cvPyrDown( dst, pyr, 7 );
    cvDilate( pyr, pyr, 0, 1 );  // 做膨胀操作,消除目标的不连续空洞
    cvPyrUp( pyr, dst, 7 );
/*	for (i=0;i<dst->height;i++)
		for (j=0;j<dst->width;j++)
		{
			if ((dst->imageData+i*dst->width)[j]==0)
			{
				(img->imageData+i*3*img->width)[3*j]=0;
				(img->imageData+i*3*img->width)[3*j+1]=0;
				(img->imageData+i*3*img->width)[3*j+2]=0;
			}
		}*/
///新加入
	stor = cvCreateMemStorage(0);
	cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
		
	// 找到所有轮廓
	cvFindContours( dst, stor, &cont, sizeof(CvContour), 
			CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
	// 直接使用CONTOUR中的矩形来画轮廓
		
	if (!cont)
	{
		return;
	}
	int cen_r_x;
	int cen_r_y;
	int cout_cnt=0;
	for(;cont;cont = cont->h_next)
	{	
		CvRect r = ((CvContour*)cont)->rect;
		cen_r_x=r.x+0.5*r.width;
		cen_r_y=r.y+0.5*r.height;
		if(cont->total > 64)
		{
			counter++;
			cout_cnt++;
			if (counter==1)
			{
				min_x=r.x;
				min_y=r.y;
				max_x=r.x+r.width;
				max_y=r.y+r.height;
			}
			else
			{
				if (r.x<min_x&&r.y<min_y)
				{
					min_x=r.x;
					min_y=r.y;
				}
				if (r.x+r.width>max_x&&r.y+ r.height>max_y)
				{
					max_x=r.x + r.width;
					max_y=r.y + r.height;
						
				}
			}
		}
    }	
	cvRectangle( img, cvPoint(min_x,min_y), 
		cvPoint(max_x , max_y),
                          CV_RGB(255,0,0), 1, CV_AA,0);
	cvReleaseImage( &pyr );
}

void main()
{
	CBGSeg BGSeg;
	BGSeg.BGSegment("E:\\tracking\\1.avi",0, 170, PARTICLE, 20);
}

⌨️ 快捷键说明

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