分为两步:OpenCV获取摄像头数据+图像在Picture上显示

第一步:OpenCV获取摄像头数据

参考:http://www.cnblogs.com/epirus/archive/2012/06/04/2535190.html

http://blog.sina.com.cn/s/blog_6dbe9bdb0100nii7.html

http://blog.csdn.net/augusdi/article/details/8762961

#include "stdafx.h"
#include <atltime.h>
#include <highgui.h>
int main()
{
int c;
CTime time;
IplImage *img;
CvCapture* capture = cvCaptureFromCAM();
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
cvMoveWindow("mainWin", , );
while()
{
img=cvQueryFrame(capture);
cvShowImage("mainWin", img );
c=cvWaitKey();
//按 s 鍵儲存成 jpg 檔
if(c=='s'){
time = CTime::GetCurrentTime();
CStringA filename(time.Format(CString("%Y%m%d%H%M%S"))+".jpg");
cvSaveImage(filename,img);
}
//按 ESC 鍵離開
if(c == )
break;
}
cvReleaseImage(&img);
cvDestroyWindow("mainWin");
return ;
}

在这里,要介绍下这几个重要函数:

1.CvCapture

视频获取结构   typedef struct CvCapture CvCapture;

释放这个结构,使用函数cvReleaseCapture。

结构CvCapture 没有公共接口,它只能被用来作为视频获取函数的一个参数。这个是一个很重要的结构   以后无论是读取已有视频还是从摄像头获取都必须用到它。

2.cvCaptureFromCAM

CvCapture* cvCaptureFromCAM( int index );

参数:index     要使用的摄像头索引。如果只有一个摄像头或者用哪个摄像头也无所谓。

  函数给从摄像头的视频流分配和初始化CvCapture结构。目前在Windows下可使用两种接口:Video for Windows(VFW)和Matrox Imaging Library(MIL); Linux下也有两种接口:V4L和FireWire(IEEE1394)。

读摄像头用:CvCapture* capture=cvCaptureFromCAM(0);//参数也可以是-1,

读AVI文件演示用: CvCapture* capture=cvCaptureFromFile(“XXX.avi”);

cvCreateCameraCapture好像还没有什么区别。

3.cvQueryFrame

从摄像头或者文件中抓取并返回一帧

IplImage* cvQueryFrame( CvCapture* capture );
capture 视频获取结构。

函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。返回的图像不可以被用户释放或者修改。抓取后,capture被指向下一帧,可用cvSetCaptureProperty调整capture到合适的帧。

注意: cvQueryFrame返回的指针总是指向同一块内存。建议cvQueryFrame后拷贝一份。而且返回的帧需要FLIP后才符合OPENCV的坐标系。
若返回值为NULL,说明到了视频的最后一帧或失败!
指向同一块内存的证明详解:http://blog.sina.com.cn/s/blog_6d1fb09e0100wcm0.html

4.cvGrabFrame

从摄像头或者视频文件中抓取帧
int cvGrabFrame( CvCapture* capture );
函数cvGrabFrame从摄像头或者文件中抓取帧。被抓取的帧在内部被存储。这个函数的目的是快速的抓取帧,这一点对同时从几个摄像头读取数据的同步是很重要的。被抓取的帧可能是压缩的格式(由摄像头/驱动定义),所以没有被公开出来。如果要取回获取的帧,请使用cvRetrieveFrame。
cvQueryFrame 是函数 cvGrabFrame 和函数 cvRetrieveFrame 的组合调用,直接返回一幅图像。单独cvGrabFrame不能。
 
参考:http://blog.csdn.net/autumn20080101/article/details/7515520
程序示例:
int main( int argc, char** argv )
{
// if( argc == 2 && (pImg = cvLoadImage( argv[1], CV_LOAD_IMAGE_UNCHANGED)) != 0 )
// return 0;
CvCapture* capture = cvCaptureFromCAM(); // capture from video device #0
//CvCapture* capture = cvCaptureFromAVI("infile.avi");
IplImage* img = ;
//CVAPI(int) cvGrabFrame( CvCapture* capture ); cvNamedWindow("image",CV_WINDOW_AUTOSIZE);
char c=cvWaitKey();
while(c!=)
{
if(!cvGrabFrame(capture)){ // capture a frame
printf("Could not grab a frame\n\7");
exit();
}
//CVAPI(IplImage*) cvRetrieveFrame( CvCapture* capture );
img=cvRetrieveFrame(capture); // retrieve the captured frame cvShowImage("image",img);
c=cvWaitKey();
}
//由视频流捕捉器得到的图像是由捕捉器分配和释放内存的,不需要单独对图像进行释放内存的操作
//cvReleaseImage(&img);
cvDestroyWindow("image");
cvReleaseCapture(&capture);
return ;
}
 第二步:IplImage在Picture控件上显示
在这里,摄像头视频如果在Picture上显示,并实时更新,实现方法:多线程或定时器,在这里用定时器来实现视频数据的更新。
参考:http://www.cnblogs.com/leven20061001/archive/2012/10/17/2727865.html ,(定时器实现,较详细)
http://blog.csdn.net/poem_of_sunshine/article/details/17123577
程序示例:
// 将IplImage显示到控件上
void CPalmVeinRecogDlg::IplDrawToHDC(IplImage* image, UINT ID)// ID 是Picture Control控件的ID号
{
CDC* pDC = GetDlgItem(ID)->GetDC();
HDC pHdc = pDC->GetSafeHdc(); //从MFC的界面上获取Picture控件的绘图句柄HDC,
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect); //rect为控件的大小,获得pictrue控件所在的矩形区域
//SetStretchBltMode(pHdc, STRETCH_HALFTONE); CvvImage cimg; //将IplImage类型的图片转换成MFC能显示的图片格式CvvImage
cimg.CopyOf(image);
cimg.DrawToHDC(pHdc, rect); ReleaseDC(pDC);//一定要记住释放DC,否则会造成内存泄露
}

第三步:完整的程序实现

//打开摄像头事件处理
void CPalmVeinRecogDlg::OnBnClickedOpencam()
{
CString cStr;
CWnd* pWndOpenCam = GetDlgItem(IDC_OPENCAM);
//www = GetDlgItem(IDC_ShowImage2);
pWndOpenCam->GetWindowText(cStr); if (cStr == "打开摄像头")
{
if (!m_capture)
{
m_capture = cvCaptureFromCAM();
if (!m_capture){
m_strDebugInfo.SetWindowText(_T("打开摄像头失败!"));
return;
}
m_isCamOpen = true;
pWndOpenCam->SetWindowText("关闭摄像头");
m_strDebugInfo.SetWindowText(_T("打开摄像头成功!")); //由视频流捕捉器得到的图像是由捕捉器分配和释放内存的,不需要单独对图像进行释放内存的操作
m_currentFrame = cvQueryFrame(m_capture);
// 将IplImage显示到控件上
IplDrawToHDC(m_currentFrame, IDC_ShowImage);
}
SetTimer(ID_TIMERCAM, nClockTime, NULL); //定时器ID:1,定时器延时:100,
}
else
{
cvReleaseCapture(&m_capture);
KillTimer(ID_TIMERCAM);
pWndOpenCam->SetWindowText("打开摄像头");
m_strDebugInfo.SetWindowText(_T("关闭摄像头成功!"));
}
} /********************************************设置定时器*********************************************/
void CPalmVeinRecogDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nIDEvent)
{
case ID_TIMERCAM: //摄像头显示 定时器
{
if (m_isCamOpen){
m_currentFrame = cvQueryFrame(m_capture);
// 将IplImage显示到控件上
IplDrawToHDC(m_currentFrame, IDC_ShowImage);
}
break;
}
}
CDialogEx::OnTimer(nIDEvent);
}

PS:后续补充

Opencv+MFC获取摄像头数据,显示在Picture控件的更多相关文章

  1. 将OpenCV捕获的摄像头加载到picture控件中

    CRect rect; CStatic* pStc; CDC* pDC; HDC hDC; pStc = (CStatic*)GetDlgItem(IDC_CAM);//IDC_CAM是Picture ...

  2. MFC中Picture控件显示图像

    图片显示在picture控件中,整个软件最小化后图片消失问题. 解决方案:OpenCV学习笔记(9)利用MFC的Picture控件显示图像+播放视频和捕获摄像头画面 - CSDN博客  http:// ...

  3. MFC-----在MFC中使用Picture控件加载任意图片

    对于刚刚接触OpenCV的童鞋来说,如何在MFC中加载并显示一张图片.应该是初期必定会碰到的问题之一.因此本文在分享这方面经验的同时,也相当于是写给自己的一份备忘录. 本文使用的是OpenCV2.1+ ...

  4. MFC 刷新失效的Picture控件

    问题描述:如在摄像头显示时,关闭摄像头,此时Picture控件仍然显示最后一帧图像,需要刷新掉,还原Picture控件.或者重复显示两张不同大小的图片时,第二张背景有第一张图片残留. 解决方法1:(最 ...

  5. Winform中Picture控件图片的拖拽显示

    注解:最近做了一个小工具,在Winform中对Picture控件有一个需求,可以通过鼠标从外部拖拽图片到控件的上,释放鼠标,显示图片! 首先你需要对你的整个Fom窗口的AllowDrop设置Ture ...

  6. Atitit  项目界面h5化静态html化计划---vue.js 把ajax获取到的数据 绑定到表格控件 v2 r33.docx

    Atitit  项目界面h5化静态html化计划---vue.js 把ajax获取到的数据 绑定到表格控件 v2 r33.docx 1. 场景:应用在项目列表查询场景下1 1.1. 预计初步掌握vue ...

  7. [Android] 拍照、截图、保存并显示在ImageView控件中

    近期在做Android的项目,当中部分涉及到图像处理的内容.这里先讲述怎样调用Camera应用程序进行拍照,并截图和保存显示在ImageView控件中以及遇到的困难和解决方法.     PS:作者购买 ...

  8. 将数据表中的数据添加到ComboBox控件中

    实现效果: 知识运用: ComboBox控件的DataSource 属性 //获取或设置ComboBox的数据源 public Object DataResouce{get;set;} //属性值:任 ...

  9. 通用数据水平层级选择控件v0.70升级版使其支持jQuery v1.9.1

    升级原因:作者原来脚本支持的jquery版本太低了,查找了下资料,使得它能支持最新版本的jquery 备注说明:脚本代码源作者跟源文出处很难找,只能在此特感谢他的分享. 更新部分: 1.新版本不再支持 ...

随机推荐

  1. markdown实现

    博客园文章markdown实现   博客园也可以使用markdown写博客了~_~ 实现方法 在博客园管理-设置-页首Html代码中加入: <!-- Markdown --> <sc ...

  2. JS错误:Uncaught SyntaxError: Unexpected token ILLEGAL

    $('tbody', '#' + tableId).append('<tr onmouseover="this.style.backgroundColor=\'#eeeeee\'&qu ...

  3. Exchange 2016 创建日程,远程服务器返回错误: (401) 未经授权

    背景:在测试环境中一切正常,使用的是Exchange2013,上生产环境Exchange2016,部署后产生如下错误: Microsoft.Exchange.WebServices.Data.Serv ...

  4. 我的TDD实践---SVN架设篇

    我的TDD实践---SVN架设篇 “我的TDD实践”系列之SVN架设 写在前面: 我的TDD实践这几篇文章主要是围绕测试驱动开发所展开的,其中涵盖了一小部分测试理论,更多的则是关注工具的使用及环境的搭 ...

  5. 基于存储过程的MVC开源分页控件

    基于存储过程的MVC开源分页控件--LYB.NET.SPPager 摘要 现在基于ASP.NET MVC的分页控件我想大家都不陌生了,百度一下一大箩筐.其中有不少精品,陕北吴旗娃杨涛大哥做的分页控件M ...

  6. c# 在datagridview中添加comboboxcolumn 绑定数据库读取显示数据

    datagridview中的comboboxcolumn 从绑定的数据库中读取显示时,只需要注意一点,就是sql语句加个 CStr() 字符串转换函数即可,如下: SELECT CStr(XXX) a ...

  7. 跨站请求伪造(Cross Site Request Forgery (CSRF))

    跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Sit ...

  8. TOGAF架构内容框架之概述及架构工作产品分类

    TOGAF架构内容框架之概述及架构工作产品分类 在TOGAF 9之前的版本中,TOGAF的重点主要集中在企业架构开发方法方面,用于指导其使用者如何在各自的组织中对企业架构进行创建和维护,而对于企业架构 ...

  9. 34. LotusScript中的错误处理程序

    错误处理程序是所有严肃的程序的必要部分.但是在Lotus Notes开发中,很多程序员编写LotusScript代码时,并没有写专门的错误处理代码的习惯.这能够行得通,主要是因为LotusScript ...

  10. oracle保证读一致性原理

    35 这里也有讲解 1:undo segment的概念 当数据库进行修改的时候,需要把保存到以前的old的数据保存到一个地方,然后进行修改,用于保存old数据的segment 就是undo segme ...