如何利用MFC及Opencv读入摄像头并显示画面

您所在的位置:网站首页 snap拍摄 如何利用MFC及Opencv读入摄像头并显示画面

如何利用MFC及Opencv读入摄像头并显示画面

2023-08-25 07:31| 来源: 网络整理| 查看: 265

如何利用MFC及Opencv读入摄像头并显示画面?

       一般在做机器视觉项目或其他视频监控类的工程情况下,首先遇到的问题就是如何有效读入摄像头并显示,当然在opencv当中其实只用几个函数就可以解决,但是如果想显示在指定的界面,opencv就没那么方便了,本文是利用MFC制作一个简单的视频显示界面框架。如下图:

制作步骤及方法:

1、首先利用MFC应用程序向导新建一个对话框,然后在对话框中添加如上控件,两个Picture Control并更改ID为IDC_PIC_STATIC、IDC_PIC1_STATIC及三个按钮的名字。在实现过程中会用到一个文件CvvImage,因为本人使用的软件版本是Visual Studio 2013及Opencv 2.4.9,这个文件在当前的Opencv 2.4.9版本中被删除了,也不知道为什么要弃用这个。好了,这个文件网上有很多。下载好之后将文件复制到当前工程目录下,然后在当前项目界面的右边点击添加头文件CvvImage.h以及在源文件中点击添加CvvImage.cpp文件,如下图:

之后,就在OpenCameraDlg.cpp文件中添加头文件:

#include "opencv2/opencv.hpp" #include "CvvImage.h"

以及using namespace std;  using namespace cv;

2、定义全局变量:

CvCapture* Capture; CvCapture* m_Video; IplImage* frame; IplImage* m_grabframe; CRect rect; CDC *pDC; HDC hDC; CWnd *pwnd; int ImgNum = 0;

3、在对话框中右键点击打开摄像头按钮,点击添加事件响应函数一栏,然后函数名命名为On_OpenCamera

void CShowPicture_MFCDlg::On_OpenCamera() { // TODO: Add your command handler code here Capture = cvCreateCameraCapture(0); // if (Capture==0) { MessageBox(_T("无法连接摄像头!!!")); return; } frame = cvQueryFrame(Capture); //从摄像头或者文件中抓取并返回一帧 pDC = GetDlgItem(IDC_PIC_STATIC)->GetDC();//GetDlgItem(IDC_PIC_STATIC)意思为获取显示控件的句柄(句柄就是指针),获取显示控件的DC GetDlgItem(IDC_PIC_STATIC)->GetClientRect(&rect); hDC = pDC->GetSafeHdc();//获取显示控件的句柄 CvvImage m_CvvImage; m_CvvImage.CopyOf(frame, 1); //复制该帧图像 m_CvvImage.DrawToHDC(hDC, &rect); //显示到设备的矩形框内 ReleaseDC(pDC); SetTimer(1, 25, NULL); //定时器,定时时间和帧率一致 } 4、添加定时器函数

右键单击对话框在类向导中选择映射消息一栏,然后双击选择WM_TIMER,如下图所示:

在其中添加响应函数代码:

void CShowPicture_MFCDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: Add your message handler code here and/or call default pDC = GetDlgItem(IDC_PIC_STATIC)->GetDC();//GetDlgItem(IDC_PIC_STATIC)意思为获取显示控件的句柄(句柄就是指针),获取显示控件的DC GetDlgItem(IDC_PIC_STATIC)->GetClientRect(&rect); hDC = pDC->GetSafeHdc();//获取显示控件的句柄 frame = cvQueryFrame(Capture); //从摄像头或者文件中抓取并返回一帧 CvvImage m_CvvImage; m_CvvImage.CopyOf(frame, 1); //复制该帧图像 m_CvvImage.DrawToHDC(hDC, &rect); //显示到设备的矩形框内 CDialogEx::OnTimer(nIDEvent); }5、添加关闭摄像头响应函数代码

      在关闭摄像头按钮上右键选择添加响应函数一栏,并命名为On_CloseCamera,代码如下:

void CShowPicture_MFCDlg::On_CloseCamera() { // TODO: Add your command handler code here if (!Capture) { MessageBox(_T("没有打开摄像头!!!")); return; } cvReleaseCapture(&Capture); pDC = GetDlgItem(IDC_PIC_STATIC)->GetDC();//GetDlgItem(IDC_PIC_STATIC)意思为获取显示控件的句柄(句柄就是指针),获取显示控件的DC GetDlgItem(IDC_PIC_STATIC)->GetClientRect(&rect); hDC = pDC->GetSafeHdc();//获取显示控件的句柄 frame = cvLoadImage("D:\\Documents\\Visual Studio 2013\\Projects\\beijing.jpg"); //图片读取路径可以自己设定 CvvImage m_CvvImage; m_CvvImage.CopyOf(frame, 1); //复制该帧图像 m_CvvImage.DrawToHDC(hDC, &rect); //显示到设备的矩形框内 ReleaseDC(pDC); } 6、添加捕获图像响应函数代码

      在捕获图像按钮上右键单击选择添加事件响应函数一栏,并命名函数为On_CaptureImage,代码如下:

void CShowPicture_MFCDlg::On_CaptureImage() { // TODO: Add your command handler code here //m_grabframe = cvQueryFrame(Capture); m_grabframe = frame; if (m_grabframe == 0) { MessageBox(_T("摄像头已关闭,无法捕捉图像!!!")); return; } CString ImagePath=TEXT("D:\\Documents\\Visual Studio 2013\\Projects\\标定图片\\"); //CString ImagePath = _T("D:\\Documents\\Visual Studio 2013\\Projects\\标定图片\\"); if (!PathIsDirectory(ImagePath)) { CreateDirectory(ImagePath, 0);//不存在则创建 MessageBox(_T("标定图片文件夹已创建!!!")); return; } char ImagesName[100]; ImgNum = ImgNum + 1; sprintf_s(ImagesName, "%s%.2d%s", "D:\\Documents\\Visual Studio 2013\\Projects\\标定图片\\", ImgNum, ".jpg"); IplImage * m_snap = cvCreateImage(cvGetSize(m_grabframe), m_grabframe->depth, m_grabframe->nChannels); cvCopy(m_grabframe, m_snap, NULL); cvSaveImage(ImagesName, m_snap); //把图像写入指定文件夹的文件中去 //以下代码是完成图像的显示过程 pDC = GetDlgItem(IDC_PIC1_STATIC)->GetDC();//GetDlgItem(IDC_PIC_STATIC)意思为获取显示控件的句柄(句柄就是指针),获取显示控件的DC GetDlgItem(IDC_PIC1_STATIC)->GetClientRect(&rect); hDC = pDC->GetSafeHdc();//获取显示控件的句柄 CvvImage m_CvvImage; m_CvvImage.CopyOf(m_snap, 1); //复制该帧图像 m_CvvImage.DrawToHDC(hDC, &rect); //显示到设备环境的矩形框内 } 至此,整个过程就大致完成了,程序运行效果如下:

有什么疑问可以留言。。。谢谢!!!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3