« QuickSort 快速排序的实现形态学运算小结 »

VFW视频捕获之尝试

VFW,全名Video For Windows,是一种用于视频处理的工具包,也可以说是一种技术——尽管从今天看来,这是一种简陋的工具包,落后的技术。——ZwqXin.com

实现这个可以说完全由于之前某个作业的关系,当然,选择VFW而不是其他,仅仅是因为第一次GOOGLE“视频捕获”就找到它了。至于它怎么个落后法也不理了,反正顶多也就算入门吧,用点古老而简单的技术又如何?

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/image-processing/vfw-capture-try.html

视频捕捉卡是怎么一种概念呢?可以说是一种基于软件和硬件的模型,古老的VFW和新进的WDM就是这么两种模型。视频捕捉技术是怎么一种概念呢?可以说是一种用代码用API去“贯通”模型的“方法”,古老的VFW技术和不那么古老的DirectShow便是这么两种方法。VFW的体系结构缺乏为视频会议,电视浏览,视频区域捕获和VBI(Vertical Blanking Interval)数据流提供强而有效的支持[语自Windows下WDM 视频捕获简介],因而现在只不过是在乖乖地等待被淘汰的命运而已。的确,微软也抛弃了的微软东西,很难翻盘了。

当然,知道这么“让人无语”的事实,是在完成程序发现捕获帧速好差,再次GOOGLE“VFW”的时候了。

遗憾没有找回当时给予我API讲述参照的VFW介绍文,这里写个新的吧:VFW在windows下编程控制摄像头 。在这里能找到API的详细论述,我就无谓在此多费唇舌了。

什么是视频捕获呢?这是视频处理的第一步。假设你有部DV,你去乱拍摄些什么乱七八糟的东西,回家弄成视频,然后拿个播放器播放,这肯定算是“视频捕获”,不过中间牵涉的细节多着了。又譬如,你有个QQ,你去跟人家视频聊天,聊些什么乱七八糟的东西,然后对方的QQ要读取你发送过去的数据,变成可视化的视频形式展示给人家看,对方的QQ此时也肯定是在“视频捕获”,而且“很单纯地只是读数据而已呀,你想什么!”。又譬如,我把摄像头放电脑桌前,开着,让它摄些正经的东西,然后用VFW的API把所摄取到的正经的东西在电脑上呈现、播放,我也是在“视频捕获”,而且很正经。

具体呢?参考上面那篇文章应该能有所获,在WIN32中(MFC同理),通过capCreateCaptureWindow 能直接生成一个捕获窗口,返回句柄。接下来就是把摄像头跟此窗口连接了——摄像头在VFW中被抽象成一个“驱动设备号”,用capDriverConnect(发送通过使用WM_CAP_DRIVR_CONNECT消息)就够了——好了,捕捉完成。

:啥米?

:?就是这样啊.......

: (-_ -)||

:哦,当然了,还有几个设置用的系统对话框的调用。还有截图截声截AVI的API,啦啦啦。。。。

最后(喂喂!),我想说说截取图像的方法。在VFW里,某帧图像的捕获,可以用capFileSaveDIB把它弄到硬盘,也可以用capGrabFrameNoStop把它弄到剪切板。那么,如果我想实现通常的那种“另存为”的存储方式时怎么办呢?可以用剪切板编程:把该帧图像弄到剪切板后,把剪切板的内容从新弄成一张位图,再对该位图实施保存。

  1. void VideoCapture::SnatchImage(HWND ParentWnd, HDC DeviceDrawingContext)
  2.     
  3.     if(!Connected)
  4.     {
  5.         ConnectToVideoDriver(ParentWnd, VideoID);
  6.         return;
  7.     }
  8.     else
  9.        ISnatched  = capGrabFrameNoStop(VideoWnd);
  10.  
  11.  
  12.     if(ISnatched)
  13.     {
  14.         if(capEditCopy(VideoWnd))//到剪贴板
  15.             if(MessageBox(NULL, "已保存到系统剪贴板,显示于窗口不?\n[请在显示后再保存]", 
  16.                 "Snatch  Succeeds", MB_YESNO | MB_ICONINFORMATION) == IDYES)
  17.             {
  18.                 if(OpenClipboard(ParentWnd))
  19.                 { 
  20.                   enImageShow();
  21.  
  22.                   RECT windowRect;
  23.                   GetClientRect(ParentWnd, &windowRect);
  24.                       
  25.  
  26.                   BmpHandle = (HBITMAP)GetClipboardData(CF_BITMAP);
  27.                   BmpDC = CreateCompatibleDC(DeviceDrawingContext);
  28.                   SelectObject(BmpDC, BmpHandle);
  29.                   BitBlt(DeviceDrawingContext, 10,10,windowRect.right-20, windowRect.bottom-50,BmpDC,0,0,SRCCOPY);
  30.                   CloseClipboard();
  31.  
  32.                 }
  33.                 else
  34.                  MessageBox(NULL, " 剪贴板有问题 ", "Clipboard  Fails", MB_OK | MB_ICONINFORMATION);
  35.  
  36.             }
  37.  
  38.     }

上面最后效果只是显示出来,但是过程中生成了位图的句柄,位图资源DC(见[认识HBITMAP与Bmp操作(整内存拷贝版)] ),保存也不过是调用GetDIBits来从它们身上取得位图数据,填充填充BMP文件头之类的了。

最后给上DEMO,完结本文。
ZwqXin 's LVideoCapture ver1.0 (进后,点download链接)

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/image-processing/vfw-capture-try.html

  • quote 1.mysee
  • 你是用MFC做的吧? 我用的是Win32 console. 问题出来了:CDC 、CClientDC CBitmap均无法识别。请问该怎么办?
    zwqxin 于 2012-4-5 20:44:09 回复
    记得用的是Win32哦,不过不是console而已。
  • 2012-4-5 10:30:27 回复该留言
  • quote 2.LL
  • 正在学习MFC和vfw对摄像头的操作处理,想用背景减除法做目标检测,网上关于背景减除法的介绍都是通过利用opencv作背景建模前景检测的方法实现的,不知道用VC和MFC先捕获一帧图像然后用以后捕获的帧都和该帧相减能不能实现
    zwqxin 于 2014-8-10 23:59:53 回复
    一般先捕获得一张稳定的背景图。
  • 2014-8-10 13:46:06 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

IE下本页面显示有问题?

→点击地址栏右侧【兼容视图】←

日历

Search

网站分类

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2024 ZwqXin. All Rights Reserved. Theme edited from ipati.