2系统详细设计.doc
《2系统详细设计.doc》由会员分享,可在线阅读,更多相关《2系统详细设计.doc(14页珍藏版)》请在冰点文库上搜索。
![2系统详细设计.doc](https://file1.bingdoc.com/fileroot1/2023-7/9/2258b900-e9ed-4642-88b2-64aa8e3f8cfc/2258b900-e9ed-4642-88b2-64aa8e3f8cfc1.gif)
系统详细设计说明书
杨后超
2013.8.06
1.引言
1.1编写目的
本报告根据交通部门实时的对道路车流量的统计的要求,对系统如何实现功能如何划分做了概要性的说明。
通过该报告能够使详细设计人员和开发人员了解本系统的体系结构,技术方案,软件的功能能结构,各业务间的数据接口,数据库结构等,并对整个系统的功能实现按照功能模块进行了较为详细的规划和描述,为下一步的开发任务指明方向,提出了纲要。
1.2参考资料
【1】城市道路车流量检测技术及其应用研究_颜李
【2】基于视频的车流量检测技术研究_吴志伟
【3】运动车辆视频检测与车流量检测方法的研究_墨芹
2.设计概述
本系统采用结构化设计的方法来实现系统总体功能,提高系统的各项指标,即将整个系统合理的划分成各个功能模块,正确地处理模块之间和模块内部的联系以及和数据库的联系,定义各模块的内部结构,通过对模块的设计和模块之间关系的系统来实现整个系统的功能。
2.1限制和约束
开发过程中最为重要的里程碑如下表:
时间段
里程碑
9月
项目启动、需求分析
10月上半月
系统的概要设计、系统详细设计
10月到十二月
完成白天黑夜流量统计系统
1月上半月
完成各种噪声所带来的对检测、识别的影响。
1月下半月
测试、部署
在以上这些条件下,系统要实现的目标是:
目的是实现系统的总体设计,明确系统的总体结构和数据结构,即划分出系统的功能模块,设计出系统的数据库数据结构,为下一步的对每个模块进行设计的详细设计工作提供依据,同时为系统的测试、修改和维护提供依据。
2.2设计原则和设计要求
一.设计原则
(1).独立性
每个模块只涉及软件要求的具体子功能
(2).易维护性
基于MFC开发,采用统一的编码规则和注释,便于系统开发和维护
(3).可扩展性
考虑到用户需求的多变性,采用易于扩展的软件架构,便于软件升级
二.设计要求
l需求规定:
1.系统打开视频序列界面:
2.人工划定感兴趣的区域(ROI):
3.模式选择(白天和黑夜):
4.跟踪界面:
5.流量统计界面:
3系统的软件构架
开始
总系统构架:
视频采集
灰度化、平滑去噪等
确定ROI同时判断
白天检测模式夜间检测模式
车流量统计
4.系统主要模块功能以及代码
白天车流量统计:
voidCCarTrackSystemDlg:
:
Nightupdate_mhi(IplImage*img,IplImage*dst,intdiff_threshold)
{
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////夜间开始////////////////////////////////////////////////
doubletimestamp=clock()/1000.;
CvSizesize=cvSize(img->width,img->height);
inti,idx1=last,idx2;
IplImage*silh;
CvSeq*seq;
CvRectcomp_rect;
doublecount;
doubleangle;
CvPointcenter;
doublemagnitude;
CvScalarcolor;
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{
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;itotal;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,"MotionDetected",NULL,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(countcontinue;
center=cvPoint((comp_rect.x+comp_rect.width/2),
(comp_rect.y+comp_rect.height/2));
cvCircle(dst,center,cvRound(magnitude*1.2),color,3,CV_AA,0);
cvLine(dst,center,cvPoint(cvRound(center.x+
magnitude*cos(angle*CV_PI/180)),
cvRound(center.y-magnitude*sin(angle*CV_PI/180))),
color,3,CV_AA,0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////结束/////////////////////////
}:
夜间车流量统计:
voidCCarTrackSystemDlg:
:
update_mhi(IplImage*img,IplImage*dst,intdiff_threshold)
{
doubletimestamp=clock()/100.;//getcurrenttimeinseconds时间戳
CvSizesize=cvSize(img->width,img->height);
CvPointpt3,pt4;
CvRectbndRect=cvRect(0,0,0,0);//用cvBoundingRect画出外接矩形时需要的矩形
CvFontfont1;//初始化字体格式
intlinetype=CV_AA;
//getcurrentframesize,得到当前帧的尺寸
intidx1,idx2;
IplImage*silh;
IplImage*pyr=cvCreateImage(cvSize((size.width&-2)/2,(size.height&-2)/2),8,1);
CvMemStorage*stor;
CvSeq*cont;
/*先进行数据的初始化*/
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(inti=0;i{
cvReleaseImage(&buf[i]);
buf[i]=cvCreateImage(size,IPL_DEPTH_8U,1);
cvZero(buf[i]);//clearBufferFrameatthebeginning
}
cvReleaseImage(&mhi);
mhi=cvCreateImage(size,IPL_DEPTH_32F,1);
cvZero(mhi);//clearMHIatthebeginning
}//endofif(mhi)
/*将当前要处理的帧转化为灰度放到buffer的最后一帧中*/
cvCvtColor(img,buf[last],CV_BGR2GRAY);//convertframetograyscale
idx1=last;
idx2=(last+1)%N;//indexof(last-(N-1))thframe
last=idx2;
//做帧差
silh=buf[idx2];//差值的指向idx2|idx2-idx1|-->idx2(<-silh)
cvAbsDiff(buf[idx1],buf[idx2],silh);//getdifferencebetweenframes
//对差图像做二值化
cvThreshold(silh,silh,30,255,CV_THRESH_BINARY);//thresholdit,二值化
cvUpdateMotionHistory(silh,mhi,timestamp,MHI_DURATION);//updateMHI
cvConvert(mhi,dst);//将mhi转化为dst,dst=mhi
//中值滤波,消除小的噪声
cvSmooth(dst,dst,CV_MEDIAN,3,0,0,0);
cvPyrDown(dst,pyr,CV_GAUSSIAN_5x5);//向下采样,去掉噪声,图像是原图像的四分之一
cvDilate(pyr,pyr,0,1);//做膨胀操作,消除目标的不连续空洞
cvPyrUp(pyr,dst,CV_GAUSSIAN_5x5);//向上采样,恢复图像,图像是原图像的四倍
//
//下面的程序段用来找到轮廓
//
//Createdynamicstructureandsequence.
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中的矩形来画轮廓
for(;cont;cont=cont->h_next)
{
CvRectr=((CvContour*)cont)->rect;
if(r.height*r.width>1500)//面积小的方形抛弃掉
{
bndRect=cvBoundingRect(cont,0);
//GetanaverageXpositionofthemovingcontour.
avgX=(bndRect.x+bndRect.x+bndRect.width)/2;
avgY=(bndRect.y+bndRect.y+bndRect.height)/2;
if(avgX>(m_tangle1.x>m_tangle2.x?
m_tangle2.x:
m_tangle1.x)&&avgX<(m_tangle1.x>m_tangle2.x?
m_tangle1.x:
m_tangle2.x)
&&avgY<(m_tangle1.y>m_tangle2.y?
m_tangle1.y:
m_tangle2.y)&&avgY>(m_tangle1.y>m_tangle2.y?
m_tangle2.y:
m_tangle1.y)){
cvRectangle(img,cvPoint(r.x,r.y),
cvPoint(r.x+r.width,r.y+r.height),
CV_RGB(255,0,0),1,CV_AA,0);
pt3.x=bndRect.x;
pt3.y=bndRect.y;
pt4.x=bndRect.x+bndRect.width;
pt4.y=bndRect.y+bndRect.height;
cvInitFont(&font1,CV_FONT_HERSHEY_DUPLEX,0.5,0.5,0,2,8);
for(inti=0;i<30;i++)
{
if(TrackBlock[i]->avgX!
=0&&fabs((double)(avgX-TrackBlock[i]->avgX))<20&&fabs((double)(avgY-TrackBlock[i]->avgY))<50)
{
cvPutText(img,msg[i],cvPoint(pt3.x,pt4.y),&font1,cvScalar(255,255,255));
TrackBlock[i]->FramesTracked=nFrmNum;
TrackBlock[i]->avgX=avgX;
TrackBlock[i]->avgY=avgY;
//记录运动轨迹
TrackBlock[i]->guiji_index=TrackBlock[i]->guiji_index+1;
intindex_g=TrackBlock[i]->guiji_index;
TrackBlock[i]->guiji[index_g].x=avgX;
TrackBlock[i]->guiji[index_g].y=avgY;
for(intk=1;k {
cvLine(img,cvPoint(TrackBlock[i]->guiji[k].x,
TrackBlock[i]->guiji[k].y),
cvPoint(TrackBlock[i]->guiji[k+1].x,
TrackBlock[i]->guiji[k+1].y),CV_RGB(0,191,255),2,8,0);
}
//取轨迹中三点