1.系统打开视频序列界面:
2.人工划定感兴趣的区域(ROI):
3.模式选择(白天和黑夜):
4.跟踪界面:
5.流量统计界面:
3系统的软件构架
总系统构架:
开始
视频采灰度化、平确定ROI 白天检测模式 车流量统
4.系统主要模块功能以及代码
白天车流量统计:
void CCarTrackSystemDlg::Nightupdate_mhi( IplImage* img, IplImage* dst, int diff_threshold ) {
?/////////////////////////////////////////////////////////////////////////////////////////////////////
?////////////////////////////////////// 夜间开始 ////////////////////////////////////////////////
double timestamp = clock()/1000.;
CvSize size = cvSize(img->width,img->height); int i, idx1 = last, idx2; IplImage* silh; CvSeq* seq; CvRect comp_rect; double count; double angle; CvPoint center;
double magnitude; CvScalar color;
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 );
cvReleaseImage( & orient );
cvReleaseImage( & segmask );
cvReleaseImage( & mask );
mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 ); cvZero( mhi );
orient = cvCreateImage( size, IPL_DEPTH_32F, 1 ); segmask = cvCreateImage( size, IPL_DEPTH_32F, 1 ); mask = cvCreateImage( size, IPL_DEPTH_8U, 1 ); }
cvCvtColor( img, buf[last], CV_BGR2GRAY ); // “灰度”
idx2 = (last + 1) % N; last = idx2;
silh = buf[idx2];
cvAbsDiff( buf[idx1], buf[idx2], silh );
cvThreshold( silh, silh, diff_threshold, 1, CV_THRESH_BINARY );
cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ); // 更新 MHI
cvCvtScale( mhi, mask, 255./MHI_DURATION,
(MHI_DURATION - timestamp)*255./MHI_DURATION );
cvZero( dst );
cvCvtPlaneToPix(mask, 0, 0, 0, dst );
cvCalcMotionGradient( mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3 );
if( !storage )
storage = cvCreateMemStorage(0); else
cvClearMemStorage(storage);
// 运动分割
seq = cvSegmentMotion( mhi, segmask, storage, timestamp, MAX_TIME_DELTA );
for( i = 0; i < seq->total; i++ ) {
if( i < 0 ) { // 对整幅图像操作
comp_rect = cvRect( 0, 0, size.width, size.height ); color = CV_RGB(255,255,255);
magnitude = 100; // 画线长度以及圆半径的大小控制 }
else {
comp_rect = ((CvConnectedComp*)cvGetSeqElem( seq, i ))->rect;
// 去掉小的部分
if( comp_rect.width + comp_rect.height < 100 ) continue;
color = CV_RGB(255,0,0); // red色
magnitude = 30;
///////if(seq->total > 0) MessageBox(NULL,\tected\ULL,0); }
// 感性区域
cvSetImageROI( silh, comp_rect ); cvSetImageROI( mhi, comp_rect );
cvSetImageROI( orient, comp_rect ); cvSetImageROI( mask, comp_rect );
angle = cvCalcGlobalOrientation( orient, mask, mhi, timestamp,
MHI_DURATION);
angle = 360.0 - angle;
// 在轮廓内计算点数
count = cvNorm( silh, 0, CV_L1, 0 );
cvResetImageROI( mhi ); cvResetImageROI( orient ); cvResetImageROI( mask ); cvResetImageROI( silh );
if( count < comp_rect.width*comp_rect.height * 0.05 )