MFC+OpenCV打开摄像头

        MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。

        工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。

        用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。

一、建立工程。

1、建立一个基于对话框的工程VideoProcess,在对话框中加入一个按钮IDC_CAMERA,标题为“打开摄像头” 。

      右击工程并选中“New Class…”为工程添加基类为CWinThread派生线程类CCamera。

      给工程添加新对话框IDD_CAMERA_DLG,标题为“摄像头视频”。 为对话框IDD_CAMERA_DLG创建一个基于CDialog的类CCameraDlg。


2、在主对话框中添加按钮,并双击后,添加消息响应函数(启动用户界面线程),还要加上CCamera类的头文件。

void CVideoProcessDlg::OnBnClickedCameraDlg()
{
	// TODO: 在此添加控件通知处理程序代码
	CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CCamera));
}

3、并在CCamera类中添加protected变量CCameraDlg m_dlg,并添加头文件。

#include "CameraDlg.h"
// CCamera

class CCamera : public CWinThread
{
	DECLARE_DYNCREATE(CCamera)

protected:
	CCamera();           // 动态创建所使用的受保护的构造函数
	virtual ~CCamera();

	CCameraDlg m_dlg; //tfygg

public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

protected:
	DECLARE_MESSAGE_MAP()
};

分别重载InitInstance()函数和ExitInstance()函数:

BOOL CCamera::InitInstance()
{
	// TODO: 在此执行任意逐线程初始化
	m_dlg.Create(IDD_CAMERA_DLG);
	m_dlg.ShowWindow(SW_SHOW);
	m_pMainWnd=&m_dlg;
	return TRUE;
}

int CCamera::ExitInstance()
{
	// TODO: 在此执行任意逐线程清理
	m_dlg.DestroyWindow();
	return CWinThread::ExitInstance();
}

至此,基本工程环境建立完毕。编译运行后,点击主对话框的按钮,就会弹出Camera对话框。


二、OpenCV静态编译环境搭建

1、搭建OpenCV基本环境。

(1)配置好头文件目录

(2)配置好静态库目录。选择staticlib目录

(3)添加“附加依赖库”:

IlmImfd.lib
libjasperd.lib
libjpegd.lib
libpngd.lib
libtiffd.lib
zlibd.lib
opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_ml249d.lib
opencv_nonfree249d.lib
opencv_objdetect249d.lib
opencv_ocl249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_superres249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_ocl249.lib
opencv_videostab249d.lib
opencv_photo249.lib
opencv_stitching249.lib
opencv_superres249.lib
opencv_videostab249.lib
opencv_calib3d249.lib
opencv_contrib249.lib
opencv_core249.lib
opencv_features2d249.lib
opencv_flann249.lib
opencv_gpu249.lib
opencv_highgui249.lib
opencv_imgproc249.lib
opencv_legacy249.lib
opencv_ml249.lib
vfw32.lib
comctl32.lib

          其中第一个库很重要。 最后两个库不是opencv的,但也要添加。

(4)编译测试。

2、添加CvvImage类。点击打开链接

3、添加videoProcessor类。


三、播放视频

1、在IDD_CAMERA_DLG对话框中添加Picture控件,用于显示视频。

2、在CameraDlg.h文件中添加一个线程参数结构:

struct threadInfo
{
	CRect rect;// 矩形类
	HDC hdc;                      // 获取设备上下文句柄
	CDC *pDC;
};

线程函数的声明:

UINT ThreadFunc(LPVOID lpParam);

注意,二者应在类CCameraDlg的外部。

3、在类CCameraDlg内部添加protected型变量: CWinThread* pThread;

4、在CameraDlg.cpp文件中进行如下操作:

(1)定义公共变量:  threadInfo Info;

(2)添加OnInitDialog方法。并加入以下代码

BOOL CCameraDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  在此添加额外的初始化
	UpdateData(TRUE);
	Info.pDC = GetDlgItem(IDC_VIDEO)->GetDC();//根据ID获得窗口指针再获取与该窗口关联的上下文指针
	Info.hdc= Info.pDC->GetSafeHdc();                      // 获取设备上下文句柄
    GetDlgItem(IDC_VIDEO)->GetClientRect(&Info.rect); //获取box1客户区
	pThread=AfxBeginThread(ThreadFunc,&Info);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

(3)添加线程处理函数。

UINT ThreadFunc(LPVOID lpParam)
{
	threadInfo* pInfo=(threadInfo*)lpParam;
	CRect rect = pInfo->rect;// 矩形类
	HDC hdc = pInfo->hdc;                      // 获取设备上下文句柄

	VideoProcessor processor;
	processor.setInput(0);
	processor.displayInputParam("input", hdc, &rect);

	processor.run();
	
	return 0;
}

4、测试。

MFC+OpenCV打开摄像头_第1张图片



四、运动检测

1、添加线程类CBgFg。

2、添加对话框,并添加该对话框的类。

3、重载线程类的InitInstance()函数和ExitInstance()。

4、测试。如下图:




五、暂停/恢复视频线程

主要是使用SuspendThread()和ResumeThread()

1、添加按钮

2、在按钮的代码里添加:

      挂起pThread->SuspendThread(); 

      恢复 pThread->ResumeThread();



注意遇到的问题:

1、Error 1 error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in bvpmeasure.obj

        这个 value ‘0’、value '2' 还是容易解决,一般就是用Release模式去链接了一个Debug编译出的lib,或者用Debug模式链接了Release编译的lib。调整相应的lib版本即可。

2、1>LIBCMT.lib(invarg.obj) : error LNK2005: ___pInvalidArgHandler 已经在 LIBCMTD.lib(invarg.obj) 中定义
1>LINK : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library

       解决办法:链接器->输入->忽略特定默认库: libcmt.lib

你可能感兴趣的:(mfc,opencv,静态编译)