mfc | mfc集成opencv,实现摄像头监控、拍照、视频图像处理(亮度、对比度、色调、饱和度)功能
这里是引用
文章目录
- 一、开发环境
- 二、MFC项目创建
- 三、集成opencv
- 3.1 opencv安装
- 3.2 添加项目属性
- 3.3 测试OpenCV(打开摄像头)
- 3.4 OPENCV视频嵌入到弹框中
- 四、关闭摄像头、拍照功能实现
- 4.1 添加按钮
- 4.2 添加全局静态变量
- 4.3 关闭摄像头功能实现
- 4.4 拍照功能实现
- 五、重复打开BUG修复
- 5.1 问题描述
- 5.2 解决方案
- 六、视频图像处理功能实现
- 6.1 添加滑条和编辑框控件
- 6.1.1 添加滑条和编辑框
- 6.1.2 滑条和编辑框控件绑定变量
- 6.1.3 设置滑动条范围、初始值
- 6.1.4 设置编辑框初始值
- 6.1.5 设置滑动条值显示到编辑框中
- 6.1.6 设置默认值
- 6.2 亮度功能实现
- 总结
一、开发环境
编辑器:Visual Studio2022
OpenCV版本:4.9.0
二、MFC项目创建
三、集成opencv
3.1 opencv安装
下载地址:https://opencv.org/releases/
安装:无脑下一步(记住opencv的安装路径)
3.2 添加项目属性
- 右键项目点击属性。在“通用属性-VC++目录-常规-包含目录”中添加%opencv%\build\include\opencv2和%opencv%\build\include,%opencv%为你自己的opencv目录。
-
在“通用属性-VC++目录-常规-库目录”中添加%opencv%\build\x64\vc15\lib,%opencv%为你自己的opencv目录
-
在“通用属性-链接器-输入-附加依赖项”中添加%opencv%\build\x64\vc15\lib\opencv_world451d.lib,%opencv%为你自己的opencv目录。不同版本的该文件名称不同,只需要将自己版本的opencv文件夹中该文件名填入即可。要注意一定要是****d.lib,因为只有d.lib才对应的是dubug版本
点击应用确定。至此Opencv开发环境配置完成。
3.3 测试OpenCV(打开摄像头)
1.创建打开摄像头按钮
2.编辑确定按钮的代码,代码内容如下
void CopencvdemoDlg::OnBnClickedopen()
{//1.从摄像头读入视频VideoCapture cap(0);//2.循环显示每一帧while (1){Mat cam;cap >> cam;//获取当前帧图像imshow("相机", cam);//显示当前帧图像waitKey(30);//延时30秒}
}
3.添加头文件
#include <opencv2/opencv.hpp>
#include<opencv2/highgui/highgui_c.h>using namespace std;
using namespace cv;
4.至此测试编码完成,启动项目,点击确定,界面如下:
3.4 OPENCV视频嵌入到弹框中
- 控件添加(Picture Control)
从工具栏中选择Picture Control,拖动到窗口中,调整大小,移动到合适位置,效果如下图
-
控件ID修改
右击控件属性,修改ID为"IDC_PIC"
-
控件绑定变量
右击控件,添加变量
-
控件绑定点击事件
点击完成后,双击按钮控件,重新编写代码,代码如下
void CopencvdemoDlg::OnBnClickedopen()
{//将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秒}
}
- 启动项目,效果如下
四、关闭摄像头、拍照功能实现
4.1 添加按钮
ID | 显示文字 |
---|---|
IDC_open | 打开摄像头 |
IDC_close | 关闭摄像头 |
IDC_photo | 拍照 |
4.2 添加全局静态变量
1.打开项目对话框的头文件(opencv_demoDlg.h),在头文件中定义静态变量
static bool closeFlag; //关闭摄像头标志
static bool takePhotoFlag; //拍照标志
2.打开项目对话框的cpp文件
(opencv_demoDlg.cpp),在cpp文件中声明变量。
下图中的folderPath为全局变量,closeFlag、takePhotoFlag 两个变量为静态变量(静态变量的定义为类名::变量名
)
//关闭监控标志
bool CopencvDemoDlg::closeFlag = false;
//拍照标志
bool CopencvDemoDlg::takePhotoFlag = false;
//图片默认存储位置
CString folerPath = L"./opencv_demo_pic/"; //相对路径
4.3 关闭摄像头功能实现
- 双击
关闭摄像头
按钮,添加如下代码
void CopencvdemoDlg::OnBnClickedclose()
{// closeFlag置为true,关闭实时监控CopencvdemoDlg::closeFlag = true;
}
- 双击
打开摄像头
按钮,更改如下代码
//打开摄像头按钮
void CopencvdemoDlg::OnBnClickedopen()
{// 当用户点机实时监控,将closeFlag置为falseCopencvdemoDlg::closeFlag = false;//将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; // 创建视频采集对象;cap.open(0); // 打开默认相机;if (!cap.isOpened())// 判断相机是否打开成功;{MessageBox(_T("无法连接摄像头!!!"));return;}//2.循环显示每一帧while (1){Mat cam;cap >> cam;//获取当前帧图像imshow("picView", cam);//显示当前帧图像waitKey(30);//延时30秒//如果CloseFlag为true,跳出循环,结束监控if (CopencvdemoDlg::closeFlag== true) break;}//控件PictureControl 清除显示GetDlgItem(IDC_PIC)->ShowWindow(FALSE);GetDlgItem(IDC_PIC)->ShowWindow(TRUE);cap.release();cv::destroyAllWindows();
}
至此点击运行项目,可以实现摄像头的开启和关闭功能。
4.4 拍照功能实现
- 双击
拍照
按钮,添加如下代码
void CopencvdemoDlg::OnBnClickedphoto()
{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);}
拍照功能至此完成,运行项目,点击打开摄像头后,点击拍照即可实现拍照。拍摄的照片可在工程目录下的opencv_demo_pic
文件夹中查看。
五、重复打开BUG修复
5.1 问题描述
尝试发现,当打开摄像头之后,再次点击打开摄像头,视频消失,窗体被销毁;或者,未连接摄像头时,点击打开摄像头后,弹出窗口后,窗体控件出错
5.2 解决方案
(1)在相机打开失败时,进行摄像头关闭操作。
(2)成功打开摄像头后,将打开摄像头
按钮禁用
(3)关闭摄像头后启用打开摄像头
按钮,并清空重启窗体控件
六、视频图像处理功能实现
6.1 添加滑条和编辑框控件
6.1.1 添加滑条和编辑框
设置编辑框为只读
6.1.2 滑条和编辑框控件绑定变量
功能 | 滑条ID | 滑条变量 | 编辑框ID | 编辑框变量(值变量int) |
---|---|---|---|---|
亮度 | IDC_SLIDER_Brightness | s_Brightness | IDC_EDIT_Brightness | i_Brightness |
对比度 | IDC_SLIDER_contrast | s_contrast | IDC_EDIT_contrast | i_contrast |
色调 | IDC_SLIDER_hue | s_hue | IDC_EDIT_hue | i_hue |
饱和度 | IDC_SLIDER_saturation | s_saturation | IDC_EDIT_saturation | i_saturation |
6.1.3 设置滑动条范围、初始值
//设置滑动条范围
s_Brightness.SetRange(0, 255);
s_contrast.SetRange(0, 255);
s_hue.SetRange(0, 127);
s_saturation.SetRange(0, 255);//设置滑动条初始值
s_Brightness.SetPos(25);
s_contrast.SetPos(127);
s_hue.SetPos(0);
s_saturation.SetPos(127);
6.1.4 设置编辑框初始值
,i_brightness(25)
,i_contrast(127)
,i_hue(0)
,i_saturation(127)
6.1.5 设置滑动条值显示到编辑框中
将滑块数据显示到编辑框中,在【项目】-【类向导】-【消息】页面,找到消息事件函数WM_HSCROLL
,双击出现在右边方框,再次双击右边方框 OnHScroll
函数
在弹出的消息事件函数里面,添加如下代码:
//消息事件
void CopencvdemoDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{// TODO: 在此添加消息处理程序代码和/或调用默认值UpdateData(TRUE);i_brightness = s_brightness.GetPos();//获得滑动块当前位置i_contrast = s_contrast.GetPos();i_hue = s_hue.GetPos();i_saturation = s_saturation.GetPos();UpdateData(FALSE);CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}
至此界面显示完成,运行项目,滑动条的值可以实时显示在编辑框中
6.1.6 设置默认值
双击设为默认按钮
,添加如下代码
6.2 亮度功能实现
总结
以上就是本文要讲的内容。