当前位置: 首页 >> 应用软件 >> 桌面与多媒体 >> 使用directshow代替opencv的vfw的源代码
 

使用directshow代替opencv的vfw的源代码

作者:      来源:blog.csdn.net/hardVB     发表时间:2006-06-01     浏览次数:      字号:    

本文提供了使用directshow代替opencv的vfw 的源代码,与转化为iplimage格式的算法.
实验中发现opencv的cvCaptureFromCAM 使用的是vfw,采用消息机制,速度较慢,测试发现fps只有 9-12左右,太慢了.  发现经过使用directshow后速度提升到60帧/s.在opencv group上了解到这是一个普遍问题,也许有人做过转换,却没有完整的例子与代码.在此贴出.对希望提高opencv视频分析速度的有所帮助.

用法如下:
static ARFrameGrabber frameGrabber;
IplImage ds_frame;
frameGrabber.Init(0, true);
frameGrabber.SetFlippedImage(true);
for(;;)
    {
       IplImage *frame =0;
 frameGrabber.GrabByteFrame();
 BYTE *myBuffer = frameGrabber.GetByteBuffer();

 int width = frameGrabber.GetWidth();
 int height = frameGrabber.GetHeight();  
 int stride  = (width * sizeof( RGBTRIPLE ) + 3) & -4;

 cvInitImageHeader( &ds_frame, cvSize(width, height), 8, 3,IPL_ORIGIN_BL, 4 );
 ds_frame.widthStep = stride;   
 cvSetData( &ds_frame, myBuffer, stride ); 
 frame = &ds_frame;

        /* 视频分析部分 */
     
   }

以下是directshow源文件,加入工程可用.


// ARFrameGrabber.h: interface for the ARFrameGrabber class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_)
#define AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//#include <AR/config.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dshow.h>
//#include <streams.h>
#include <atlbase.h>
#include <qedit.h>

class SmartString
{
public:
 SmartString():str(NULL) {}

 SmartString(char* pStr):str(NULL)
 {
  if (pStr)
  {
   int size = int(strlen(pStr));
   str = new char[size+1];
   strcpy(str, pStr);
  }
 }

 SmartString(SmartString& sStr)
 {
  SetString(sStr.GetBuffer());
 }

 ~SmartString()
 {
  if (str)
   delete[] str;
 }

 SmartString& operator =(char* pStr)
 {
  SetString(pStr);
  return *this;
 }

 SmartString& operator =(SmartString& sStr)
 {
  SetString(sStr.GetBuffer());
  return *this;
 }

 char* GetBuffer() {return str;}

protected:
 void SetString(char *pStr)
 {
  if (str)
   delete[] str;

  if (!pStr)
  {
   str = NULL;
  }
  else
  {
   int size = int(strlen(pStr));
   str = new char[size + 1];
   strcpy(str, pStr);
  }

 }


 char* str;
};

class DeviceInfo
{
public:
 DeviceInfo():next(NULL), deviceId(-1)
 {
 }
 ~DeviceInfo()
 {
  if (next)
   delete next;
 }


 SmartString friendlyName;
 int   deviceId; 
 DeviceInfo* next;
};


class  ARFrameGrabber 
{
public:
 ARFrameGrabber();
 virtual ~ARFrameGrabber();

 void Init(int deviceId, bool displayProperties = true);
 void BindFilter(int deviceId, IBaseFilter **pFilter);
 void GrabFrame(long* size, long** pBuffer);
 void GrabFrame();
 void Grab32BitFrame();
 void GrabByteFrame();
 void SetCrossBar();
 


 long  GetBufferSize() {return bufferSize;}
 long* GetBuffer() {return pBuffer;}
 BYTE* GetByteBuffer() {return pBYTEbuffer;}
 
 void SetFlippedImage(bool flag) {flipImage = flag;}

 void DisplayProperties();
 void EnumDevices(DeviceInfo *head);
    int GetWidth();
    int GetHeight();

protected:
 CComPtr<IGraphBuilder> pGraph;
 CComPtr<IBaseFilter> pDeviceFilter;
 CComPtr<IMediaControl> pMediaControl;
 CComPtr<IBaseFilter> pSampleGrabberFilter;
 CComPtr<ISampleGrabber> pSampleGrabber;
 CComPtr<IPin> pGrabberInput;
 CComPtr<IPin> pGrabberOutput;
 CComPtr<IPin> pCameraOutput;
 CComPtr<IMediaEvent> pMediaEvent;
 CComPtr<IBaseFilter> pNullFilter;
 CComPtr<IPin> pNullInputPin;

 void FlipImage(long* pBuf);

private:
 void ReportError(char *msg);

 bool flipImage;
 long bufferSize;
 long *pBuffer;
 BYTE *pBYTEbuffer;
    bool connected;
    int width;
    int height;
};

#endif // !defined(AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_)

 

ARFrameGrabber.cpp
// ARFrameGrabber.cpp: implementation of the ARFrameGrabber class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <assert.h>
#include "ARFrameGrabber.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ARFrameGrabber::ARFrameGrabber()
    : pBuffer(NULL), bufferSize(0), flipImage(false), connected(false), width(0), height(0)
{
}

ARFrameGrabber::~ARFrameGrabber()
{
 pMediaControl->Stop();
 if (pBuffer)
  delete[] pBuffer;
 if(pBYTEbuffer)
  delete[] pBYTEbuffer;
}


void ARFrameGrabber::Init(int deviceId, bool displayProperties)
{
 HRESULT hr = S_OK;
 CoInitialize(NULL);
 // Create the Filter Graph Manager.
 hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
  IID_IGraphBuilder, (void **)&pGraph);

 hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
    IID_IBaseFilter, (LPVOID *)&pSampleGrabberFilter);

 hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMediaControl);
 hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pMediaEvent);

 hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
  IID_IBaseFilter, (LPVOID*) &pNullFilter);

 hr = pGraph->AddFilter(pNullFilter, L"NullRenderer");

 hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&pSampleGrabber);

 

 AM_MEDIA_TYPE   mt;
 ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
 mt.majortype = MEDIATYPE_Video;
 mt.subtype = MEDIASUBTYPE_RGB32;
 mt.formattype = FORMAT_VideoInfo;
 hr = pSampleGrabber->SetMediaType(&mt);

 pGraph->AddFilter(pSampleGrabberFilter, L"Grabber");
 


 // Bind Device Filter.  We know the device because the id was passed in
 BindFilter(deviceId, &pDeviceFilter);
 pGraph->AddFilter(pDeviceFilter, NULL);

 CComPtr<IEnumPins> pEnum;
 pDeviceFilter->EnumPins(&pEnum);
 
 hr = pEnum->Reset();
 hr = pEnum->Next(1, &pCameraOutput, NULL);


 pEnum = NULL;
 pSampleGrabberFilter->EnumPins(&pEnum);
 pEnum->Reset();
 hr = pEnum->Next(1, &pGrabberInput, NULL);

 pEnum = NULL;
 pSampleGrabberFilter->EnumPins(&pEnum);
 pEnum->Reset();
 pEnum->Skip(1);
 hr = pEnum->Next(1, &pGrabberOutput, NULL);


 

 pEnum = NULL;
 pNullFilter->EnumPins(&pEnum);
 pEnum->Reset();
 hr = pEnum->Next(1, &pNullInputPin, NULL);

  SetCrossBar();

    if (displayProperties) {
   CComPtr<ISpecifyPropertyPages> pPages;

   HRESULT hr = pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages);
   if (SUCCEEDED(hr))
   {
    PIN_INFO PinInfo;
    pCameraOutput->QueryPinInfo(&PinInfo);

    CAUUID caGUID;
    pPages->GetPages(&caGUID);

    OleCreatePropertyFrame(
     NULL,
     0,
     0,
     L"Property Sheet",
     1,
     (IUnknown **)&(pCameraOutput.p),
     caGUID.cElems,
     caGUID.pElems,
     0,
     0,
     NULL);
    CoTaskMemFree(caGUID.pElems);
    PinInfo.pFilter->Release();
   }
    }

    hr = pGraph->Connect(pCameraOutput, pGrabberInput);

 hr = pGraph->Connect(pGrabberOutput, pNullInputPin);

// hr = pGraph->Render(pGrabberOutput);

 if (FAILED(hr))
 {
  switch(hr)
  {
  case VFW_S_NOPREVIEWPIN :
   break;
  case E_FAIL :
   break;
  case E_INVALIDARG :
   break;
  case E_POINTER :
   break;
  }
 }

 pSampleGrabber->SetBufferSamples(TRUE);
 pSampleGrabber->SetOneShot(TRUE);
   
    hr = pSampleGrabber->GetConnectedMediaType(&mt);
    VIDEOINFOHEADER *videoHeader;
    assert(mt.formattype == FORMAT_VideoInfo);
    videoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
    width = videoHeader->bmiHeader.biWidth;
    height = videoHeader->bmiHeader.biHeight;
    connected = true;
}

[1] [2]

责任编辑 webmaster

 
 
 
推荐文章
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •