[置顶] 第六章 KinectV2结合MFC显示和处理图像数据(上)
2016-09-01 16:42
507 查看
第六章 KinectV2结合MFC显示和处理图像数据(上)
首先声明一下,本系统所使用的开发环境版本是计算机系统Windows 10、Visual Studio 2013、Opencv3.0和Kinect SDK v2.0。这些都可以在百度上找到,download下来安装一下即可。详情参考本系列第二篇KinectV2结合opencv入门开发以及一些相关的学习资料
其实只要用前面几章的知识就差不多可以把基本功能实现了,只不过实在控制台下,没有一个好用的交互界面,不方便使用,更不能发挥Kinect的体感方面的优势。想到前面的基础程序是在C++基础上写的,故选了一个好入门的平台--MFC,说好入门不是说MFC简单,只是因为MFC比较成熟,学习资料较多,如果前面是在C#基础上写的,那肯定首选WPF了。MFC那么多内容,这里不便说清楚,我也说不清楚,只能大概说一下本系统的简单界面。一、用电脑的摄像头代替Kinect的程序
核心的代码如下:
VideoCapture capture; //定义一个摄像头类型的对象 capture.open(0); //打开摄像头 //AfxMessageBox("OK"); if (!capture.isOpened()) //判断是否打开摄像头 { MessageBox(_T("无法打开摄像头")); return; } //保存视频 writer = cvCreateVideoWriter("MyVideo.avi", CV_FOURCC('x', 'v', 'I', 'D'), 25, cvSize(640, 480)); // 测试 //IplImage* m_Frame; Mat cframe; //定义一个Mat类对象,用来存放摄像头的图像流 capture >> cframe; IplImage* iframe; iframe = &IplImage(cframe); //Mat转IplImage DrawPicToHDC(iframe, IDC_PIC_STATIC); //显示摄像头获取的图像 //cvWaitKey(10); // 设置计时器,每10ms触发一次事件 SetTimer(1, 10, NULL);
运行截图:
这是一个非简单的小demo,实现了普通相机的功能,就是录像和拍照啊之类的,基于MFC平台写的,非常简单,而且有详细注释,这里就不做过多的解释。这里给出整个过程的下载地址:
http://download.csdn.net/detail/baolinq/9618271
二、基于MFC平台的Kinect程序
有了上部分的基础,电脑摄像头和Kinect都是一种摄像头,只是Kinect相机更高端一点,是RGBD相机,很容易类比过去,把电脑摄像头换成kinect相机就差不多了。说起来是这么简单,一两句话的事,但这只是一种思想,如果真的用程序去实现还是有一定的难度。一起来看一下。
2.1 MFC 一个类访问另一个类成员对象的成员变量值
电脑摄像头比较简单,只有几句话就可以表达出来,可以直接写在MFC自动生成的类和方法里面,然后单击按钮触发事件。但是Kinect的初始化和启动以及获取图像的程序那么长,如果也放在那下面的话,会显得程序结构很乱,可读性很差。一般我们会自己创建类和自己的方法,然后在MFC自带的类和方法里面调用自己创建的类,这样可以一目了然,程序干净整洁,也更加便于维护。这里就会遇到MFC里面一个类访问另一个类成员对象的成员变量值 。
MFC中一个类要访问另外一个类的的对象的成员变量值,这就需要获得原来那个类对象的指针,其实有好几种方法都可以实现。
比如维护一个单例模式、设置静态变量等等。我们这里举个列子,实现多个类之间的相互访问。
(1)示例:创建MFC对话框,实现对个对话框之间数据访问
1. 我们创建一个MFC对话框应用程序,命名为Visit工程.2. 对话框本身有一个主界面(CVisitDlg对话框),那我们再添加一个新界面CXXXDlg.
(2)在主界面CVisitDlg类的头文件中,添加一个static CVisitDlg *s_pDialog;指针(注:添加为共有类型的)
由于这个指针式静态的,我们需要在类外初始化,那么我们在CVisitDlg .cpp文件中,写上一行初始化代码,直接初始化为空,如下:
CVisitDlg *CVisitDlg::s_pDialog = NULL; //(注意要写在类外,不要写在类实现函数里面)。
(3)然后需要在CVisitDlg 主对话框生成的时候,给这个指针赋值为主对话框指针。
那么,我们可以在CVisitDlg 类的构造函数或者OnInitDialog()函数里面写上如下一句代码:s_pDialog = this;
好了,现在我们只要在其他的类里面获得这个静态指针,就可以访问这个类里面的所有数据了~~~~
(4)获得静态指针
假设,我们想在CXXXDlg类中访问CVisitDlg类的数据,如下代码轻轻松松搞定:CVisitDlg *pDia = CVisitDlg::s_pDialog;
小插曲:这里推荐一个学习编程的网站 鸡啄米http://www.jizhuomi.com/software/257.html,
里面有MFC的入门学习资料,很基础,可以快速入门,想提高的话,可以看孙鑫老师的VC++和深入浅出MFC之类的。
2.2 MFC创建文件夹
就是在指定目录下创建文件夹,然后把一些处理结果和图片保存到该目录下。CString m_strFolderPath=_T("E:\\path"); if(!PathIsDirectory(m_strFolderPath)) { CString strMsg; strMsg.Format (_T("指定路径\"%s\"不存在,是否创建?"), m_strFolderPath); if (AfxMessageBox(strMsg, MB_YESNO) == IDYES) { if (!CreateDirectory(m_strFolderPath, NULL ) ) { strMsg.Format(_T("创建路径\"%s\"失败!是否继续?"), m_strFolderPath); if (AfxMessageBox(strMsg, MB_YESNO) == IDYES) return; } } }
但是此处CreateDirectory有局限性,只能创建单层文件夹,如果需要创建多层,还需要自己写函数
2.3 MFC窗口背景颜色和控件颜色的设置
如果只是像前面那个例子那样,整个界面全是灰色的,那界面就很没意思了,太难看了,没人愿意去使用这样的东西。既然做了界面,就应该做的酷炫一点,美观一点,这样用起来才会比较愉悦。这里给大家讲一些最简单的装X利器,给背景和控件上点颜色,这样简单的步骤会让你的界面看起来比较高端~~对话框背景色的设置
参考:http://www.tuicool.com/articles/miai6f
(1)重载OnPaint()函数,即WM_PAINT消息,代码如下所示:
void CtestDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(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 { //CDialogEx::OnPaint(); //设置为绿色背景 CRect rect; CPaintDC dc(this); GetClientRect(rect); dc.FillSolidRect(rect,RGB(0,255,0)); } }
2、重载OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor),即WM_CTLCOLOR消息:
a)在对话框的.h文件中添加CBrush类的成员m_brushb)在对话框的.cpp文件中的OnInitDialog()中添加以下代码(背景红色):
<span style="white-space: pre;"> </span>m_brush.CreateSolidBrush(RGB(255,0,0));
c)重载OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor),代码如下:
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何特性 if(nCtlColor == CTLCOLOR_DLG) return m_brush; //返加红色刷子 // TODO: 如果默认的不是所需画笔,则返回另一个画笔 return hbr;<pre name="code" class="cpp">
控件颜色的设置
重载OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor),即WM_CTLCOLOR消息:
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何特性 // 设置显示字体 CFont * font=new CFont; font->CreateFont(16,0,0,0,FW_SEMIBOLD,FALSE,FALSE,0, ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH&FF_SWISS,_T("Arial")); switch(nCtlColor) { case CTLCOLOR_STATIC: //对所有静态文本框的设置 { pDC->SetBkMode(TRANSPARENT); //设置背景为透明 pDC->SetTextColor(RGB(255,255,0)); //设置字体颜色 pWnd->SetFont(font); //设置字体 HBRUSH B = CreateSolidBrush(RGB(125,125,255)); //创建画刷 return (HBRUSH) B; //返回画刷句柄 } case CTLCOLOR_EDIT: //对所有编辑框的设置 { if(IDC_EDIT2 == pWnd->GetDlgCtrlID()) { pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(255,255,0)); pWnd->SetFont(font); HBRUSH B = CreateSolidBrush(RGB(125,125,125)); return (HBRUSH) B; } if(IDC_EDIT3 == pWnd->GetDlgCtrlID()) { pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(255,0, 0)); pWnd->SetFont(font); HBRUSH B = CreateSolidBrush(RGB(125,125,0)); return (HBRUSH) B; } } default: return CDialog::OnCtlColor(pDC,pWnd, nCtlColor); } // TODO: 如果默认的不是所需画笔,则返回另一个画笔 return hbr; }
注:
nCtlColor的类别有以下几种:
CTLCOLOR_BTN 按钮控件
CTLCOLOR_DLG 对话框
CTLCOLOR_EDIT 编辑框
CTLCOLOR_LISTBOX 列表框
CTLCOLOR_MSGBOX 消息框
CTLCOLOR_SCROLLBAR 滚动条
CTLCOLOR_STATIC 静态文本
这部分主要给大家讲了一下MFC做界面遇到的部分困难,不会的时候他们是困难,学会了之后就是技术了。还有一些其他常见的问题比如界面的放大缩小、最大化和还原、界面的多线程问题等等,还有好多的。通过这些就可以很容易做出类似这样的界面
类比第一个程序,把Kinect代替电脑的摄像头,然后把Kinect 获取的图像显示到MFC界面上,这个问题的主要难度都在文章的第二部分讲到了,并给出了解决方案,具体的实现将在下一章中讲解。敬请期待~
超跑开起来,要先制定一个小目标,比如先买辆兰博基尼限量款~哈哈哈
相关文章推荐
- [置顶] 第七章 KinectV2结合MFC显示和处理图像数据(下)
- Opencv (Opencv2)结合MFC学习数字图像处理【3】---显示图片
- (转)Opencv (Opencv2)结合MFC学习数字图像处理【3】---显示图片
- Opencv (Opencv2)结合MFC学习数字图像处理---显示图片
- vc/mfc获取rgb图像数据后动态显示及保存图片的方法
- vc/mfc获取rgb图像数据后动态显示及保存图片的方法
- OpenCV 利用MFC的Picture控件显示和处理图像
- OpenCV学习笔记(三):将图像显示在MFC控件上并做直方图均衡化处理
- vc/mfc获取rgb图像数据后动态显示及保存图片的方法
- MFC图像处理软件 地图 不显示图片对话框
- VS2012中MFC使用Picture Control显示OpenCV处理的图像
- Opencv (Opencv2)结合MFC学习数字图像处理---图片解码(3)
- 远程控制编写之屏幕传输 MFC实现 屏幕截图 发送bmp数据 显示bmp图像
- 利用MFC的Picture控件显示和处理图像
- Opencv (Opencv2)结合MFC学习数字图像处理【2】---图片解码
- Opencv (Opencv2)结合MFC学习数字图像处理---图片解码(2)
- Kinect V2彩色数据用OpenCV显示
- opencv2.3结合MFC显示图像
- Kinect V2深度数据用OpenCV显示
- MFC图像处理-图像移动显示算法