⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 walkwhitedlg.cpp

📁 机器人视觉处理程序
💻 CPP
字号:
// WalkWhiteDlg.cpp : implementation file
//

#include "stdafx.h"

#include "IRExpPlatform.h"
#include "IRExpPlatformDlg.h"
#include "WalkWhiteDlg.h"
#include "VideoConfigureDlg.h"
#include "global.h"
#include "ThresholdSet.h"
#include "ParameterSet.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWalkWhiteDlg dialog


CWalkWhiteDlg::CWalkWhiteDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CWalkWhiteDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CWalkWhiteDlg)
	m_strCarState = _T("");
	//}}AFX_DATA_INIT
}


void CWalkWhiteDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CWalkWhiteDlg)
	DDX_Text(pDX, IDC_EDITSTATECAR, m_strCarState);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CWalkWhiteDlg, CDialog)
	//{{AFX_MSG_MAP(CWalkWhiteDlg)
	ON_BN_CLICKED(IDC_STARTSAMPLE, OnStartsample)
	ON_BN_CLICKED(IDC_ENDSAMPLE, OnEndsample)
	ON_BN_CLICKED(IDC_RUNORSTOPCAR, OnRunorstopcar)
	ON_BN_CLICKED(IDC_SEGMENT, OnSegment)
	ON_BN_CLICKED(IDC_CLOSEINWALKWHITEDLG, OnCloseinwalkwhitedlg)
//	ON_BN_CLICKED(IDC_BACKINWALKWHITEDLG, OnBackinwalkwhitedlg)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CONFIGINWALKWHITEDLG, OnConfiginwalkwhitedlg)
	ON_WM_PAINT()
	ON_BN_CLICKED(IDC_COLORVIDEOOPEN, OnColorvideoopen)
	ON_BN_CLICKED(IDC_COLORVIDEOCLOSE, OnColorvideoclose)
	ON_BN_CLICKED(IDC_THRESHOLDSETINWALKWHITEDLG, OnThresholdsetinwalkwhitedlg)
	ON_BN_CLICKED(IDC_PARAMETERSET, OnParameterset)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWalkWhiteDlg message handlers

BOOL CWalkWhiteDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	
	//////////////////////////////////////////////////////////
	//初始化各变量值
	theApp.bColor          = TRUE;
	theApp.bSegment        = FALSE;
	theApp.nCntObject      = 0;
	theApp.nCntLinePts     = 0;
	theApp.xCoordinate     = 0;
	theApp.yCoordinate     = 0;
	theApp.nDirection      = FRONT;
	theApp.nMotiontype     = STOP;
	theApp.nLastMotiontype = STOP;
	theApp.bMove           = FALSE;
	theApp.bFirstFilter    = TRUE;

	//初始化机器人运动状态
	theApp.strCarState= "停止";       
	m_strCarState=theApp.strCarState;

	//更新上述值至各控件窗口
	UpdateData(FALSE);
	
	//初始化对应控件的使能状态
	GetDlgItem(IDC_COLORVIDEOOPEN) -> EnableWindow(TRUE);
	GetDlgItem(IDC_COLORVIDEOCLOSE) -> EnableWindow(FALSE);
	GetDlgItem(IDC_SEGMENT) -> EnableWindow(FALSE);
	GetDlgItem(IDC_RUNORSTOPCAR) -> EnableWindow(FALSE);
	GetDlgItem(IDC_ENDSAMPLE) -> EnableWindow(FALSE);
	GetDlgItem(IDC_STARTSAMPLE) -> EnableWindow(FALSE);		
	//GetDlgItem(IDC_BACKINWALKWHITEDLG) -> EnableWindow(TRUE);
	//GetDlgItem(IDC_HELPINWALKWHITEDLG) -> EnableWindow(TRUE);
	GetDlgItem(IDC_CLOSEINWALKWHITEDLG) -> EnableWindow(TRUE);
	GetDlgItem(IDC_CONFIGINWALKWHITEDLG) -> EnableWindow(FALSE);
	GetDlgItem(IDC_THRESHOLDSETINWALKWHITEDLG) -> EnableWindow(FALSE);
	GetDlgItem(IDC_PARAMETERSET) -> EnableWindow(FALSE);

	//GetDlgItem(IDC_HELPINWALKWHITEDLG) -> EnableWindow(FALSE);
	
	for(int i=0; i<WIDTH*HEIGHT*3; i++)
		theApp.tempColor[i]= 255;			//初始化存放颜色RGB值的数组
		
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

//按下"开始采集"按钮执行的处理函数
void CWalkWhiteDlg::OnStartsample() 
{
	// TODO: Add your control notification handler code here
	
	m_nTimer=SetTimer(1, 11, NULL); //启动定时器,每间隔11ms图像采集一次,运动模块执行一次
	
	GetDlgItem(IDC_SEGMENT) -> EnableWindow(TRUE);
	GetDlgItem(IDC_ENDSAMPLE) -> EnableWindow(TRUE);	
}

//按下"结束采集"按钮执行的处理函数
void CWalkWhiteDlg::OnEndsample()
{
	// TODO: Add your control notification handler code here
	KillTimer(m_nTimer);              //关闭定时器

	GetDlgItem(IDC_SEGMENT) -> EnableWindow(FALSE);
	GetDlgItem(IDC_RUNORSTOPCAR) -> EnableWindow(FALSE);	
	GetDlgItem(IDC_ENDSAMPLE) -> EnableWindow(FALSE);

	theApp.bSegment = FALSE;
	theApp.bMove = FALSE;
	StopCar();                       //停止机器人	
}


//按下"启停机器人"按钮执行的处理函数
void CWalkWhiteDlg::OnRunorstopcar() 
{
	// TODO: Add your control notification handler code here
	theApp.bMove =! theApp.bMove;   //改变机器人的运动状态,启动->停止或停止->启动
}

//按下"阈值分割"按钮执行的处理函数
void CWalkWhiteDlg::OnSegment() 
{
	// TODO: Add your control notification handler code here
	if(theApp.bSegment == FALSE)
	{		
		theApp.bSegment = TRUE;
		GetDlgItem(IDC_RUNORSTOPCAR) -> EnableWindow(TRUE);
	}
/*
	else
	{
		theApp.bSegment = FALSE;	
		theApp.bMove = FALSE;
		GetDlgItem(IDC_RUNORSTOPCAR) -> EnableWindow(FALSE);
	}
*/	
}

//按下"关闭"按钮执行的处理函数
void CWalkWhiteDlg::OnCloseinwalkwhitedlg() 
{
	// TODO: Add your control notification handler code here

		KillTimer(m_nTimer);                        //关闭定时器
		StopCar();	                                //停止机器人
		capDriverDisconnect(m_hCaptureInWhiteDlg ); //断开视频连接
		CDialog::OnCancel();                        //关闭对话框
		
}
/*
//按下"返回"按钮执行的处理函数
void CWalkWhiteDlg::OnBackinwalkwhitedlg() 
{
	// TODO: Add your control notification handler code here
	KillTimer(m_nTimer);                         //关闭定时器
	StopCar();	                                 //停止机器人
	capDriverDisconnect(m_hCaptureInWhiteDlg );  //断开视频连接                                   

	CDialog::OnCancel();                         //关闭对话框  
	
//    AfxGetMainWnd()->ShowWindow(SW_SHOW);      //显示主对话框

}
*/
//定时器执行函数
void CWalkWhiteDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
	theApp.bFirstFilter = TRUE;     // 第一次中值滤波
	MedianFilter();                 // 滤波处理函数

	if (theApp.bSegment==TRUE)      //已经对图像进行滤波处理
	{
		ColorSegment();             //阈值分割

		
		theApp.bFirstFilter = FALSE; //第二次中值滤波
		MedianFilter();              //对阈值分割后的图像再一次进行中值滤波

		DecisionSearchLine();        //跟踪白线处理函数

		
		if(theApp.bMove == TRUE)     //允许启动机器人
		{
			Motion();                //启动机器人
			m_strCarState=theApp.strCarState;			
			UpdateData(FALSE);		//更新机器人运动状态至控件窗口
		}
		else
			if (theApp.bMove==FALSE)         //不允许启动机器人
			{
			StopCar();                 //停止机器人
			m_strCarState=theApp.strCarState;			
			UpdateData(FALSE);		//更新机器人运动状态至控件窗口
			}
	}

	DisplayFrames();                 //显示阈值分割后的图像    

	
	CDialog::OnTimer(nIDEvent);
}


//显示阈值分割后的图像
void CWalkWhiteDlg::DisplayFrames()
{
	CWnd* pVideoAfterDeal;                  //图像阈值分割处理后显示对应的Picture控件指针
	CDC* pDC;                               //内存设备环境CDC指针
	CDC dcMemory;                           //内存设备环境CDC对象
	CBitmap  *pOldBmp;
	CBitmap newBmp;			//公用位图对象

	pVideoAfterDeal = GetDlgItem(IDC_VIDEOAFTERDEALWALKWHITEDLG);//取得图像阈值分割处理后显示对应的Picture控件指针
	pDC = pVideoAfterDeal -> GetDC();
	newBmp.CreateCompatibleBitmap(pDC, WIDTH, HEIGHT); //创建与内存设备环境相兼容的位图
	
	dcMemory.CreateCompatibleDC(pDC);                         //创建与内存设备环境相兼容的环境           
    pOldBmp = dcMemory.SelectObject(&newBmp);          //将位图选入内存设备环境,并保存原始位图
	
	BYTE r, g, b;
	for(int i=0;i<HEIGHT;i++)                                 //行
		for(int j=0;j<WIDTH;j++)                              //列
		{			
			r=theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 2];  //取得r分量
			g=theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 1];  //取得g分量
			b=theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 0];  //取得b分量
			dcMemory.SetPixel(j,i,RGB(r,g,b));                         //画坐标为(j,i)的象素点
		}

	pDC->BitBlt(0, 0, WIDTH, HEIGHT, &dcMemory, 0, 0, SRCCOPY);   //将内存设备环境复制到真正的设备环境中
	UpdateWindow( );

	dcMemory.SelectObject(pOldBmp);                              //选择原来的位图对象
	newBmp.DeleteObject();                                //删除位图

	ReleaseDC(&dcMemory);                                        //释放内存设备环境
	ReleaseDC(pDC);	
	

}

//按下"视频配置"按钮执行的处理函数
void CWalkWhiteDlg::OnConfiginwalkwhitedlg() 
{
	// TODO: Add your control notification handler code here
	CVideoConfigureDlg VideoConfigureDlg;
	VideoConfigureDlg.DoModal();                                 //打开视频配置模态对话框
	
}

void CWalkWhiteDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	DisplayFrames();
	// Do not call CDialog::OnPaint() for painting messages
}


//按下"彩色视频开"按钮执行的处理函数
void CWalkWhiteDlg::OnColorvideoopen() 
{
	// TODO: Add your control notification handler code here
	m_hCaptureInWhiteDlg=IniVideo(this->m_hWnd);            //初始化视频
	if (capDriverConnect(m_hCaptureInWhiteDlg, 0))          //如果与0号视频采集卡连接成功
	{
	//以下五行改变各控件的使能状态
	GetDlgItem(IDC_COLORVIDEOCLOSE) -> EnableWindow(TRUE);
	GetDlgItem(IDC_COLORVIDEOOPEN) -> EnableWindow(FALSE);
	GetDlgItem(IDC_STARTSAMPLE) -> EnableWindow(TRUE);
	GetDlgItem(IDC_ENDSAMPLE) -> EnableWindow(FALSE); 
	GetDlgItem(IDC_CONFIGINWALKWHITEDLG) -> EnableWindow(TRUE);
	GetDlgItem(IDC_THRESHOLDSETINWALKWHITEDLG) -> EnableWindow(TRUE);
	GetDlgItem(IDC_PARAMETERSET) -> EnableWindow(TRUE);	
	}
	theApp.bColor=TRUE;	                                    //TRUE,彩色视频显示标志

	
}

//按下"彩色视频关"按钮执行的处理函数
void CWalkWhiteDlg::OnColorvideoclose() 
{
	// TODO: Add your control notification handler code here
	capDriverDisconnect(m_hCaptureInWhiteDlg);            //断开视频连接
	KillTimer(m_nTimer);                                  //关闭定时器	
	
	//以下十行改变各控件的使能状态
	GetDlgItem(IDC_COLORVIDEOOPEN) -> EnableWindow(TRUE);
	GetDlgItem(IDC_COLORVIDEOCLOSE) -> EnableWindow(FALSE);
	GetDlgItem(IDC_SEGMENT) -> EnableWindow(FALSE);
	GetDlgItem(IDC_RUNORSTOPCAR) -> EnableWindow(FALSE);
	GetDlgItem(IDC_ENDSAMPLE) -> EnableWindow(FALSE);
	GetDlgItem(IDC_STARTSAMPLE) -> EnableWindow(FALSE);
	GetDlgItem(IDC_CONFIGINWALKWHITEDLG) -> EnableWindow(FALSE);
	//GetDlgItem(IDC_BACKINWALKWHITEDLG) -> EnableWindow(TRUE);
	//GetDlgItem(IDC_HELPINWALKWHITEDLG) -> EnableWindow(TRUE);
	GetDlgItem(IDC_CLOSEINWALKWHITEDLG) -> EnableWindow(TRUE);
	GetDlgItem(IDC_THRESHOLDSETINWALKWHITEDLG) -> EnableWindow(FALSE);
	GetDlgItem(IDC_PARAMETERSET) -> EnableWindow(FALSE);	


	for(int i=0; i<WIDTH*HEIGHT*3; i++)
		theApp.tempColor[i]= 255;			//初始化
	DisplayFrames();	
	
}

//初始化视频
HWND CWalkWhiteDlg::IniVideo(HWND m_hwn)
{
	HWND m_hTempCapture;
	
	CWnd *pWndBeforDeal=GetDlgItem(IDC_VIDEOBEFORDEALWALKWHITEDLG); //取得原始图像显示对应的Picture控件指针
	CRect videoRect;
	CRect windowRect;
	long xoffset;
	long yoffset;
	int  hTitle;
	
	//让视频窗口正好覆盖原始图像显示对应的Picture控件
	//GetWindowRect()求取的坐标是相对于显示器左上角而言的
	pWndBeforDeal->GetWindowRect(&videoRect);       //取得原始图像显示对应的Picture控件矩形   
	GetWindowRect(&windowRect);                     //取得真个对话框矩形
	xoffset=videoRect.TopLeft().x -windowRect.TopLeft().x;
	yoffset=videoRect.TopLeft().y -windowRect.TopLeft().y;

	hTitle =::GetSystemMetrics(SM_CYSIZE); 	       //求取标题栏高度

	m_hTempCapture = capCreateCaptureWindow ("CapWindow", WS_EX_CONTROLPARENT
			| WS_CHILD | WS_VISIBLE, xoffset-2, yoffset-hTitle-3, videoRect.Width(), videoRect.Height(), this->m_hWnd, 0);  //-2,-3是为了微调窗口左上角坐标,因为视频窗口显示时可能存在2-3各象素的误差
    ASSERT(m_hTempCapture );
	CAPDRIVERCAPS capDrvCaps;                     // CAPDRIVERCAPS结构体定义了驱动器的性能                   

	//判断采集窗口是否与0号捕获卡驱动程序相连接,
	//这里采用简化的方法,因只有一块捕获卡,计算机自动登记号码通常是为0  
	if (capDriverConnect(m_hTempCapture , 0))
	{
		//作默认值初始化,并得到驱动器的性能,存入CAPDRIVERCAPS结构中
		capDriverGetCaps(m_hTempCapture , &capDrvCaps, sizeof(CAPDRIVERCAPS)); 

		//如果初始化成功
		if (capDrvCaps.fCaptureInitialized) 
		{	
			//设置预视帧频
			capPreviewRate(m_hTempCapture , 2 * 1000 / RATE); 

			//设置成预视模式(preview),该方式是通过内存作
			//为缓冲区来存放视频数据,它是获得视频数据的必要条件.
			//另一种称为Overlay模式,它是不经过内存而直接将
			//数据传入显存中。它不符合我们要求.
			capPreview(m_hTempCapture , TRUE);

			//设置每帧结束后所调用的回调函数(默认为彩色视频)
			capSetCallbackOnFrame(m_hTempCapture , FrameCallbackProc); 

		}

		//如果初始化不成功
		else{
			//初始化不成功的消息框显示
			AfxMessageBox("捕获卡初始化失败"); 
			//发送WM_CLOSE消息,关闭对话框
			AfxGetMainWnd()->PostMessage(WM_CLOSE);
			
		}
	}
	//连接不成功
	else{
		//连接不成功的消息框显示
		AfxMessageBox("捕获卡连接失败"); 
		//发送WM_CLOSE消息,关闭对话框
	 	//AfxGetMainWnd()->PostMessage(WM_CLOSE); 
		this->PostMessage(WM_CLOSE);
	} 

	
	return m_hTempCapture;

}

void CWalkWhiteDlg::OnThresholdsetinwalkwhitedlg() 
{
	// TODO: Add your control notification handler code here
	CThresholdSet thresholdSetDlgInWalkWhite;
	thresholdSetDlgInWalkWhite.DoModal();
	
}

void CWalkWhiteDlg::OnParameterset() 
{
	// TODO: Add your control notification handler code here
	CParameterSet dlgParmSet;
	dlgParmSet.DoModal();
	
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -