C++摄像头视频捕捉程序

合集下载

CCaptureVideo类的bug以及修改方法

CCaptureVideo类的bug以及修改方法

usb廉价摄像头抓取实时视频数据,呵呵,这可是一个非常不错视频开发试验。

通过这个试验,可以在学习中体验视频给我们带来的乐趣。

网上常用的是CCaptureVideo类,来处理usb摄像头数据捕获和读取。

我也用的是这个类来在win32环境下面做做试验。

很好用,而且很轻松就得到了usb摄像头的实时数据。

但是这个类就是十全十美的吗?我看不见得。

比如说,我直接定义CCaptureVideo的一个对象,没有调用它的init()函数,即没有调用它来获取视频数据,程序退出的时候会抛出异常。

经过检查才发现原来m_pBF要不就是m_pGB 没有初始化成NULL。

这是一个很低级的错误拉,不过很容易就可以修改过来。

这样哪怕你不使用这个类,只是声明一个对象,那么程序推出的时候也不会出现什么异常。

刚刚那个是比较明显的bug了,还有一些不太明显的。

不知道大家在使用CCaptureVideo类的时候是否遇见过。

例如,我们可能希望按下某个按钮的时候开始摄像头视频捕捉,再按一次,就停止视频捕捉;然后如果需要,那么再次重复按下该按钮,再次重新启动视频捕捉,这就好比qq的视频聊天一样,qq主程序没有关掉,但是你可以在不同的时间段和不同的人视频聊天。

简单的描述就是在不关闭主程序的前提下进行:打开摄像头--->关闭摄像头--->再打开摄像头--->再关闭摄像头--->再打开摄像头...等等以此类推。

对于网上流传的CCaptureVideo类而言,它是有问题的,假设我们声明了一个CCaptureVideo类的指针CCaptureVideo * m_cap ;然后,在OnInitDialog函数中创建该对象,m_cap = new CCaptureVideo() ;然后就是例牌的枚举可用摄像头(m_cap->EnumDevices (m_cam_lst);),或者直接调用init函数(m_cap->Init(m_cam_lst.GetCurSel (),hWnd);),开始捕获视频数据。

OpenCV实现简单摄像头视频监控程序

OpenCV实现简单摄像头视频监控程序

OpenCV实现简单摄像头视频监控程序如何在冗长的监控录像中找到关键点?我们知道,监控录像中⼤部分信息都是没⽤的,那些信息就等同于⼀幅静态图像。

我们要等待监控的范围内出现异常情况时再跟踪。

这其实是⼀个最简单的计算机图像处理程序。

简单的思路是这样的:⾸先给摄像头取景采样,当背景稳定时,以该图⽚作为基准图⽚。

然后在监控过程中,若出现了和基准图⽚反差较⼤的视频帧,那么启动捕捉程序,并标出异常区域。

程序如下:#include <cv.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <highgui.h>#define ESC 0x1b#define TRUE 1#define FALSE 0// 检测图像异常,仅在采样时调⽤。

// 返回真表⽰已检测到异常,需要重新采样。

// 返回假表⽰未检测到异常,在⼀定时间后即可获取基准图像。

int detect(CvCapture* capture, IplImage* std, IplImage* frm, CvRect* rect);// 图像采样,确定基准图像,以便监测场景变化// 返回真表⽰采样成功,返回假表⽰采样失败int gather(CvCapture* capture, IplImage* std, CvRect* rect);// 摄像机监视,⽤矩形框标⽰出和基准图像反差较⼤的图像范围。

void monitor(CvCapture* capture, IplImage* std, CvRect* rect);// 求 x 的平⽅int square(int x);int main(int argc, char* argv[]){CvCapture* capture; // 摄像机源IplImage* std; // 基准图像CvRect rect; // 异常位置矩形标识capture = cvCreateCameraCapture(0);if (!capture) return -1;std = cvQueryFrame(capture);rect = cvRect(-1, -1, 0, 0);std = cvCloneImage(std);cvNamedWindow("Monitor Screen");if (gather(capture, std, &rect)){monitor(capture, std, &rect);}cvDestroyWindow("Monitor Screen");cvReleaseImage(&std);cvReleaseCapture(&capture);return 0;}int detect(CvCapture* capture, IplImage* std, IplImage* frm, CvRect* rect){int x, y; // 循环变量int f = FALSE; // 检测到异常的标识int x1 = -1, x2 = 0; // 异常区域矩形横坐标范围int y1 = -1, y2 = 0; // 异常区域矩形纵坐标范围uchar *ptr1b, *ptr1g, *ptr1r; // 基准图像的每个像素的三个颜⾊通道的值uchar *ptr2b, *ptr2g, *ptr2r; // 实时图像的每个像素的三个颜⾊通道的值int squaresum; // 计算 RGB 差值平⽅和// 遍历图像中的每⼀个点,将实时采样图与基准图做⽐较,检测两者的每⼀个 // 像素点的 RGB 差值平⽅和。

用VC++实现网络摄像头视频捕获的研究

用VC++实现网络摄像头视频捕获的研究

辱扔金?触电.I;蕾.兀、^、(。

l^JCOMpITEROFIIL^、、、应用技术2009年4月10rj第4期用VC++实现网络摄像头视频捕获的研究■黄冈师范学院陈文灿朱泽民摘要:本文介绍了微软发布的数字视频软件包vFw及Vc++对VFM的支持,给出了网络摄像头视频捕获的一般流程,并详细介绍了其中的一些关键步骤。

关键词:V刚;AVlCap;VC++一、引言数字视频的获得是视频会议、可视电话、视频监控系统等多媒体应用的前提。

目前进行多媒体视频开发的主流技术有DirectShow、微软推】}f{的VFw和第i方提供的软件包。

然而,DireetShow组件较为复杂,不容易掌握;第i方软件包虽然简单实用,但由于只提供给编程人员编译好的动态链接库和一些接口。

其内部的实现埘于编程人员来说是一个黑盒子,不利于编程人员核心技术水平的提升。

微软数字视频软件包vFw提供的高级编程接口大大降低了多媒体音频视频开发的难度,编程人员不必对音频视频底层有较深入的了解就可进行编程。

同tj,l-,VisualC++开发平台对VFW也提供r较好的支持。

二、关键技术简介(一)VFW介绍vFW是VideoForWindows的简写,是Mi—crosoft1992年推,f{的一个关于数字视频的软件包,它能使应用程序数字化并播放从传统模拟视频源得到的视频剪辑。

vFw给程序员提供VBX和AVICap窗口类的高级编程工具,使程序员能够通过发送消息或设置属性来捕获、播放和编辑视频剪辑。

用户不必专门安装vFw,在安装Windows操作系统时,安装程序会自动地配置视频所需要的组件,如设备驱动程序和视频压缩程序。

VFW主要南6个模块组成,各模块之间的关系可参考图l。

其中1.AVICAP.I)1.I.包含r执行视频捕获的两数。

它给AVI文件、I/O和视频音频设备驱动程序提供了一个高级接口;2.MSVIDEO.DLL用一套特殊的DrawDib函数来处理屏幕上的视频操作;3.MCIAVI.I)RV是驱动程序,包括对VFw的MCI命令的解释器;4.AV…I。

c语言摄像头的编程_概述及解释说明

c语言摄像头的编程_概述及解释说明

c语言摄像头的编程概述及解释说明1. 引言1.1 概述:本文将介绍C语言摄像头编程的相关知识和技巧。

随着科技的不断进步,摄像头已经成为了我们生活中不可或缺的一部分。

而通过编程控制摄像头,可以实现各种有趣和实用的功能。

本文将引导读者从基础知识开始,逐步深入了解C语言与摄像头的通信方式、驱动选择与安装、图像采集、处理与分析等方面的内容。

1.2 文章结构:本文共分为五个主要部分: 引言、C语言摄像头编程基础知识、C语言中使用摄像头进行图像采集、C语言中对摄像头图像进行处理与分析以及结论和展望。

在引言部分,我们将对整篇文章进行概述,并介绍每个部分所涵盖的内容。

1.3 目的:本文旨在提供给读者一个全面而系统的了解C语言摄像头编程的指南。

通过理论讲解和实践案例,读者可以学习到如何使用C语言控制和操作摄像头,并利用其功能进行各种图像采集、处理与分析任务。

此外,本文还会对未来C语音摄像头编程的发展进行展望,为读者提供一个前景的思考角度。

以上是“1. 引言”部分的内容。

接下来,我们将逐一介绍文章其他章节的具体内容。

2. C语言摄像头编程基础知识:摄像头是一种用于捕捉图像或视频的设备,它在现代计算机应用中扮演着重要的角色。

C语言是一种广泛使用的编程语言,可以与摄像头进行通信并控制其功能。

2.1 摄像头原理简介:摄像头通过感光元件将光线转换为电信号,并通过图像处理器将电信号转换为数字图像或视频。

常见的摄像头类型包括USB摄像头、网络摄像头和嵌入式摄像头。

它们可以用于各种应用领域,如视频会议、安防监控和电子眼镜等。

2.2 C语言与摄像头的通信方式:C语言可以通过调用操作系统提供的API来与摄像头进行通信。

对于不同类型的摄像头,可能需要使用不同的库或驱动程序来访问其功能。

例如,对于USB摄像头,可以使用v4l库(Video for Linux);而对于网络摄像头,则可以使用libcurl 库进行远程访问。

2.3 摄像头驱动的选择与安装:在使用C语言进行摄像头编程之前,需要确定合适的驱动程序以确保正确地连接和控制相机。

VC捕捉摄像头图像入门源码(非常适合新手)

VC捕捉摄像头图像入门源码(非常适合新手)

//此源码是我更改过的基于VFW(Video for Windows)的源码,使用了定时器能实时的显示图像,从网上可搜到原版源码,但是原版的功能是保存为一个文件,且不能实时显示,此版本虽然能显示,但感觉反应速度不是很快,没有基于DirectShow的程序更新速度快,不过在WM_PAINT消息处理里加while(1){capGrabFrame(ghWndCap);}刷新速度就快很多了,但是这样程序就进入死循环不能再处理其他消息,至于怎样改进,就靠读者你了。

//源码的任何部分都可以在MSDN里查到,请参考MSDN。

#include <windows.h>#include <stdio.h>#include <vfw.h>#pragma comment(lib,"vfw32.lib")HWND ghWndCap ; //捕获窗的句柄CAPSTATUS gCapStatus ; //捕获窗的状态CAPDRIVERCAPS gCapDriverCaps ; //视频驱动的能力char gachBuffer[20];//char szCaptureFile[] = "CamCapture.AVI";///////////////////////////////////////////////////////////////////// //// StatusCallbackProc: 状态回调函数,使用capSetCallbackOnStatus宏来注册这个回调函数。

// hWnd: 捕获窗体句柄// nID: 当前状态的状态码// lpStatusText: 当前状态的文本字符///////////////////////////////////////////////////////////////////// //LRESULT CALLBACK StatusCallbackProc(HWND hWnd,int nID,LPSTR lpStatusText){if(!ghWndCap)return FALSE;//获得捕获窗的状态capGetStatus(ghWndCap,&gCapStatus,sizeof(CAPSTATUS));//更新捕获窗的大小,得到消息WM_CAP_GET_STATUSSetWindowPos(ghWndCap,NULL,0,0,gCapStatus.uiImageWidth,gCapStatus.uiI mageHeight,SWP_NOZORDER|SWP_NOMOVE);if(nID==0){//清除旧的状态信息SetWindowText(ghWndCap,(LPSTR)"hello");return (LRESULT)TRUE;}//显示状态ID和状态文本wsprintf(gachBuffer,"Status# %d: %s",nID,lpStatusText); SetWindowText(ghWndCap,(LPSTR)gachBuffer);return (LRESULT)TRUE;}///////////////////////////////////////////////////////////////////// /////////// ErrorCallbackProc: 错误回调函数,过capSetCallbackOnError宏来注册回调// hWnd: 捕获窗口句柄// nErrID: 错误代码// lpErrorText: 关于错误的文本信息///////////////////////////////////////////////////////////////////// //////////LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int nErrID,LPSTR lpErrorText){if(!ghWndCap)return FALSE;if(nErrID==0)return TRUE;//清除旧的错误wsprintf(gachBuffer,"Error# %d",nErrID);//显示错误标识和文本MessageBox(hWnd, lpErrorText, gachBuffer,MB_OK | MB_ICONEXCLAMATION); return (LRESULT) TRUE;}///////////////////////////////////////////////////////////////////// /////////// FrameCallbackProc: 帧回调函数,通过capSetCallbackFrame宏来注册回调函数// hWnd: 捕获窗体句柄// lpVHdr: 指向一个包含帧信息的数据结构体///////////////////////////////////////////////////////////////////// ////////////LRESULT CALLBACK FrameCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr){FILE *fp;fp=fopen("caram.dat","w");if(!ghWndCap)return FALSE;//假设fp为一打开的.dat文件指针fwrite(lpVHdr->lpData,1,lpVHdr->dwBufferLength,fp);return (LRESULT)TRUE;}///////////////////////////////////////////////////////////////////// ///////////TimerProc函数处理定时器,在这里抓取并显示图像///////////////////////////////////////////////////////////////////// /////////VOID CALLBACK TimerProc(HWND hwnd, // handle to windowUINT uMsg, // WM_TIMER messageUINT_PTR idEvent, // timer identifierDWORD dwTime // current system time){capGrabFrame(ghWndCap);}////////////////////////////////////////////////////////////////////主回调函数////////////////////////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter){// HDC hdc;// PAINTSTRUCT ps;// RECT rect;switch(uMsg){case WM_CREATE:ghWndCap=capCreateCaptureWindow((LPSTR)"Capture Window",WS_CHILD|WS_VISIBLE,0,0,320,240,(HWND)hwnd,(int)0);capSetCallbackOnError(ghWndCap,(FARPROC)ErrorCallbackProc);capSetCallbackOnStatus(ghWndCap,(FARPROC)StatusCallbackProc);capSetCallbackOnFrame(ghWndCap,(FARPROC)FrameCallbackProc);capDriverConnect(ghWndCap,0); // 将捕获窗同驱动连接capDriverGetCaps(ghWndCap,&gCapDriverCaps,sizeof(CAPDRIVERCAPS));/ /获得驱动的能力,相关的信息放在结构变量gCapDriverCaps中capPreviewRate(ghWndCap, 66); //uses this macro to set the frame display rate for preview mode to 66 milliseconds per framecapPreview(ghWndCap, TRUE); //and then uses the capPreview macro to place the capture window in preview mode.if(gCapDriverCaps.fHasOverlay) //检查驱动器是否有叠加能力capOverlay(ghWndCap,TRUE); //启动Overlay模式if(gCapDriverCaps.fHasDlgVideoSource)capDlgVideoSource(ghWndCap); //Video source 对话框if(gCapDriverCaps.fHasDlgVideoFormat)capDlgVideoFormat(ghWndCap); // Video format 对话框if(gCapDriverCaps.fHasDlgVideoDisplay)capDlgVideoDisplay(ghWndCap); // Video display 对话框// capFileSetCaptureFile( ghWndCap, szCaptureFile); //将要保存的文件名设为本源文件开头处的全局字符串常量// capFileAlloc(ghWndCap, (1024L * 1024L * 5)); //为捕获文件分配存储空间capCaptureSequence(ghWndCap); //开始捕获视频序列// capGrabFrame(ghWndCap); //捕获单帧图像SetTimer(hwnd,1,10,TimerProc);break;case WM_PAINT:capGrabFrame(ghWndCap);/* hdc=BeginPaint(hwnd,&ps);GetClientRect(hwnd,&rect);DrawText(hdc,TEXT("Hello,Windows XP!"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);EndPaint(hwnd,&ps);*/break;case WM_CLOSE:if(IDYES==MessageBox(hwnd,"Sure exit ?","CamCapture",MB_YESNO)){DestroyWindow(hwnd);}break;case WM_DESTROY:KillTimer(hwnd,1);capSetCallbackOnStatus(ghWndCap,NULL);capSetCallbackOnError(ghWndCap,NULL);capSetCallbackOnFrame(ghWndCap,NULL);capCaptureAbort(ghWndCap);//停止捕获capDriverDisconnect(ghWndCap); //将捕获窗同驱动断开PostQuitMessage(0);break;default:return DefWindowProc(hwnd,uMsg,wParam,lParam);}return 0;}//主函数int WINAPI WinMain(HINSTANCE hInstance, // handle to current instanceHINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine, // command lineint nCmdShow // show state){static TCHAR szAppName[]=TEXT("CamCapture");WNDCLASS wndcls;HWND hwnd;MSG msg;wndcls.cbClsExtra=0;wndcls.cbWndExtra=0;wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);wndcls.hIcon=LoadIcon(NULL,IDI_QUESTION);wndcls.hInstance=hInstance;wndcls.lpfnWndProc=WindowProc;wndcls.lpszClassName="CamCapture";wndcls.lpszMenuName=NULL;wndcls.style=CS_HREDRAW | CS_VREDRAW;if(!RegisterClass(&wndcls)){MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);return 0;}hwnd=CreateWindow("CamCapture","CamCapture",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,320,240,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,nCmdShow);UpdateWindow(hwnd);while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return 0;}。

基于C的实时视频监控系统设计与实现

基于C的实时视频监控系统设计与实现

基于C的实时视频监控系统设计与实现随着科技的不断发展,视频监控系统在各个领域得到了广泛的应用,如公共安全、交通监控、工业生产等。

而实时视频监控系统则是其中一种应用较为广泛的形式,它可以实时地获取、传输、处理和显示监控区域的视频信息,为用户提供及时有效的监控服务。

本文将介绍基于C语言的实时视频监控系统设计与实现过程。

1. 系统需求分析在设计实时视频监控系统之前,首先需要明确系统的需求。

一般来说,实时视频监控系统需要具备以下功能:实时采集监控区域的视频数据实时传输视频数据至监控中心实时处理视频数据,如图像识别、运动检测等实时显示监控画面支持远程监控和管理2. 系统设计2.1 硬件设计实时视频监控系统的硬件设计包括摄像头、传感器、处理器等组件。

摄像头用于采集监控区域的视频数据,传感器用于获取环境信息,处理器则负责数据处理和传输。

2.2 软件设计基于C语言的实时视频监控系统软件设计主要包括以下几个模块:视频采集模块:负责从摄像头获取视频数据视频传输模块:负责将视频数据传输至监控中心视频处理模块:对视频数据进行处理,如图像识别、运动检测等视频显示模块:实时显示监控画面远程管理模块:支持远程监控和管理3. 系统实现3.1 视频采集模块实现视频采集模块可以使用开源库如OpenCV来实现。

通过OpenCV提供的接口,可以方便地从摄像头获取视频数据,并进行相关设置和参数调整。

示例代码star:编程语言:c#include <opencv2/opencv.hpp>int main() {cv::VideoCapture cap(0);if (!cap.isOpened()) {std::cerr << "Error: Cannot open camera" << std::endl;return -1;}cv::Mat frame;while (true) {cap >> frame;if (frame.empty()) {break;}// Process the frame herecv::imshow("Video", frame);if (cv::waitKey(30) >= 0) {break;}}cap.release();cv::destroyAllWindows();return 0;}示例代码end3.2 视频传输模块实现视频传输模块可以使用网络编程库如Socket来实现。

c++ 编写连接摄像头的通用方法

c++ 编写连接摄像头的通用方法【摄像头连接概述】在本文中,我们将介绍一种通用的C++编写连接摄像头的方法。

摄像头连接主要包括以下几个步骤:准备工作、实现通用连接方法、代码示例及解析、总结与拓展。

通过本文,读者可以了解到如何使用C++编写程序实现摄像头连接,并实现基本视频捕捉功能。

【准备工作】在进行摄像头连接之前,我们需要做好以下准备工作:1.安装适当的驱动程序:根据摄像头型号和操作系统,确保安装了正确的驱动程序。

2.导入必要的库:我们需要使用一些库来实现摄像头连接,如OpenCV。

在使用OpenCV之前,需要先安装相应版本的库文件。

3.配置开发环境:安装C++编译器,并配置好开发环境。

【实现通用连接方法】在C++中,我们可以使用以下通用方法连接摄像头:1.初始化库:引入OpenCV库,并初始化cv::VideoCapture对象。

2.打开摄像头:使用cv::VideoCapture::open()方法尝试打开摄像头。

3.检查摄像头是否成功打开:通过检查cv::VideoCapture对象的是否为null来判断摄像头是否成功打开。

4.释放资源:在程序结束时,释放摄像头资源,关闭cv::VideoCapture对象。

【代码示例及解析】以下是一个简单的C++代码示例,演示了如何实现摄像头连接:```cpp#include <iostream>#include <opencv2/opencv.hpp>int main() {// 初始化库cv::Mat frame;cv::VideoCapture cap(0); // 0表示默认摄像头// 检查摄像头是否成功打开if (!cap.isOpened()) {std::cout << "摄像头未打开,请检查摄像头是否正确连接。

" << std::endl;return -1;}// 循环捕获并显示画面while (true) {cap >> frame;if (frame.empty()) {std::cout << "未捕获到画面,请检查摄像头是否正常工作。

c#基于opencv,开发摄像头播放程序

c#基于opencv,开发摄像头播放程序前⾔Windows下实现摄像视频捕捉有多种实现⽅式;各种⽅式的优劣,本⽂不做对⽐。

但是,opencv是⼀款⽼牌开发库,在图像处理领域声名显赫。

采⽤opencv来处理摄像视频,在性能和稳定性上,是有保障的。

并且,opencv包含很多图像处理函数,可以更⽅便的对视频处理。

执⾏程序是⽤wpf开发的,所以先将opencv封装成c语⾔接⼝,以供调⽤。

opencv也不可能提供现成的控件供wpf使⽤,两种不同的开发语⾔“沟通”起来有些困难。

其实稍作变通,就可以实现摄像头播放功能。

1 对opencv封装opencv的类VideoCapture封装了对摄像头的操作,使⽤起来也⾮常简单。

bool open(int device); device为摄像头设备序号。

如果有多个摄像头,怎么知道哪个摄像头的序号那?可以通过如下函数,获取摄像头列表。

摄像头在list中索引即为设备序号。

int GetCameraDevices(vector<wstring>& list){ICreateDevEnum *pDevEnum = NULL;IEnumMoniker *pEnum = NULL;int deviceCounter = 0;CoInitialize(NULL);HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,reinterpret_cast<void**>(&pDevEnum));if (SUCCEEDED(hr)){// Create an enumerator for the video capture category.hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum, 0);if (hr == S_OK) {//if (!silent)printf("SETUP: Looking For Capture Devices\n");IMoniker *pMoniker = NULL;while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {IPropertyBag *pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,(void**)(&pPropBag));if (FAILED(hr)) {pMoniker->Release();continue; // Skip this one, maybe the next one will work.}// Find the description or friendly name.VARIANT varName;VariantInit(&varName);hr = pPropBag->Read(L"Description", &varName, 0);if (FAILED(hr))hr = pPropBag->Read(L"FriendlyName", &varName, 0);if (SUCCEEDED(hr)) {hr = pPropBag->Read(L"FriendlyName", &varName, 0);int count = 0;wstring str2 = varName.bstrVal;list.push_back(str2);}pPropBag->Release();pPropBag = NULL;pMoniker->Release();pMoniker = NULL;deviceCounter++;}pDevEnum->Release();pDevEnum = NULL;pEnum->Release();pEnum = NULL;}}return deviceCounter;}总之,使⽤opencv打开摄像头⾮常简单。

基于C++的摄像头图像采集及拼接程序的简单实现

基于C++的摄像头图像采集及拼接程序的简单实现程序的说明实现从摄像头实时采集单帧图像,之后完成图像的拼接,本程序实现了两张图⽚的拼接和三张图⽚的拼接。

在此之前你需要在 linux 下安装 opencv Package 这个包,因为本程序主要使⽤ opencv 这个包中提供的 api 函数。

实现从摄像头实时不同视⾓采集视频的单帧图像并保存实时采集的视频⽂件之后,完成图像的拼接,由于实验室设备有限,⼿头只有两个摄像头⼀次只能抓取。

两张不同视⾓的单帧图像,我们抓取的单帧图像保存在当前项⽬⽬录下的 frame1 和 frame2 ⽂件夹中,因此我同时制作了两个完成程序。

拼接的程序,⼀个实现完成两个不同视⾓的图像拼接,另⼀个实现三张不同视⾓的单帧图像的拼接。

其中的 testusb.cpp ⽂件是测试摄像头的程序。

在执⾏本程序前,你应该保证有两个是摄像头插在主机端⼝上,⽤于实时采集单帧图像。

代码介绍在进⾏程序的编译前,请确定你已经安装了 opencv2.4.9 和 pkg-config 包,本程序是在 ubuntu14.04 平台下实现的,在本项⽬⽬录下,已经有编译⽣成的可执⾏程序,其中 Camera_to_Frmae.cpp 是我们从双摄像头实时抓取单帧图像的源码。

ImageJoint.cpp 和 ImageJoint2.cpp、ImageJoint3.cpp 分别是完成两张不同视⾓的图像拼接和三张不同视⾓的图像拼接程序,其中三张图像拼接的图像是我从⽹上找的现成的图像库testusb.cpp 是我测试摄像头的程序程序编译g++ -o dst src.cpp \`pkg-config opencv --cflags --libs\`程序的执⾏和退出./dst程序需要退出时,按 Ctrl + C 快捷键效果从摄像头设备采集两张单帧图像图像拼接效果图补充:c++利⽤opencv打开摄像头并且保存图⽚项⽬背景利⽤⼀个usb双⽬摄像机进⾏双⽬测距的项⽬,这个项⽬代码有助于使⽤usb双⽬摄像机打开摄像机并且保存图⽚打开双⽬相机的函数void SetCam(int weigth, int height, int num){string a = "0";string Error;VideoCapture Cam(0);/*设定缓冲区⼤⼩*/Cam.set(CV_CAP_PROP_FRAME_WIDTH, weigth);Cam.set(CV_CAP_PROP_FRAME_HEIGHT, height);while (!Cam.isOpened()){a = to_string(num);Error = "cannot open the camera1!";Error = Error.replace(22, 1, a);//Error.copy(error, 24, 0);//这⾥5代表复制⼏个字符,0代表复制的位置,}//namedWindow("摄像头");//关键⼀句代码while (true) {Cam >> input_image;//将影像传⼊图⽚leftImage = input_image(Rect(0, 0, input_image.size().width / 2, input_image.size().height));//split left imagerightImage = input_image(Rect(input_image.size().width / 2, 0, input_image.size().width / 2, input_image.size().height));imshow("leftImage", leftImage);//left imageimshow("rightImage", rightImage);//right imageSave(i, 20);if (27 == waitKey(30))break;return ;}保存图⽚函数Savevoid Save(int &imgnum, int amount){if (imgnum < amount){a = to_string(imgnum);seat = floor((imgnum - 1) / 10);Left = Left.replace(4 + seat, 1, a);Right = Right.replace(5 + seat, 1, a);imwrite(Left, leftImage);imwrite(Right, rightImage);imgnum += 1;}}全部代码#include <opencv2/opencv.hpp>#include<iostream>using namespace cv;using namespace std;VideoCapture Cam1, Cam2;const int weigth = 1280;const int height = 480;static string Left = "Left0.jpg", Right = "Right0.jpg", a = "0";static int seat = 0;static Mat input_image, leftImage, rightImage;static int i = 0;void Save(int &imgnum, int amount){if (imgnum < amount){a = to_string(imgnum);seat = floor((imgnum - 1) / 10);Left = Left.replace(4 + seat, 1, a);Right = Right.replace(5 + seat, 1, a);imwrite(Left, leftImage);imwrite(Right, rightImage);imgnum += 1;}}void SetCam(int weigth, int height, int num)string a = "0";string Error;VideoCapture Cam(0);/*设定缓冲区⼤⼩*/Cam.set(CV_CAP_PROP_FRAME_WIDTH, weigth);Cam.set(CV_CAP_PROP_FRAME_HEIGHT, height);while (!Cam.isOpened())a = to_string(num);Error = "cannot open the camera1!";Error = Error.replace(22, 1, a);//Error.copy(error, 24, 0);//这⾥5代表复制⼏个字符,0代表复制的位置,//namedWindow("摄像头");//关键⼀句代码while (true) {Cam >> input_image;//将影像传⼊图⽚leftImage = input_image(Rect(0, 0, input_image.size().width / 2, input_image.size().height));//split left imagerightImage = input_image(Rect(input_image.size().width / 2, 0, input_image.size().width / 2, input_image.size().height));imshow("leftImage", leftImage);//left imageimshow("rightImage", rightImage);//right imageSave(i, 20);if (27 == waitKey(30))break;return ;void main()//char* error = "error";SetCam(weigth, height, 10);到此这篇关于基于C++的摄像头图像采集及拼接程序的实现的⽂章就介绍到这了,更多相关C++摄像头图像采集内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

VC++编写摄像头录制系统

VC++编写基于摄像头录制系统首先编写该程序之前,必须要用到微软公司给我们提供的音视频函数库vfw。

VFW(Video for Windows)是Microsoft推出的关于数字视频的一个软件开发包,VFW 的核心是AVI文件标准。

AVI(Audio Video Interleave)文件中的音、视频数据帧交错存放。

围绕AVI文件,VFW推出了一整套完整的视频采集、压缩、解压缩、回放和编辑的应用程序接口(API)。

由于AVI文件格式推出较早且在数字视频技术中有广泛的应用,所以VFW仍然有很大的实用价值,而且进一步发展的趋势。

在VC++开发环境中调用VFW和使用其它开发包没有什么不同,只是需要将VFW32.lib 文件加入工程中,但在开放视频捕捉与压缩管理程序时需要其它软件硬件设置。

VFW为AVI 文件提供了丰富的处理函数和宏定义,AVI文件的特点在于它是典型的数据流文件,它由视频流、音频流、文本流组成。

所以对AVI文件的处理主要是处理文件流。

废话不多说了:本程序主要由底层的vc++ ApI函数实现:今后该程序会转换成基于MFC 的源代码开发。

首先用新建Win32程序,建立一个空项目:编写一个摄像头录制系统应用程序,代码如下:在新建的一个头文件和.cpp文件取名为VCaper.h,VCaper.cpp。

把vfw.lib文件库导入到程序中。

头文件写入一些宏定义资源:#define SELCAPDRVDLG 100#define SELCAPDRVDLG_LSTBOX 101#define SELCAPDRVDLG_BUTTON 103#define EXIT 104#define HELP 105#define MINIMIZE 106#define MOVE 107#define CONNECT 113#define BUTTONSIZE 15#define PHOTO 114#define RECORDVIDEO 115#define COPY 116#define SOURCE 117#define FORMAT 118#define DISPLAY 119VCaper.cpp文件实现代码如下:#include<windows.h> //windows编程代码#include <vfw.h>// 视频库#include <string>#include <commdlg.h>// common dialogs#include "VCaper.h"// resource header#include <stdio.h>//字符串函数//#include "oldeb.h"//字符串函数LRESULT WINAPI MainWndProc( HWND, UINT, WPARAM, LPARAM ); // 选择捕捉程序驱动程序LRESULT WINAPI SelCapDrvProc( HWND, UINT, WPARAM, LPARAM );// 列举捕捉驱动int EnumCapDrv();// 在主窗口创建按钮VOID APIENTRY HandlePopupMenu(HWND, POINT);// 右键弹出菜单句柄DWORD WINAPI videoThreadProc(LPVOID lParam);// 视频程序线程/******************* 全程变量********************/HANDLE ghInstance;// 应用程序实例HWND hwndMain; // 主要窗口句柄HWND hwndVideo;// 视频捕捉窗口句柄HWND hwndSelCapDrvDlg;// 选择捕捉驱动对话句柄HWND hwndSelCapDrvDlg_LBox;// 选择捕捉驱动对话列举框句柄HWND hwndExit;// 退出按钮HWND hwndMin;// 最小化按钮HWND hwndHelp; // 帮助按钮HWND hwndRecord;// 录像按钮HWND hwndPhoto;// 快照按钮HWND hwndSource;//视频源选项HWND hwndFormat;//视频格式御览HWND hwndConnect;//数据块连接HANDLE hVideoThread;// 停止录取视频线程HRGN hRegion1;// 窗口修正区域CAPDRIVERCAPS CapDrvCaps;// 驱动性能bool isRecordFileOpen = false;// 录像开始标记bool isPhotoFileOpen = false;//照相开始标记char recordFile[260];// 保持录像标记char photoFile[260];// 保持照相标记bool isPicFileOpen = false;// flag set if snapshot file is openchar pictureFile[260];// file to hold snapshotbool isRecording = false;// 判断是否录像bool threadEnd = false;// 判断视频线程是否终止/********************************************************************\* Function: int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int) ** ** 用途: 应用程序初始化** ** 注释: 注册窗口类, 创建显示主要窗口, 进入消息循环** ** *\********************************************************************/int PASCAL WinMain( HINSTANCE hInstance,//HINSTANCE:实例的句柄(Handle to an instance)HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int nCmdShow ){WNDCLASS wc;//WNDCLASS结构包含了RegisterClass函数注册窗口类时的窗口类属性MSG msg;//如果不是前实例if( !hPrevInstance ){wc.lpszClassName = "GenericAppClass";wc.lpfnWndProc = MainWndProc;//函数名代表首地址,指定一个回调函数wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;wc.hInstance = hInstance;wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );wc.hCursor = LoadCursor( NULL, IDC_ARROW );wc.hbrBackground = CreateSolidBrush (RGB(200, 200,100));wc.lpszMenuName = "GenericAppMenu";wc.cbClsExtra = 0;wc.cbWndExtra = 0;RegisterClass( &wc );//注册窗口类}ghInstance = hInstance;hwndMain = CreateWindow( "GenericAppClass",//该函数创建一个重叠式窗口、弹出式窗口或子窗口。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Visual C++编程实现摄像头视频捕捉摘要:本文主要讲述用Directshow进行视频捕捉(捕捉静态图像)的编程思路,并提供针对摄像头编程的一个视频捕捉类CcaptureVideo和一个示例。

前言DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。

DirectShow为多媒体流的捕捉和回放提供了强有力的支持。

用DirectShow开发应用程序,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。

DirectShow是基于COM的,为了编写DirectShow应用程序,需要了解COM客户程序编写的基础知识。

DirectShow提供了大量的接口,但在编程中发现还是不够方便,如果能构建一个视频捕捉类把常用的一些动作封装起来,那么就更方便了。

编程思路为了更加容易建立视频捕捉应用程序,DirectShow提供了一个叫做Capture Graph Builder的对象,Capture Graph Builder提供IcaptureGraphBuilder2接口,该接口可以建立和控制Capture Graph。

建立视频捕捉程序,必须首先获取并初始化IcaptureGraphBuilder2接口,然后选择一个适当的视频捕捉设备。

选择好设备后,为该设备创建Capture filter,然后调用AddFilter 把Capture filter添加到Filter Graph。

如果仅仅希望用摄像头来进行实时监控的话,只需要在上面的基础上调用ICaptureGraphBuilder2::RenderStream就可以了:ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder//省略初始化部分代码IBaseFilter *pCap; // Video capture filter.//省略初始化和添加到Filter Graph部分代码pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);DirectShow提供了一个捕捉静态图像的方法:使用Sample Grabber filter。

依次按照以下三个步骤就可以了:第一步, 定义一个类实现Sample Grabber的回调接口IsampleGrabberCB:class CSampleGrabberCB : public ISampleGrabberCB{//在后面提供的类中具体完成}CSampleGrabberCB mCB;第二步、调用RenderStream依次把Still pin、Sample Grabber和系统默认Renderer Filter连接起来。

第三步、配置Sample Grabber以捕获数据。

视频捕捉类CCaptureVideo的具体实现// CCaptureVideo视频捕捉类头文件/////////////////////////////////////////////////////////////////////#if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED _)#define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_/////////////////////////////////////////////////////////////////////// CaptureVideo.h : header file/////////////////////////////////////////////////////////////////////#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include <atlbase.h>#include <windows.h>#include <dshow.h>#ifndef SAFE_RELEASE#define SAFE_RELEASE( x ) \if ( NULL != x ) \{ \x->Release( ); \x = NULL; \}#endifclass CSampleGrabberCB;class CCaptureVideo : public CWnd{friend class CSampleGrabberCB;public:void GrabOneFrame(BOOL bGrab);HRESULT Init(int iDeviceID,HWND hWnd);int EnumDevices(HWND hList);CCaptureVideo();virtual ~CCaptureVideo();private:HWND m_hWnd;IGraphBuilder *m_pGB;ICaptureGraphBuilder2* m_pCapture;IBaseFilter* m_pBF;IMediaControl* m_pMC;IVideoWindow* m_pVW;CComPtr<ISampleGrabber> m_pGrabber;protected:void FreeMediaType(AM_MEDIA_TYPE& mt);bool BindFilter(int deviceId, IBaseFilter **pFilter);void ResizeVideoWindow();HRESULT SetupVideoWindow();HRESULT InitCaptureGraphBuilder();};#endif// !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_) //-------------------------------------------------------------------// CCaptureVideo视频捕捉类实现文件CaptureVideo.cpp//-------------------------------------------------------------------// CaptureVideo.cpp: implementation of the CCaptureVideo class.///////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "CaptureVideo.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endifBOOL bOneShot=FALSE;//全局变量class CSampleGrabberCB : public ISampleGrabberCB{public:long lWidth;long lHeight;TCHAR m_szFileName[MAX_PATH];// 位图文件名称CSampleGrabberCB( ){strcpy(m_szFileName, "c:\\donaldo.bmp");}STDMETHODIMP_(ULONG) AddRef() { return 2; }STDMETHODIMP_(ULONG) Release() { return 1; }STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );return NOERROR;}return E_NOINTERFACE;}STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){return 0;}STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){ if( !bOneShot )return 0;if (!pBuffer)return E_POINTER;SaveBitmap(pBuffer, lBufferSize);bOneShot = FALSE;return 0;}//创建位图文件BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize ){HANDLE hf = CreateFile(m_szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,CREATE_ALWAYS, NULL, NULL );if( hf == INVALID_HANDLE_VALUE )return 0;// 写文件头BITMAPFILEHEADER bfh;memset( &bfh, 0, sizeof( bfh ) );bfh.bfType = ’MB’;bfh.bfSize = sizeof( bfh ) + lBufferSize + sizeof( BITMAPINFOHEADER );bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );DWORD dwWritten = 0;WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );// 写位图格式BITMAPINFOHEADER bih;memset( &bih, 0, sizeof( bih ) );bih.biSize = sizeof( bih );bih.biWidth = lWidth;bih.biHeight = lHeight;bih.biPlanes = 1;bih.biBitCount = 24;WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );// 写位图数据WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );CloseHandle( hf );return 0;}};CSampleGrabberCB mCB;////////////////////////////////////////////////////////////////////// // Construction/Destruction////////////////////////////////////////////////////////////////////// CCaptureVideo::CCaptureVideo(){//COM Library Intializationif(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/ {AfxMessageBox("CoInitialize Failed!\r\n");return;}m_hWnd = NULL;m_pVW = NULL;m_pMC = NULL;m_pGB = NULL;m_pCapture = NULL;}CCaptureVideo::~CCaptureVideo(){// Stop media playbackif(m_pMC)m_pMC->Stop();if(m_pVW){m_pVW->put_Visible(OAFALSE);m_pVW->put_Owner(NULL);}SAFE_RELEASE(m_pCapture);SAFE_RELEASE(m_pMC);SAFE_RELEASE(m_pGB);SAFE_RELEASE(m_pBF);CoUninitialize( );}int CCaptureVideo::EnumDevices(HWND hList){if (!hList)return -1;int id = 0;//枚举视频扑捉设备ICreateDevEnum *pCreateDevEnum;HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);if (hr != NOERROR)return -1;CComPtr<IEnumMoniker> pEm;hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);if (hr != NOERROR)return -1;pEm->Reset();ULONG cFetched;IMoniker *pM;while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK){IPropertyBag *pBag;hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);if(SUCCEEDED(hr)){VARIANT var;var.vt = VT_BSTR;hr = pBag->Read(L"FriendlyName", &var, NULL);if (hr == NOERROR){TCHAR str[2048];id++;WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);SysFreeString(var.bstrVal);}pBag->Release();}pM->Release();}return id;}HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd){HRESULT hr;hr = InitCaptureGraphBuilder();if (FAILED(hr)){AfxMessageBox("Failed to get video interfaces!");return hr;}// Bind Device Filter. We know the device because the id was passed inif(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");// hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,// m_pBF, NULL, NULL);// create a sample grabberhr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );if( !m_pGrabber ){AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");return hr;}CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber );//设置视频格式AM_MEDIA_TYPE mt;ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));mt.majortype = MEDIATYPE_Video;mt.subtype = MEDIASUBTYPE_RGB24;hr = m_pGrabber->SetMediaType(&mt);if( FAILED( hr ) ){AfxMessageBox("Fail to set media type!");return hr;}hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );if( FAILED( hr ) ){AfxMessageBox("Fail to put sample grabber in graph");return hr;}// try to render preview/capture pinhr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,m_pBF,pGrabBase,NULL);if( FAILED( hr ) )hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pBF,pGrabBase,NULL);if( FAILED( hr ) ){AfxMessageBox("Can’t build the graph");return hr;}hr = m_pGrabber->GetConnectedMediaType( &mt );if ( FAILED( hr) ){AfxMessageBox("Failt to read the connected media type");return hr;}VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;mCB.lWidth = vih->bmiHeader.biWidth;mCB.lHeight = vih->bmiHeader.biHeight;FreeMediaType(mt);hr = m_pGrabber->SetBufferSamples( FALSE );hr = m_pGrabber->SetOneShot( FALSE );hr = m_pGrabber->SetCallback( &mCB, 1 );//设置视频捕捉窗口m_hWnd = hWnd ;SetupVideoWindow();hr = m_pMC->Run();//开始视频捕捉if(FAILED(hr)){AfxMessageBox("Couldn’t run the graph!");return hr;}return S_OK;}bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter){if (deviceId < 0)return false;// enumerate all video capture devicesCComPtr<ICreateDevEnum> pCreateDevEnum;HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);if (hr != NOERROR){return false;}CComPtr<IEnumMoniker> pEm;hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);if (hr != NOERROR){return false;}pEm->Reset();ULONG cFetched;IMoniker *pM;int index = 0;while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId){IPropertyBag *pBag;hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);if(SUCCEEDED(hr)){VARIANT var;var.vt = VT_BSTR;hr = pBag->Read(L"FriendlyName", &var, NULL);if (hr == NOERROR){if (index == deviceId){pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);}SysFreeString(var.bstrVal);}pBag->Release();}pM->Release();index++;}return true;}HRESULT CCaptureVideo::InitCaptureGraphBuilder(){HRESULT hr;// 创建IGraphBuilder接口hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&m_pGB);// 创建ICaptureGraphBuilder2接口hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **) &m_pCapture);if (FAILED(hr))return hr;m_pCapture->SetFiltergraph(m_pGB);hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);if (FAILED(hr))return hr;hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW);if (FAILED(hr))return hr;return hr;}HRESULT CCaptureVideo::SetupVideoWindow(){HRESULT hr;hr = m_pVW->put_Owner((OAHWND)m_hWnd);if (FAILED(hr))return hr;hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);if (FAILED(hr))return hr;ResizeVideoWindow();hr = m_pVW->put_Visible(OATRUE);return hr;}void CCaptureVideo::ResizeVideoWindow(){if (m_pVW){//让图像充满整个窗口CRect rc;::GetClientRect(m_hWnd,&rc);m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);}}void CCaptureVideo::GrabOneFrame(BOOL bGrab){bOneShot = bGrab;}void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt){if (mt.cbFormat != 0) {CoTaskMemFree((PVOID)mt.pbFormat);// Strictly unnecessary but tidiermt.cbFormat = 0;mt.pbFormat = NULL;}if (mt.pUnk != NULL) {mt.pUnk->Release();mt.pUnk = NULL;}}如何使用视频捕捉类CCaptureVideo构建CCaptureVideo类以后,使用就方便多了,我们在编程中只需要是要下面三个类成员函数就可以实现用摄像头进行视频捕捉:①int EnumDevices(HWND hList); //hList是下拉列表框的句柄,本函数用于枚举当前系统安装的所有视频捕捉设备②HRESULT Init(int iDe viceID,HWND hWnd);//iDeviceID是视频捕捉设备序号,hWnd 是视频捕捉窗口的句柄③void GrabOneFrame(BOOL bGrab);//调用GrabOneFrame(true)就可以捕获当前的静态图像并保存到硬盘上具体示例:用MFC AppWizard(exe)创建一个对话框应用程序,取名为ds,给对话框添加一个下拉列表框(IDC_COMBO1)、两个按钮(IDC_PHOTO、IDC_HAVEALOOK)和一个Picture 控件(ID:IDC_STATIC_SCREEN,Type: Rectangle,Color:Gray)。

相关文档
最新文档