📄 cbgseg.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 + -