搭建MFC框架启动摄像头

搭建MFC框架启动摄像头
在之前的博⽂中已经完成了针对图⽚的⼈脸性别识别功能,在这篇⽂章中我们开始引⼊摄像头设备,为程序添加第⼆个功能:视频⼈脸性别识别。
  ⼀、添加控件
  这⾥需要新添加两个与视频⼈脸性别识别相关的功能控件,⼀个是“打开视频”按钮(ID为IDC_OpenVideo),⼀个是“暂停按钮”按钮。为了适当减少主窗⼝中的按钮控件的数量,这⾥再次采⽤⼀种复⽤策略,即将视频识别模式中的“暂停”功能与之前图⽚⽂件夹识别模式中的“下⼀张”功能合并,通过⼀个按钮来控制:
  ⼆、CVideoInfo类
  2.1 添加视频流类
  接下来需要开启视频摄像头,将摄像头得到的图像实时的显⽰在主程序的picture控件中。有关OpenCv中的摄像头操作我在这篇博⽂中进⾏了较为详细的介绍。这⾥我们对摄像头的开启进⾏⼀下⼩⼩的封装,即将其声明为⼀个类CVideoInfo,这样做的原因主要是为了能够⽅便后期的处理,我们将摄像头输出的视频流、帧图像、帧图像的尺⼨(宽度和⾼度)都封装在同⼀个对象中,⽅便读取,也⽅便获取图像的相关属性
  在VS中切换到类视图窗⼝,右击⼯程名,添加类:
  指定添加类的类型为“C++类”:
  输⼊类名CVideoInfo,对应的.h⽂件和.cpp⽂件名称系统会⾃动⽣成,⽆继承,访问属性默认使⽤public,单击完成:
  此时在类视图下可以看到⼯程中多了⼀个名为CVideoInfo的类:
  2.2 编辑CVideoInfo类
  接下来为CVideoInfo添加相应的代码。切换到解决⽅案资源管理器窗⼝,会发现此时⼯程⽬录下会多出两个⽂件,VideoInfo.h和VideoInfo.cpp:
  ⾸先编辑类对应的头⽂件VideoInfo.h,发现VS已经在头⽂件中提供了基本的类声明,并给出了缺省的构造函数和析构函数,我们在这⾥只需向其中添加若⼲成员变量即可,这⾥我们添加四个成员变量:CvCapture*格式的视频流变量,IplImage*格式的帧图像变量,以及两个整型变量⽤以表⽰帧图像的宽度和⾼度:
CvCapture* m_pCapture;    //⽤于存储摄像头输⼊的视频流
IplImage* m_pFrameImage;  //存储图⽚
int m_FrameWidth;          //图⽚宽度
洗水
int m_FrameHeight;        //图⽚⾼度
  最终VideoInfo.h⽂件中的类声明代码如下:
#pragma once
#include "opencv2/opencv.hpp"
class CVideoInfo
{
public:
CvCapture* m_pCapture;    //⽤于存储摄像头输⼊的视频流
雨水口施工IplImage* m_pFrameImage;  //存储图⽚
int m_FrameWidth;          //图⽚宽度
int m_FrameHeight;        //图⽚⾼度
public:
CVideoInfo(void);          //缺省构造函数
public:
~CVideoInfo(void);        //缺省析构函数
};
  ⾄于VideoInfo.cpp,由于VideoInfo类⽬前只是负责图像的存储和显⽰,没有其他额外的功能,因此在这⾥只需要完成构造函数对成员变量的初始化,⽽析构函数采⽤系统提供的缺省函数即可,VideoInfo.cpp⽂件的代码如下:
#include "StdAfx.h"桥梁钢模
#include "VideoInfo.h"
CVideoInfo::CVideoInfo(void)  //缺省构造函数
{
m_pCapture = NULL;
m_pFrameImage = NULL;
}
CVideoInfo::~CVideoInfo(void)//缺省析构函数
{
}
煮面机
  完成了类的定义之后,需要向CGenderRecognitionMFCDlg类中添加⼀个VideoInfo*形式的变量m_pVideoInfo⽤来保存当前的视频流信息,当然使⽤全局变量也可以实现这个功能,不过会是代码变得更复杂,不推荐。
  在添加变量之前需要先在CGenderRecognitionMFCDlg.h中包含⼀下VideoInfo.h头⽂件,使得VideoInfo类可见:
  接下来就可以正式着⼿开启摄像头了。
酸雨采样器  三、开启摄像头
  双击“打开视频”按钮,添加对应的事件处理函数:
  ⾸先,判断程序是否进⾏了分类器加载初始化:
if (m_boolInitOK == FALSE)
{
MessageBox("请先进⾏初始化");
钢副框角码
return;
}
  然后使⽤cvCreateCameraCapture函数开启摄像头,并将视频流赋值给m_pVideoInfo:
m_pVideoInfo->m_pCapture = cvCreateCameraCapture(0);//创建⼀个Capture(摄像头)
  注意此时运⾏程序的话在这句代码会报错,原因是m_pVideoInfo这个成员变量尚未被分配内存空间,因此需要在程序开始运⾏时⼿动通过new操作符对其进⾏内存空间的分配,这⾥将内存分配的语句放置在OnInitDialog()这个成员函数中:
/*********为m_pVideoInfo变量分配内存空间**********/
m_pVideoInfo = new CVideoInfo;
  四、显⽰图像
  在摄像头捕捉到图像之后,接下来需要将帧图像实时的显⽰在picture界⾯中,实现这个功能的⽅法有很多,这⾥采⽤定时器的⽅法。即设置⼀个定时器,每隔⼀定时间就触发,在对应的回调函数中完
成帧图像的显⽰⼯作。因此在OnBnClickedButton1Video()函数中需要对定时器进⾏初始化,单击“打开视频”按钮后,就开始触发定时器,轮询播放摄像头画⾯:
SetTimer(1,1,NULL);//触发⼀个计数器,在响应函数中完成图像显⽰
  有关MFC中定时器的使⽤⼤家参见⽹上资料,这⾥就不再赘述。
  接下来添加定时器消息响应函数,在类视图中右键单击CGenderRecognitionMFCDlg类,选择属性,弹出属性对话框,在消息栏中到WM_TIMER,单击右边的下拉箭头,添加消息响应函数OnTimer:
  在OnTimer()函数体中完成帧图像的绘制,这⾥直接给出代码:
void CGenderRecognitionMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
m_pVideoInfo->m_pFrameImage = cvQueryFrame(m_pVideoInfo->m_pCapture);//得到视频流中的下⼀帧
CvvImage cvvImage;
cvvImage.CopyOf(m_pVideoInfo->m_pFrameImage);
cvvImage.DrawToHDC(m_pPicCtlHdc,m_PicCtlRect);
CDialogEx::OnTimer(nIDEvent);
}
  此时运⾏程序,程序正常执⾏,能够在picture界⾯上实时的显⽰摄像头采集的图像,在下⼀篇博客中将介绍如何向其中添加性别识别的步骤。
  五、注意事项
  1、CVideoInfo类的封装问题
  说实话这⾥将摄像头输⼊的视频流封装为CVideoInfo类的⼯作⽅式显得有点⼩题⼤做,似乎直接在类中添加⼀个CvCapture*类型的成员变量就能够完成任务,但随着程序的改进,我们可能需要得到越来越多的视频帧图像的属性值(如尺⼨,通道数等等),甚⾄需要在读取帧图像之前对原图像做⼀些必要的、固化的初始化操作,如果我们将视频流封装成CVideoInfo类,就能够⽅便的以成员函数的形式给出这些操作、属性值,避免了在程序的⼤框架下添加,也避免了对各个属性值的频繁读取。
  2、类成员访问属性问题
  C++中对类成员变量的访问属性推荐设置为private,对成员函数的访问属性推荐设置为public,并且推荐通过成员函数来访问成员变量,⽽⾮直接读取。
  3、定时器问题

本文发布于:2024-09-21 00:32:37,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/115440.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:添加   摄像头   函数   属性
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议