利用MFC来显示摄像头并拍照
今天是第一次尝试写一个MFC程序。水了一天,终于写好了。总结一下。
一、配置环境
调用摄像头是通过opencv库进行的,所以首先要配置好opencv 的环境。这个可以通过这个链接进行配置。
https://blog.csdn.net/qq_41175905/article/details/80560429
需要注意的几点:
1.在vs2017属性管理器中配置路径时,配置x64文件夹是代表MFC运行在64位系统上的,Win32(x86)是代表MFC运行在32位系统上的,所以要根据生成MFC的运行环境来进行配置。
2.这个教程应该是完全可以配置成功的。
3.需要注意的是,opencv3.0以上的版本是没有x86的库,可以用cmake进行编译生成,但是我没尝试成功,可以下载低版本,配置方法稍微不点不同。
二、搭建整体框架
利用vs2017生成MFC框架。然后在资源视图上,进行整体的规划。我设计的样式如图:
这里需要注意的点:
1.每个控件的ID,自己要修改命名。注意要能容易辨别出来。
2.添加控件变量时,会在类中自动添加。将变量与控件相互绑定起来。需要利用函数 :UpdateData();TRUE表示从控件传给变量,FALSE表示从变量传给控件。默认值是TRUE,即从控件传给变量。
三、事件处理函数。
在资源视图上双击需要添加事件处理函数的控件。进入源代码中进行编写程序。这个demo中主要是进行了“打开摄像头”和“拍照”的事件处理。同时也添加了定时器的事件处理函数。主要源代码如下
void CMFCCameraDlg::OnBnClickedOpencam() { // TODO: 在此添加控件通知处理程序代码 //double m_observe_z[8]; Mat frame; cap.open(0); //for (int ii = 0; ii< 50;ii++) //{ cap >> frame; CDC* pDC = GetDlgItem(IDC_ShowImage)->GetDC();//得到图片控件的指针对象。 HDC hDC = pDC->GetSafeHdc();//得到可以操作的句柄。这种形式类似于 CWND 和HWND //IplImage img = frame; CImage cimg; MATTOCIM mattocim; //自己定义的一个类,实现功能主要是CImage与Mat格式相互转换。 mattocim.MatToCImage(frame, cimg);//Mat格式转为 CImage类型。 CRect rect; GetDlgItem(IDC_ShowImage)->GetClientRect(&rect); cimg.Draw(hDC,rect); ReleaseDC(pDC); SetTimer(1, 1, NULL); //imshow("调用摄像头", frame); //waitKey(30); //} } void CMFCCameraDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 Mat frame; //for (int ii = 0; ii< 50;ii++) //{ cap >> frame; CDC* pDC = GetDlgItem(IDC_ShowImage)->GetDC(); HDC hDC = pDC->GetSafeHdc(); //IplImage img = frame; CImage cimg; MATTOCIM mattocim; mattocim.MatToCImage(frame, cimg); CRect rect; GetDlgItem(IDC_ShowImage)->GetClientRect(&rect); cimg.Draw(hDC, rect); ReleaseDC(pDC); //SetTimer(1, 10, NULL); CDialogEx::OnTimer(nIDEvent); } void CMFCCameraDlg::OnBnClickedTakephoto() { Mat frame; //for (int ii = 0; ii< 50;ii++) //{ cap >> frame; imwrite("1.bmp", frame); KillTimer(1); cap.release(); // TODO: 在此添加控件通知处理程序代码 }
需要注意的点:
1.在前面的MFC编程基础中,我们已经提到了消息映射表。vs2017中会自动为我们添加这个映射表。
2.定时器事件需要自己手动增加。增加的步骤是:
1.打开类视图
2.打开后,右键对话框类
3.在类向导里面添加,或者在下面的属性窗口添加