TrackandIDDlg.cpp
上传用户:wfkeli
上传日期:2014-02-03
资源大小:3091k
文件大小:14k
- // TrackandIDDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include <string>
- #include "TrackandID.h"
- #include "TrackandIDDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- using namespace std;
- /////////////////////////////////////////////////////////////////////////////
- // CAboutDlg dialog used for App About
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
- // Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected:
- //{{AFX_MSG(CAboutDlg)
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- // No message handlers
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTrackandIDDlg dialog
- CTrackandIDDlg::CTrackandIDDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CTrackandIDDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CTrackandIDDlg)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
- void CTrackandIDDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CTrackandIDDlg)
- // NOTE: the ClassWizard will add DDX and DDV calls here
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CTrackandIDDlg, CDialog)
- //{{AFX_MSG_MAP(CTrackandIDDlg)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_StartTrackandID, OnStartTrackandID)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTrackandIDDlg message handlers
- BOOL CTrackandIDDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
-
- // TODO: Add extra initialization here
-
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CTrackandIDDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
- void CTrackandIDDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
- // The system calls this to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CTrackandIDDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
- /////////////////////////////////////////////////////////////////////////////////////
- //打开视频文件以及车辆跟踪和识别
- void CTrackandIDDlg::OnStartTrackandID()
- {
- // TODO: Add your control notification handler code here
- int argc=2;
- ////打开文件///////////////////////////////////////////////////
- CString FilePathName;
- CFileDialog dlg(TRUE);
- if(dlg.DoModal()==IDOK)
- FilePathName=dlg.GetPathName();
- IplImage* pFrame = NULL;
- IplImage* pFrImg = NULL;
- IplImage* pBkImg = NULL;
- IplImage* pFrImg1 = NULL;
- CvMat* pFrameMat = NULL;
- CvMat* pFrMat = NULL;
- CvMat* pBkMat = NULL;
- CvMat* pFrMat1 = NULL;
- CvMemStorage * storage = cvCreateMemStorage(0);//轮廓边缘提取时的参数
- CvSeq * contour = 0;//轮廓边缘提取时的参数
- int mode = CV_RETR_EXTERNAL;//轮廓边缘提取时的参数
- //形态学处理时内核的大小
- IplConvKernel* Element = cvCreateStructuringElementEx(13,13,1,1,CV_SHAPE_RECT,NULL);
- CvFont font1;//初始化字体格式
- int linetype=CV_AA;
- cvInitFont(&font1, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, 8);
- //用字符串时一定要把using namespace std;写在前面,否则不能用,下面是用于显示的字符串
- string msg[10]={"JGD01","JGD02","JGD03","JGD04","JGD05","JGD06","JGD07","JGD08","JGD09","JGD10"};
- int No=0;//用于记录显示车辆
- bool FindCar=false;
-
- //在视频中画出感兴趣的区域,怎么样才能沿车道画线???????
- CvPoint pt1,pt2,pt3,pt4,pt5;
- pt1.x=292;//(视频中左下点)
- pt1.y=100;
- pt2.x=412;//(视频中右上点)
- pt2.y=280;
- CvRect bndRect=cvRect(0,0,0,0);//用cvBoundingRect画出外接矩形时需要的矩形
- int avgX = 0;//The midpoint X position of the rectangle surrounding the moving objects
- int avgY = 0;//The midpoint Y position of the rectangle surrounding the moving objects
- int avgX1=0;//用来合并相近的车辆
- int avgY1=0;
- for(int i=0;i<10;i++)
- {
- TrackBlock[i]=NULL;
- if((TrackBlock[i]=(struct AvTrackBlock *) malloc(sizeof(struct AvTrackBlock)))==NULL)
- {
- MessageBox("内存分配错误");
- exit(1);
- }
- }////////////////////
- CvCapture* pCapture = NULL;
- int nFrmNum = 0;//表示图像的帧数
- //创建窗口
- cvNamedWindow("video", 1);
- //cvNamedWindow("background",1);
- cvNamedWindow("foreground",1);
- //使窗口有序排列
- cvMoveWindow("video", 30, 0);
- //cvMoveWindow("background", 360, 0);
- cvMoveWindow("foreground", 690, 0);
- if( argc > 2 ){
- fprintf(stderr, "Usage: bkgrd [video_file_name]n");
- //return -1;
- }
- ////打开摄像头///////////////////////////////////////////////////
- if (argc ==1)
- if( !(pCapture = cvCaptureFromCAM(-1))){
- fprintf(stderr, "Can not open camera.n");
- //return -2;
- }
- ///打开视频文件//////////////////////////////////////////////////
- if(argc == 2)
- if( !(pCapture = cvCaptureFromFile(FilePathName))){
- fprintf(stderr, "Can not open video file %sn", FilePathName);
- //return -2;
- }
-
- //逐帧读取视频,cvQueryFrame从摄像头或者文件中抓取并返回一帧
- while(pFrame = cvQueryFrame(pCapture))
- {
- nFrmNum++;
- //如果是第一帧,需要申请内存,并初始化
- if(nFrmNum == 1)
- {
- pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
- pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
- pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
- pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
- pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
- cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
- cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
- cvConvert(pFrImg, pFrameMat);
- cvConvert(pFrImg, pFrMat);
- cvConvert(pFrImg, pBkMat);
- }
- else if(nFrmNum == 3)
- {
- cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
- cvConvert(pFrImg, pFrameMat);
- //高斯滤波先,以平滑图像
- cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
- //在视频中设置并画出感兴趣的区域
- cvRectangle(pFrame,pt1,pt2,CV_RGB(255,0,0),2, 8, 0 );
- //当前帧跟背景图相减,cvAbsDiff计算两个数组差的绝对值
- cvAbsDiff(pFrameMat, pBkMat, pFrMat);
- //二值化前景图
- cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
-
- //通过查找边界找出ROI矩形区域内的运动车辆,建立完全目标档案
- //cvCanny(pFrImg, pBkImg, 50, 150, 3);
- cvDilate(pFrImg,pBkImg,Element,1);
- cvFindContours(pBkImg, storage, &contour, sizeof(CvContour),
- mode, CV_CHAIN_APPROX_SIMPLE);
- //process each moving contour in the current frame用函数cvBoundingRect
- for(;contour!=0;contour=contour->h_next)
- {
- //Get a bounding rectangle around the moving object.
- bndRect = cvBoundingRect(contour, 0);
-
- //Get an average X position of the moving contour.
- avgX = (bndRect.x + bndRect.x + bndRect.width) / 2;
- avgY = (bndRect.y + bndRect.y + bndRect.height) / 2;
- pt5.x = bndRect.x;//写字的左下角点
- pt5.y = avgY;
- //If the center of contour is within ROI than show it
- if(avgX>300 && avgX<400 && avgY<300 && avgY>80)
- {
- pt3.x = bndRect.x;
- pt3.y = bndRect.y;
- pt4.x = bndRect.x + bndRect.width;
- pt4.y = bndRect.y + bndRect.height;
- if(bndRect.height>35) //把长度小于某个阀值的干扰矩形去掉
- {
- cvRectangle(pFrame,pt3,pt4,CV_RGB(255,0,0),1, 8, 0 );
- //在车辆的中心写编号
- cvPutText( pFrame, msg[No].c_str(), pt5, &font1, cvScalar(0,255,0));
- //把当前车辆存入跟踪数组
- TrackBlock[No]->Direction=1;
- TrackBlock[No]->FramesTracked=nFrmNum;
- TrackBlock[No]->avgX=avgX;
- TrackBlock[No]->avgY=avgY;
- No++;
- }
- }
- }/////查找边界的for 循环结束
-
- //更新背景///////////////////////////////////////////////////
- cvRunningAvg(pFrameMat, pBkMat, 0.005, 0);
- //将背景转化为图像格式,用以显示
- cvConvert(pBkMat, pBkImg);
- //显示图像////////////////////////////////////////////////////
- cvShowImage("video", pFrame);
- //cvShowImage("background", pBkImg);
- //cvShowImage("foreground", pFrImg);
- //如果有按键事件,则跳出循环,此等待也为cvShowImage函数提供时间完成显示,等待时间可以根据CPU速度调整
- if( cvWaitKey(2) >= 0 )
- break;
- }
- else if(nFrmNum > 3)//从第三帧开始,根据完全目标档案来新增或删除运动车辆档案。
- {
- cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
- cvConvert(pFrImg, pFrameMat);
- //高斯滤波先,以平滑图像
- cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
- //在视频中设置并画出感兴趣的区域
- //cvSetImageROI(pFrame,rect1);
- cvRectangle(pFrame,pt1,pt2,CV_RGB(255,0,0),2, 8, 0 );
- //当前帧跟背景图相减,cvAbsDiff计算两个数组差的绝对值
- cvAbsDiff(pFrameMat, pBkMat, pFrMat);
- //二值化前景图,void cvThreshold( const CvArr* src, CvArr* dst, double threshold,
- //double max_value, int threshold_type );
- cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
- //通过查找边界找出ROI矩形区域内的运动车辆,建立完全目标档案
- //cvCanny(pFrImg, pBkImg, 50, 150, 3);
- cvDilate(pFrImg,pBkImg,Element,1);
- cvFindContours( pBkImg, storage, &contour, sizeof(CvContour),
- mode, CV_CHAIN_APPROX_SIMPLE);
- //process each moving contour in the current frame用函数cvBoundingRect
- for(;contour!=0;contour=contour->h_next)
- {
- //Get a bounding rectangle around the moving object.
- bndRect = cvBoundingRect(contour, 0);
-
- //Get an average X position of the moving contour.
- avgX = (bndRect.x + bndRect.x + bndRect.width) / 2;
- avgY = (bndRect.y + bndRect.y + bndRect.height) / 2;
- pt5.x=bndRect.x;//写字的左下角点
- pt5.y=avgY;
- //If the center of contour is within ROI than show it
- if(avgX > 300 && avgX < 400 && avgY < 280 && avgY > 100)
- {
- pt3.x = bndRect.x;
- pt3.y = bndRect.y;
- pt4.x = bndRect.x + bndRect.width;
- pt4.y = bndRect.y + bndRect.height;
- if(bndRect.height>35) //把长度小于某个阀值的干扰矩形去掉
- {
- cvRectangle(pFrame,pt3,pt4,CV_RGB(255,0,0),1, 8, 0 );
- //cvPutText(pFrame,msg[No].c_str(), pt5, &font1, cvScalar(0,255,0));
- //在跟踪数组中寻找看是否有匹配的车辆,没有则表示是新车辆
- for(int i=0;i<10;i++)
- {
- if(TrackBlock[i]->avgX !=0 && abs(avgX-TrackBlock[i]->avgX)<20 &&
- abs(avgY-TrackBlock[i]->avgY)<50)
- {
- cvPutText(pFrame,msg[i].c_str(), pt5, &font1, cvScalar(0,255,0));
- TrackBlock[i]->FramesTracked=nFrmNum;
- TrackBlock[i]->avgX=avgX;
- TrackBlock[i]->avgY=avgY;
- i=10;//使跳出for循环
- FindCar=true;
- }
- }
- if(FindCar!=true && avgY<120)//表示没有找到车辆
- {
- TrackBlock[No]->Direction=1;
- TrackBlock[No]->FramesTracked=nFrmNum;
- TrackBlock[No]->avgX=avgX;
- TrackBlock[No]->avgY=avgY;
- if(No==9){
- No=0;
- }
- else
- No++;
- }
- FindCar=false;//赋值为false为下一次寻找车辆做准备
- }
- }
- }//轮廓分for循环结束
- //对于没有匹配的车辆,表示已经出了边界,清空数组
- for(int j=0;j<10;j++)
- {
- if(TrackBlock[j]->FramesTracked != nFrmNum)
- {
- //虽然置为零,但是可能零和当前中心的值在设定的范围内,所以不行。
- //TrackBlock[j]=NULL;为何用NULL不行。
- TrackBlock[j]->Direction=0;
- TrackBlock[j]->FramesTracked=0;
- TrackBlock[j]->avgX=0;
- TrackBlock[j]->avgY=0;
- }
- }
- //更新背景///////////////////////////////////////////////////
- cvRunningAvg(pFrameMat, pBkMat, 0.005, 0);
- //将背景转化为图像格式,用以显示
- cvConvert(pBkMat, pBkImg);
- //显示图像////////////////////////////////////////////////////
- cvShowImage("video", pFrame);
- cvShowImage("background", pBkImg);
- cvShowImage("foreground", pFrImg);
- /*if(nFrmNum/2 ==0)
- pBkMat=pFrameMat;*/
- //如果有按键事件,则跳出循环,此等待也为cvShowImage函数提供时间完成显示,等待时间可以根据CPU速度调整
- if( cvWaitKey(2) >= 0 )
- break;
- }//
- }//while循环结束
- cvReleaseStructuringElement(&Element);//删除结构元素
- //销毁窗口
- cvDestroyWindow("video");
- cvDestroyWindow("background");
- cvDestroyWindow("foreground");
- //释放图像和矩阵
- cvReleaseImage(&pFrImg);
- cvReleaseImage(&pBkImg);
- cvReleaseMat(&pFrameMat);
- cvReleaseMat(&pFrMat);
- cvReleaseMat(&pBkMat);
- }