1. 开发环境

编辑器:Visual Studio2022
OpenCV版本:4.5.4

2. MFC项目搭建





点击完成后,项目创建完成。界面如下:

点击"本地Windows调试器",即可运行,运行结果如下:

3. 集成OPENCV

3.1 opencv安装

下载地址:https://opencv.org/releases/
安装:无脑下一步(记住opencv的安装路径)

3.2 opencv目录

安装完成后,opencv目录下有build和sources两个文件夹,build是我们需要使用的,build文件夹内容见下图

3.3 opencv文件拷贝到项目中

右击项目,选择"在文件资源管理器中打开文件夹"

将opencv/build/include目录复制到项目的目录下
将opencv/build/x64/vc15/lib目录复制到项目的目录下
复制完后的目录如下:

回到项目,点击重新生成,打开生成exe所在的目录

将opencv\build\x64\vc15\bin目录下的opencv_videoio_ffmpeg454_64.dll,opencv_world454d.dll文件都拷贝到exe所在目录。
拷贝好的项目目录如下:

3.4 opencv配置

配置项目的页面:右击项目->属性->左侧的三个目录

库目录:


选择刚才拷贝的lib文件,确定

回到上一层,点击应用。

头文件:同理添加头文件。

链接器:在链接器中添加opencv_world454d.lib(直接粘贴即可)

点击应用确定。至此Opencv开发环境配置完成。

3.5 测试OpenCV

回到项目主界面,双击确定,进入代码

编辑确定按钮的代码,代码内容如下

void CopencvDemoDlg::OnBnClickedOk()
{//1.从摄像头读入视频VideoCapture cap(0);//2.循环显示每一帧while (1){Mat cam;cap >> cam;//获取当前帧图像imshow("相机", cam);//显示当前帧图像waitKey(30);//延时30秒}
}

拉到项目最上方,添加头文件

#include <opencv2/opencv.hpp>
#include<opencv2/highgui/highgui_c.h>using namespace std;
using namespace cv;


至此项目编码完成,启动项目,点击确定,界面如下:

3.6 OPENCV视频嵌入到弹框中

3.6.1 控件添加(Picture Control)

从左侧的工具栏中选择Picture Control,拖动到窗口中,调整大小,移动到合适位置,效果如下图

3.6.2 控件ID修改

右击控件属性,修改ID为"IDC_PIC"

3.6.3 控件绑定变量

右击控件,添加变量

3.6.4 控件绑定点击事件

点击完成后,双击页面的确定,重新编写代码,代码如下

void CopencvDemoDlg::OnBnClickedOk()
{//将opencv的窗体嵌入到页面中cv::namedWindow("picView", cv::WINDOW_AUTOSIZE);HWND hWnd = (HWND)cvGetWindowHandle("picView");HWND hParent = ::GetParent(hWnd);::SetParent(hWnd, GetDlgItem(IDC_PIC)->m_hWnd);::ShowWindow(hParent, SW_HIDE);//1.从摄像头读入视频VideoCapture cap(0);//2.循环显示每一帧while (1){Mat cam;cap >> cam;//获取当前帧图像imshow("picView", cam);//显示当前帧图像waitKey(30);//延时30秒}
}

启动项目, 效果如下:

3.6.5 Button控件显示的文字修改

右击按钮属性,修改描述文字,ID

3.7 界面设计

3.7.1 放大对话框区域

将鼠标移动至对话框右下角,左击(不松开)鼠标,往右下角拖动,放大窗口,放大后的效果如下图

3.7.2 添加Button控件

左击(不松开)工具箱的Button控件,拖动到右侧的对话框后,松开鼠标左键

同理再添加4个按钮,效果如图

3.7.3 按钮显示内容修改

参照3.6.5 章节,修改按钮的显示名称。

名称 显示文字 变量
按钮1 关闭监控
按钮2 录像
按钮3 录像结束
按钮4 播放视频
按钮5 打开照片所在目录

修改完毕后,拖动控件,重新布局,效果如下

4 监控、拍照、录像功能实现

4.2 添加全局静态变量

打开项目对话框的头文件(opencvDemoDlg.h),在头文件中定义静态变量

 static bool closeFlag;//关闭监控标志static bool takePhotoFlag;//拍照标志static bool recordFlag;//录像标志

打开项目对话框的cpp文件(opencvDemoDlg.cpp),在cpp文件中声明变量。
下图中的folderPath为全局变量,closeFlag、takePhotoFlag 、recordFlag三个变量为静态变量(静态变量的定义为类名::变量名)

//关闭监控标志
bool CopencvDemoDlg::closeFlag = false;
//拍照标志
bool CopencvDemoDlg::takePhotoFlag = false;
//录像标志
bool CopencvDemoDlg::recordFlag = false;
//图片、视频默认存储位置
CString folerPath = L"c:/record/";

4.2 关闭监控功能实现

回到资源视图,打开主对话框,双击关闭监控按钮,添加如下代码

void CopencvDemoDlg::OnBnClickedButton1()
{// closeFlag置为true,关闭实时监控CopencvDemoDlg::closeFlag = true;
}

同理,双击实时监控,添加如下代码

//当用户点机实时监控,将closeFlag置为false
CopencvDemoDlg::closeFlag = false;//此处代码省略//如果CloseFlag为true,跳出循环,结束监控
if (CopencvDemoDlg::closeFlag) break;


至此已经实现监控、关闭监控功能,至此点击运行项目,测试开启和关闭功能。

4.3 开启关闭BUG修复

尝试发现,当第一次关闭再打开后,只有摄像头再亮,视频不显示。原因是我们创建的picView窗体已被销毁。解决方案只需要确保我们每次打开的窗体名称不同即可,此时可以使用时间来命名窗口。

void CopencvDemoDlg::OnBnClickedOk()
{//获取当前时间日期  CTime m_time;m_time = CTime::GetCurrentTime();//通过格式化日期,构建View名称CString viewTime = m_time.Format(_T("%Y%m%d%H%M%Sview"));//将CString转换为string类型string viewTitleString = CT2A(viewTime.GetBuffer());//将string类型转为char*char* viewName = (char*)viewTitleString.data();//当用户点机实时监控,将closeFlag置为falseCopencvDemoDlg::closeFlag = false;//将opencv的窗体嵌入到页面中cv::namedWindow(viewName, cv::WINDOW_AUTOSIZE);HWND hWnd = (HWND)cvGetWindowHandle(viewName);HWND hParent = ::GetParent(hWnd);::SetParent(hWnd, GetDlgItem(IDC_PIC)->m_hWnd);::ShowWindow(hParent, SW_HIDE);//1.从摄像头读入视频VideoCapture cap(0);//2.循环显示每一帧while (1){Mat cam;cap >> cam;//获取当前帧图像imshow(viewName, cam);//显示当前帧图像//如果CloseFlag为true,跳出循环,结束监控if (CopencvDemoDlg::closeFlag) break;waitKey(30);//延时30秒}
}


至此开启监控、关闭监控功能开发完成。

4.4 拍照

回到资源视图,打开主对话框,双击拍照按钮,添加如下代码

void CopencvDemoDlg::OnBnClickedPhoto()
{// TODO: 在此添加控件通知处理程序代码takePhotoFlag = true;
}

双击实时监控按钮,添加如下代码

 //拍照if (takePhotoFlag){//拍照状态重置takePhotoFlag = false;//生成并转换照片名称m_time = CTime::GetCurrentTime();             CString m_strDateTime = folerPath + m_time.Format(_T("%Y%m%d%H%M%S.jpg"));  string name = CT2A(m_strDateTime.GetBuffer());//将Mat数据写入文件bool res = imwrite(name, cam);  }

拍照功能至此完成,运行项目,点击实时监控后,点击拍照即可实现拍照。拍摄的照片可在C:\record目录下查看。

4.5 打开照片所在位置

回到资源视图,打开主对话框,双击打开照片所在位置按钮,添加如下代码

CreateDirectory(folerPath, NULL);
ShellExecute(NULL, NULL, folerPath, NULL, NULL, SW_SHOW);

4.6 录像

回到资源视图,打开主对话框,双击录像按钮,添加如下代码

//开启摄像头VideoCapture capture(0);// 获取视频参数int width = capture.get(CAP_PROP_FRAME_WIDTH);int height = capture.get(CAP_PROP_FRAME_HEIGHT);int count = capture.get(CAP_PROP_FRAME_COUNT);double fps = capture.get(CAP_PROP_FPS);//生成录制文件名CTime m_time;m_time = CTime::GetCurrentTime();CString videoNameCString = folerPath + m_time.Format(_T("%Y%m%d%H%M%S.avi")); //格式化日期时间string videoName = CT2A(videoNameCString.GetBuffer());//实例化VideoWriter对象VideoWriter writer(videoName, VideoWriter::fourcc('D', 'I', 'V', 'X'), 30, Size(width, height), true);//生成实时监控名Mat frame;CString viewNameCString = folerPath + m_time.Format(_T("%Y%m%d%H%M%SView"));string viewNameString = CT2A(viewNameCString.GetBuffer());//opencv嵌入到mfc中char* viewName = (char*)viewNameString.data();cv::namedWindow(viewName, cv::WINDOW_AUTOSIZE);HWND hWnd = (HWND)cvGetWindowHandle(viewName);HWND hParent = ::GetParent(hWnd);::SetParent(hWnd, GetDlgItem(IDC_PIC)->m_hWnd);::ShowWindow(hParent, SW_HIDE);//循环播放并录制while (true) {//读帧数据,显示数据capture.read(frame);flip(frame, frame, 1);if (frame.empty()) break;imshow(viewName, frame);//帧写入视频文件writer.write(frame);waitKey(30);if (recordFlag) break;}//重置录制状态recordFlag = false;//释放写视频对象writer.release();

4.7 结束录像

回到资源视图,打开主对话框,双击录像结束按钮,添加如下代码

recordFlag = true;

录像功能至此结束,运行项目,点击录像,等待一段时间,点击结束录像,录像完成。

4.8 播放视频

回到资源视图,打开主对话框,双击播放视频按钮,添加如下代码

 // 公共对话框结构。   OPENFILENAME ofn;// 保存获取文件名称的缓冲区。TCHAR szFile[MAX_PATH];// 初始化选择文件对话框。   ZeroMemory(&ofn, sizeof(OPENFILENAME));ofn.lStructSize = sizeof(OPENFILENAME);ofn.hwndOwner = NULL;ofn.lpstrFile = szFile;ofn.lpstrFile[0] = '\0';ofn.nMaxFile = sizeof(szFile);ofn.lpstrFilter = L"All(*.*)\0*.*\0Text(*.txt)\0*.AVI\0\0";ofn.nFilterIndex = 1;ofn.lpstrFileTitle = NULL;ofn.nMaxFileTitle = 0;ofn.lpstrInitialDir = NULL;ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;//ofn.lpTemplateName =  MAKEINTRESOURCE(ID_TEMP_DIALOG);  // 显示打开选择文件对话框。   if (GetOpenFileName(&ofn)){//显示选择的文件。   OutputDebugString(szFile);playAVI(szFile);}

在函数外,添加PlayAVI的实现

void CopencvDemoDlg::playAVI(CString cfileName)
{CTime m_time;m_time = CTime::GetCurrentTime();             //获取当前时间日期  CString viewTime = m_time.Format(_T("%Y%m%d%H%M%Sview"));string viewNameString = CT2A(viewTime.GetBuffer());char* viewName = (char*)viewNameString.data();cv::namedWindow(viewName, cv::WINDOW_AUTOSIZE);HWND hWnd = (HWND)cvGetWindowHandle(viewName);HWND hParent = ::GetParent(hWnd);::SetParent(hWnd, GetDlgItem(IDC_PIC)->m_hWnd);::ShowWindow(hParent, SW_HIDE);string fileName = CT2A(cfileName.GetBuffer());VideoCapture capture(fileName);while (true) {Mat frame;Mat edge;capture >> frame;if (frame.empty())break;cvtColor(frame, edge, COLOR_BGR2GRAY);imshow(viewName, frame);//等待50ms,如果从键盘输入的是q、Q、或者是Esc键,则退出int key = waitKey(50);if (key == 'q' || key == 'Q' || key == 27)break;}
}

打开项目的头文件(opencvDemoDlg.h),添加PlayAVI的声明

void playAVI(CString cfileName);//播放avi视频


至此监控、拍照、录像、录像播放功能完成。

mfc | mfc集成opencv,实现监控、拍照、录像、录像播放(保姆级教程)相关推荐

  1. opencv的安装保姆级教程,并在pycharm下配置opencv

    本人在这三周不断的试着安装opencv的过程中积累了一些关于安装opencv的经验:想的把自己的积累分享出去,也是第一次写技术博客:有什么不足请见谅: 正文: 1.安装python和pycharm(按 ...

  2. 服务搭建篇(一) 搭建基于prometheus + node_exporter + grafana + Alertmanager 的监控报警系统 , 保姆级教程

    感兴趣的话大家可以关注一下公众号 : 猿人刘先生 , 欢迎大家一起学习 , 一起进步 , 一起来交流吧! 一. 介绍 1.Prometheus: 一个监控系统,集成在项目中可以对项目运行的一些情况进行 ...

  3. 官方指标监控神器SpringBootAdmin保姆级教程

    SpringBoot Admin 概述 Spring Boot 有一个非常好用的监控和管理的源软件,这个软件就是 Spring Boot Admin.该软件能够将 Actuator 中的信息进行界面化 ...

  4. Mac Xcode opencv C++环境配置 保姆级教程 填坑记录 19年最新版本

    网上找了很多教程,照着做都失败了,整整弄了两天两夜,终于好了.网上根本没有人遇到我的坑么?都搜不到,国外也没搜到,呜呜- 版本说明: 1.(必备)MacBook系统:macOS Catalina(版本 ...

  5. 树莓派3b+快速编译opencv成功案例指导(保姆级教程)

    如果对opencv的版本没有特别要求建议直接去找已经安装好opencv的镜像.那个才是最快的速度! 真是亲身体验!就差人傻了!先1我的对树莓派基本小白一个好吧,只能出一个傻瓜式教程了. 不想看傻瓜式教 ...

  6. 胎儿式保姆级教程:Jetson Xavier NX镜像烧录、开机配置、中文配置、风扇设置、远程桌面、文件传输配置、pycharm安装环境配置,QQ,opencv(cuda编译),torch(GPU).

    一.使用的硬件:nx板子.原装充电器.有线鼠标(USB).有线键盘(USB).有线摄像头(USB).7寸触摸显示屏.20寸大显示屏(显示屏有一个就可以,大屏幕更加方便).SD卡(128G,用64g也可 ...

  7. 新手入门保姆级教程,Linux平台和手机端SDK,基于Opencv、MNN、NCNN

    端侧部署开源项目:https://github.com/hzpzlz/EasyDeploy 一 MNN编译动态库 环境要求 cmake(建议使用3.10或以上版本) protobuf(使用3.0或以上 ...

  8. 阿里云“免费SSL证书”集成指南-保姆级教程

    教你白嫖阿里云免费SSL证书 SSL证书(SSL Certificates)可以说是现在一个网站的标配,如果没有用SSL证书,浏览器上会显示不安全,导致一部分用户以为网站有问题.另外在微信小程序和iO ...

  9. SpringBoot 集成 thumbnailator (图片缩放,区域裁剪,水印,旋转,保持比例)保姆级教程(含代码)

    Thumbnailator 是 Google 开源的图片处理库,支持:图片缩放,区域裁剪,水印,旋转,保持比例.详细介绍可以百度或官网,话不多说,直接上代码,具体要结合自己的业务需要进行使用(有些复杂 ...

最新文章

  1. 我练习项目眼中的 vue
  2. safair浏览器页面局部滑动问题
  3. 【深度学习】搞懂 Vision Transformer 原理和代码,看这篇技术综述就够了
  4. 图像识别最新赛事!总奖金31万,一起组队吗?
  5. linux安装篇之mongodb安装及服务自启动配置
  6. 原!操作 excel 03/07
  7. ASP.NET MVC过滤器
  8. linux浏览器打开pdf文件,linux下的pdf浏览器(可加批注)
  9. Dart 10-Day
  10. unity C# 常用算法 和 算法复杂度
  11. Codeigniter分页类代码实例
  12. springboot幂等性_SpringBoot+Redis实现接口幂等性,就看这篇了
  13. JSTL的一些使用规范,坑
  14. 在PHP中开启CURL扩展,使其支持curl()函数
  15. 免费前端网站页面模板
  16. Linux下七种文件类型、文件属性及其查看方法
  17. 人体关节正常活动范围
  18. C#报表开发工具ReportViewer vs Stimulsoft Reports.Net
  19. Android Q 上的Biometric生物识别
  20. 计算机板块:外包引领软件业高成长

热门文章

  1. others-七牛云图床备份
  2. TypeError:__init__() got an unexpected keyword argument 'xxx'
  3. 物联网工程专业属于计算机类吗,物联网工程属于计算机专业吗
  4. 飞思卡尔单片机编程与c语言,飞思卡尔单片机高效C语言编程(中文)
  5. Go 1.18特性快速了解 | Gopher Daily (2021.12.18) ʕ◔ϖ◔ʔ
  6. 投资理财-普通投资的策略
  7. 使用css3制作照片墙
  8. 联想flex 换android,Flex14首发拆机,更换SSD
  9. 联想flex 换android,联想flex15拆机加装SSD固态硬盘教程!
  10. 专业影像编辑软件Vegas pro17注册机下载安装