www.pudn.com > chunlincheck_second1.rar > chunlincheck_secondDlg.cpp


// chunlincheck_secondDlg.cpp : 实现文件 
// 
 
#include "stdafx.h" 
#include "chunlincheck_second.h" 
#include "chunlincheck_secondDlg.h" 
#include ".\chunlincheck_seconddlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 
 
 
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框 
 
class CAboutDlg : public CDialog 
{ 
public: 
	CAboutDlg(); 
 
// 对话框数据 
	enum { IDD = IDD_ABOUTBOX }; 
 
	protected: 
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持 
 
// 实现 
protected: 
	DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
} 
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
} 
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
END_MESSAGE_MAP() 
 
 
// Cchunlincheck_secondDlg 对话框 
 
 
 
Cchunlincheck_secondDlg::Cchunlincheck_secondDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(Cchunlincheck_secondDlg::IDD, pParent) 
	 
	, m_picture_num(0) 
	, m_carnum(0) 
	, m_coordinate(_T("")) 
{ 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
	////////////////////////////////////////////////////////// 
	m_pLMouseDown=FALSE;   ////////////////////////////////开始时鼠标未按下  
	m_HCursor=AfxGetApp()->LoadStandardCursor(IDC_CROSS); ///定义十字形光标 
    Drawing=0;             ////////////////////////////判断是否处于画圈状态 
	Begin=0;               //////开始未处于画线或检测状态,若是则显示坐标值  
	/////////////////////////////////////////////////////////////////////// 
	L0=10;L1=25;X=2;Y=5;x1=17;x2=314;y1=170;T=35; /////////默认状态下的参数 
} 
 
void Cchunlincheck_secondDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	DDX_Text(pDX, IDC_EDIT1, m_picture_num); 
	DDX_Text(pDX, IDC_EDIT2, m_carnum); 
	DDX_Text(pDX, IDC_EDIT3, m_coordinate); 
} 
 
BEGIN_MESSAGE_MAP(Cchunlincheck_secondDlg, CDialog) 
	ON_WM_SYSCOMMAND() 
	ON_WM_PAINT() 
	ON_WM_QUERYDRAGICON() 
	//}}AFX_MSG_MAP 
	ON_BN_CLICKED(IDC_OPEN_FIRST, OnBnClickedOpenFirst) 
	ON_BN_CLICKED(IDOK, OnBnClickedOk) 
	ON_BN_CLICKED(IDC_PAUSE, OnBnClickedPause) 
	ON_WM_TIMER() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_MOUSEMOVE() 
	ON_BN_CLICKED(IDC_OPEN_BGR, OnBnClickedOpenBgr) 
END_MESSAGE_MAP() 
 
 
// Cchunlincheck_secondDlg 消息处理程序 
 
BOOL Cchunlincheck_secondDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	// 将\“关于...\”菜单项添加到系统菜单中。 
 
	// IDM_ABOUTBOX 必须在系统命令范围内。 
	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); 
		} 
	} 
 
	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 
	//  执行此操作 
	SetIcon(m_hIcon, TRUE);			// 设置大图标 
	SetIcon(m_hIcon, FALSE);		// 设置小图标 
 
	// TODO: 在此添加额外的初始化代码 
	 
	return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE 
} 
 
void Cchunlincheck_secondDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
	if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
	{ 
		CAboutDlg dlgAbout; 
		dlgAbout.DoModal(); 
	} 
	else 
	{ 
		CDialog::OnSysCommand(nID, lParam); 
	} 
} 
 
// 如果向对话框添加最小化按钮,则需要下面的代码 
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, 
//  这将由框架自动完成。 
 
void Cchunlincheck_secondDlg::OnPaint()  
{ 
	if (IsIconic()) 
	{ 
		CPaintDC dc(this); // 用于绘制的设备上下文 
 
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); 
 
		// 使图标在工作矩形中居中 
		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; 
 
		// 绘制图标 
		dc.DrawIcon(x, y, m_hIcon); 
	} 
	else 
	{ 
		CDialog::OnPaint(); 
	} 
 
	////////////////////////////////////////////////////////////// 
		CClientDC dc(this);                            //显示背景图片和首张图片; 
		CRect rect(CPoint(0,0),CPoint(340,240)); 
		if(!firstimg.IsNull())firstimg.BitBlt(dc,rect,CPoint(0,0)); 
		if(!bgrimg.IsNull()&&Begin==0)bgrimg.BitBlt(dc,rect,CPoint(0,0)); 
    ////////////////////////////////////////////////////////////// 
		if(Drawing==1) 
		{ 
		CPen Pen;                                      //画线过程显示直线; 
		CPen *OldPen; 
		Pen.CreatePen(PS_SOLID,1,RGB(255,255,255)); 
		OldPen=dc.SelectObject(&Pen); 
		POINT points[2]; 
		points[0].x=m_Newpoint.x; 
		points[0].y=m_Newpoint.y; 
		points[1].x=m_Oldpoint.x; 
		points[1].y=m_Newpoint.y; 
		dc.Polyline(points,2); 
		dc.SelectObject(OldPen);  
		} 
    ////////////////////////////////////////////////////////////// 
 
} 
 
//当用户拖动最小化窗口时系统调用此函数取得光标显示。 
HCURSOR Cchunlincheck_secondDlg::OnQueryDragIcon() 
{ 
	return static_cast(m_hIcon); 
} 
 
void Cchunlincheck_secondDlg::OnBnClickedOpenBgr() 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	LPCTSTR lpszFilter="jpg Files(*.jpg)|*.jpg|bmp Files(*.bmp)|*.bmp||"; 
	CFileDialog dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY| 
	OFN_OVERWRITEPROMPT,lpszFilter,NULL); 
 
	//打开文件对话框 
	if(dlg1.DoModal()==IDOK) 
	{ 
		//取文件路径,扩展名 
		bgrimgfile=dlg1.GetPathName(); 
		bgrimg.Destroy(); 
		bgrimg.Load(bgrimgfile);                    //读取背景图片 
		Drawing=0; 	                
        Begin=0; 
        Invalidate(); 
		UpdateWindow(); 
	} 
} 
 
 
void Cchunlincheck_secondDlg::OnBnClickedOpenFirst() 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	LPCTSTR lpszFilter="jpg Files(*.jpg)|*.jpg|bmp Files(*.bmp)|*.bmp||"; 
	CFileDialog dlg2(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY| 
	OFN_OVERWRITEPROMPT,lpszFilter,NULL); 
 
	//打开文件对话框 
	if(dlg2.DoModal()==IDOK) 
	{ 
		//取文件路径,扩展名 
		filename=dlg2.GetFileName(); 
		filepath=dlg2.GetPathName(); 
		int leng_of_filename=filename.GetLength(); 
		filefolder=filepath; 
		filefolder.Delete(filepath.GetLength()-leng_of_filename,leng_of_filename); 
		fileext=dlg2.GetFileExt(); 
		filetitle=dlg2.GetFileTitle(); 
		filetitlenum=atoi(filetitle); 
		//读取显示图片 
		bgrimg.Destroy(); 
		firstimg.Destroy(); 
		firstimg.Load(filepath);   //读取第一张图片; 
		Drawing=1;                 //打开第一张后画线; 
		Begin=1;                   //打开第一张图片后仍显示鼠标坐标值;  		           
        Invalidate(); 
		UpdateWindow(); 
	    } 
} 
 
void Cchunlincheck_secondDlg::OnBnClickedOk() 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	jishu=0; 
	pause=1; 
	N=x2-x1+1; 
	chun=new int[N+2];chun2=new int[N+2];chunlin=new int[N+2];  //定义三个动态数组,其中chun为 
	m_carnum=0;                      //当前数据流,chun2为前一帧数据流,chunlin为chun与chun2的差;                                               
	Drawing=0;                                  //检测开始后取消画线状态; 
	Begin=1;                                    //检测开始后仍显示鼠标坐标值; 
    for(int k=0;k<=N+1;k++)chun2[k]=0;                                     
	 
	/////////////////////////////////////////////////////////////////////// 
	/////////////////////////////////////////////////////////////////////// 
	myfile01.Open("C:\\01.txt",CFile::modeCreate|CFile::modeWrite); //创建4个文件 
	myfile02.Open("C:\\02.txt",CFile::modeCreate|CFile::modeWrite); //用于输出数据流 
	myfile03.Open("C:\\03.txt",CFile::modeCreate|CFile::modeWrite); 
	myfile04.Open("C:\\04.txt",CFile::modeCreate|CFile::modeWrite); 
	/////////////////////////////////////////////////////////////////////// 
    /////////////////////////////////////////////////////////////////////// 
	bgrimg.Load(bgrimgfile); 
	firstimg.Destroy(); 
	                                                           	 
	SetTimer(1,100,NULL);                                       //启动定时器   
} 
 
void Cchunlincheck_secondDlg::OnTimer(UINT nIDEvent) 
{ 
    if(jishu<=3000) 
	{	 
		 
        ////////////////////////////////////////////////////////////////////////////////// 
        //读取显示序列图片 
		filename.Format("%s%d.%s",filefolder,3*jishu+filetitlenum,fileext);  //如果每张图片读取 
		img.Destroy();                                                       //则运行较慢,每次 
		img.Load(filename);                                              //隔一张或两张读取图片 
		 
        /////////////////////////////////////////////////////////////////////////////////// 
		COLORREF c1,c2;       //本程序段为膨胀操作:线条上的一点,如果其邻域(大小由X,Y决定) 
		int r,g,b;            //有任一点显示有车存在(即超过一定阀值),则该点用'1'表示,否则 
		                      //为'0'。线条上所有点采取如此操作,则产生一数组,长度由线条上象 
	  	for(int x=x1,i=1;x<=x2;x++,i++)            //素个数决定。 
		{    
		   	 
			for(int cx=-X;cx<=X;cx++)               
			{     
				chun[i]=0; 
				for(int cy=-Y;cy<=Y;cy++) 
				{ 
				 c1=bgrimg.GetPixel(x+cx,y1+cy); 
			     c2=img.GetPixel(x+cx,y1+cy); 
			     r=GetRValue(c2)-GetRValue(c1); 
			     g=GetGValue(c2)-GetGValue(c1); 
			     b=GetBValue(c2)-GetBValue(c1); 
			     
				 if(abs(r)>T||abs(g)>T||abs(b)>T){chun[i]=1;}				 
				} 
			}		  
		} 
		//////////////////////////////////////////////////////////////////////////////// 
		for(int x=x1;x<=x2;x++)img.SetPixelRGB(x,y1,255,255,255);  //显示图片,为直观,在 
        CClientDC dc(this);                                        //图片上画线条 
		CRect rect(CPoint(0,0),CPoint(340,260)); 
		img.BitBlt(dc,rect,CPoint(0,0));       
///////////////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////////////// 
myfile01.Seek((N+10)*jishu,CFile::begin);                           //输出数据流1 
for(int i0=1;i0<=N;i0++) 
{ 
	ch01.Format("%d",chun[i0]); 
	myfile01.Write(ch01,1); 
} 
ch01.Format("/%d/",jishu); 
myfile01.Write(ch01,sizeof(ch01)+2);    
////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////////// 
        chun[0]=chun[N+1]=1; 
		int k1;int k2; 
		for(int i1=0;i1<=N;i1++)        //去除毛刺的零,长度小于等于L0(默认情况等于10), 
		{                                //但在两端为L0的一半; 
			if(chun[i1]==1&&chun[i1+1]==0){k1=i1;} 
			if(chun[i1]==0&&chun[i1+1]==1) 
			{ 
				k2=i1; 
				if((k1==0)||(k2==N)) 
				{ 
					if((k2-k1)<=L0/2){for(int i3=k1+1;i3<=k2;i3++)chun[i3]=1;} 
				} 
				else if((k2-k1)<=L0) 
				{ 
					for(int i2=k1+1;i2<=k2;i2++)chun[i2]=1; 
				} 
			} 
		}	 
//////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////// 
myfile02.Seek((N+10)*jishu,CFile::begin);                           //输出数据流2 
for(int i0=1;i0<=N;i0++) 
{ 
	ch02.Format("%d",chun[i0]); 
	myfile02.Write(ch02,1); 
} 
ch02.Format("/%d/",jishu); 
myfile02.Write(ch02,sizeof(ch02)+2); 
///////////////////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////////////////// 
        chun[0]=chun[N+1]=0;               //选择大于选定长度L1的'1',把较短的‘1’置零, 
		int j1,j2;                         //默认情况L1等于25 
        for(int i2=0;i2<=N;i2++)        
		{    
			 
			if(chun[i2]==0&&chun[i2+1]==1){j1=i2;}    
			if(chun[i2]==1&&chun[i2+1]==0) 
			{ 
				j2=i2; 
				if((j2-j1)=L1) 
				{ 
                m_carnum++;   
				} 
			} 
				  
		}		 
//////////////////////////////////////////////////////////////////////////// 
		//转入另一轮循环 
		for(int i6=0;i6<=N+1;i6++){chun2[i6]=chun[i6];}               
		 
		jishu++; 
        m_picture_num=jishu;                       
		UpdateData(FALSE);                              //显示文本框中的数据 
	}  
 
	else 
	{  
		CWnd::KillTimer(nIDEvent); 
		img.Destroy(); 
		delete chun,chun2,chunlin;                       //动态数组删除 
		AfxMessageBox("Finish checking",MB_ICONINFORMATION|MB_OKCANCEL); 
	} 
	 
} 
 
void Cchunlincheck_secondDlg::OnBnClickedPause() 
{ 
	// TODO: 在此添加控件通知处理程序代码 
    if(pause%2==1)KillTimer(1);            
    else{SetTimer(1,200,NULL);} 
    pause++;  
} 
/////////////////////////////////////////////////////////  鼠标操作 
void Cchunlincheck_secondDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{ 
	// TODO: 在此添加消息处理程序代码和/或调用默认值 
   if(Drawing==1) 
   {m_Oldpoint=point; 
	m_Newpoint=point; 
	SetCapture(); 
	m_pLMouseDown=TRUE; 
	CRect rect(0,0,320,240);	 
	ClientToScreen(&rect); 
	ClipCursor(&rect); 
   } 
	CDialog::OnLButtonDown(nFlags, point); 
} 
 
void Cchunlincheck_secondDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{ 
	// TODO: 在此添加消息处理程序代码和/或调用默认值 
    if(m_pLMouseDown&&Drawing==1) 
	{ 
		m_pLMouseDown=FALSE; 
		ReleaseCapture(); 
		ClipCursor(NULL); 
 
		Invalidate(); 
		UpdateWindow(); 
		 
		CParameter para; 
        if(para.DoModal()==IDOK) 
		{ 
		X=para.m_X;  Y=para.m_Y; L0=para.m_L0; L1=para.m_L1;  T=para.m_T;//接收参数 
        if(m_Newpoint.x<=(X+1))x1=X+1;else x1=m_Newpoint.x;    //防止直线膨胀后超出图片范围 
		if((m_Oldpoint.x+X)>=319)x2=319-X;else x2=m_Oldpoint.x; 
		if(m_Newpoint.y+Y>=239)y1=239-Y;else y1=m_Newpoint.y; 
		}		 
	} 
	CDialog::OnLButtonUp(nFlags, point); 
} 
 
void Cchunlincheck_secondDlg::OnMouseMove(UINT nFlags, CPoint point) 
{ 
	// TODO: 在此添加消息处理程序代码和/或调用默认值 
	if(Drawing==1)   //如果处于画线,则对鼠标移动响应    
	{ 
	   SetCursor(m_HCursor); 
	   if(m_pLMouseDown) 
	    { 
		CClientDC dc(this); 
		dc.SetROP2(R2_NOT); 
		dc.MoveTo(m_Newpoint); 
        dc.LineTo(m_Oldpoint); 
		dc.MoveTo(m_Newpoint); 
		dc.LineTo(point); 
		m_Oldpoint=point; 
		}         
	} 
	/////////////////////////////////////////////////// 
	if(Begin==1)          //如果处于画线或检测状态,则显示鼠标坐标值 
	{  
		CClientDC dc(this); 
		m_coordinate.Format("(%d,%d)",point.x,point.y); 
		UpdateData(FALSE); 
	} 
	CDialog::OnMouseMove(nFlags, point); 
} 
//////////////////////////////////////////////////////////////////////////