从网络摄像头获取图像(ISampleGrabber) [英] Get Images from Webcam (ISampleGrabber)

查看:303
本文介绍了从网络摄像头获取图像(ISampleGrabber)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我需要一个程序,该程序每秒(或什至更快)从USB网络摄像头读取图像,并将其以JPEG格式写入硬盘.

我唯一的问题是,我的程序太慢了.从网络摄像头获取图片大约需要3秒钟...(Render()和WaitForCompletion()是缓慢的函数)

这是我使用的部分源代码(在循环中):

 CComPtr< ISampleGrabber> pGrabber;
 CComPtr< IBaseFilter> pSource;
 CComPtr< IGraphBuilder> pGraph;
 CComPtr< IVideoWindow> pVideoWindow;

 pGrabber.CoCreateInstance(CLSID_SampleGrabber);

 CComQIPtr< IBaseFilter和& IID_IBaseFilter> pGrabberBase(pGrabber);

 GetDefaultCapDevice(& pSource);

 pGraph.CoCreateInstance(CLSID_FilterGraph);
 pGraph-> AddFilter(pSource,L " );
 pGraph-> AddFilter(pGrabberBase,L " );

 AM_MEDIA_TYPE am_media_type;
 ZeroMemory(& am_media_type, sizeof (am_media_type));
 am_media_type.bFixedSizeSamples = TRUE;
 am_media_type.lSampleSize =  1 ;
 am_media_type.majortype = MEDIATYPE_Video;
 am_media_type.subtype = MEDIASUBTYPE_RGB24;
 am_media_type.formattype = FORMAT_VideoInfo;

 pGrabber-> SetMediaType(& am_media_type);

CComPtr< IPin> pSourcePin;
 CComPtr< IPin> pGrabPin;
 pSourcePin = GetOutPin(pSource, 0 );
 pGrabPin = GetInPin(pGrabberBase, 0 );
 pGraph-> Connect(pSourcePin,pGrabPin);
AM_MEDIA_TYPE mt;
 pGrabber-> GetConnectedMediaType(& mt);

 VIDEOINFOHEADER * vih =(VIDEOINFOHEADER *)mt.pbFormat;
 CB.Width = vih-> bmiHeader.biWidth;
 CB.Height = vih-> bmiHeader.biHeight;
 _FreeMediaType(mt);

 memset(&(cbInfo.bih), 0  sizeof (cbInfo.bih));
 cbInfo.bih.biSize =  sizeof (cbInfo.bih);
 cbInfo.bih.biWidth = CB.Width;
 cbInfo.bih.biHeight = CB.Height;
 cbInfo.bih.biPlanes =  1 ;
 cbInfo.bih.biBitCount =  24 ;

 CComPtr< IPin> pGrabOutPin = GetOutPin(pGrabberBase, 0 );
 pGraph-> Render(pGrabOutPin); /*   **************〜2秒******* ************/
 pGrabber-> SetBufferSamples(FALSE);
 pGrabber-> SetOneShot(TRUE);
 pGrabber-> SetCallback(& CB, 1 );

 CComQIPtr< IMediaControl和& IID_IMediaControl> pControl(pGraph);
 pControl-> Run();

 CComQIPtr< IMediaEvent和& IID_IMediaEvent> pEvent(pGraph);
  EvCode =  0 ;
 pEvent-> WaitForCompletion(INFINITE,& EvCode); /*   *******************〜1 s ** *********************/

 CHAR * BitmapData = NULL;
 cbInfo.biSize = CalcBitmapInfoSize(cbInfo.bih);
 ULONG大小= cbInfo.biSize + cbInfo.lBufferSize;
 * BitmapSize =大小;
 如果(位图)
 {
     *位图=(BITMAPINFO *) BYTE [Size];
     如果(*位图)
     {
         (**位图).bmiHeader = cbInfo.bih;
         BitmapData =(CHAR *)(* Bitmap)+ cbInfo.biSize;
         memcpy(BitmapData,cbInfo.pBuffer,cbInfo.lBufferSize);
     }
 } 




如果我想要每秒至少1个网络摄像头图像,该怎么办?
我已经尝试过将SetOneShot()设置为false,但是整个程序不再起作用了.
而SetBufferSamples()的作用是什么?

预先感谢您的帮助! /ms630368(VS.85).aspx">http://msdn.microsoft.com/zh-cn/library/ms630368(VS.85).aspx [CComPtr< ISampleGrabber > pGrabber; CComPtr< IBaseFilter > pSource; CComPtr< IGraphBuilder > pGraph; CComPtr< IVideoWindow > pVideoWindow; pGrabber.CoCreateInstance( CLSID_SampleGrabber ); CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( pGrabber ); GetDefaultCapDevice(&pSource); pGraph.CoCreateInstance( CLSID_FilterGraph ); pGraph->AddFilter( pSource, L"Source" ); pGraph->AddFilter( pGrabberBase, L"Grabber" ); AM_MEDIA_TYPE am_media_type; ZeroMemory(&am_media_type, sizeof(am_media_type)); am_media_type.bFixedSizeSamples = TRUE; am_media_type.lSampleSize = 1; am_media_type.majortype = MEDIATYPE_Video; am_media_type.subtype = MEDIASUBTYPE_RGB24; am_media_type.formattype = FORMAT_VideoInfo; pGrabber->SetMediaType( &am_media_type ); CComPtr< IPin > pSourcePin; CComPtr< IPin > pGrabPin; pSourcePin = GetOutPin( pSource, 0 ); pGrabPin = GetInPin( pGrabberBase, 0 ); pGraph->Connect( pSourcePin, pGrabPin ); AM_MEDIA_TYPE mt; pGrabber->GetConnectedMediaType( &mt ); VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat; CB.Width = vih->bmiHeader.biWidth; CB.Height = vih->bmiHeader.biHeight; _FreeMediaType( mt ); memset( &(cbInfo.bih), 0, sizeof( cbInfo.bih ) ); cbInfo.bih.biSize = sizeof( cbInfo.bih ); cbInfo.bih.biWidth = CB.Width; cbInfo.bih.biHeight = CB.Height; cbInfo.bih.biPlanes = 1; cbInfo.bih.biBitCount = 24; CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 ); pGraph->Render( pGrabOutPin ); /*************** ~ 2 sec *******************/ pGrabber->SetBufferSamples( FALSE ); pGrabber->SetOneShot( TRUE ); pGrabber->SetCallback( &CB, 1 ); CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph ); pControl->Run( ); CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph ); long EvCode = 0; pEvent->WaitForCompletion( INFINITE, &EvCode ); /******************** ~ 1 s ***********************/ CHAR *BitmapData = NULL; cbInfo.biSize = CalcBitmapInfoSize(cbInfo.bih); ULONG Size = cbInfo.biSize + cbInfo.lBufferSize; *BitmapSize = Size; if(Bitmap) { *Bitmap = (BITMAPINFO *) new BYTE[Size]; if(*Bitmap) { (**Bitmap).bmiHeader = cbInfo.bih; BitmapData = (CHAR *)(*Bitmap) + cbInfo.biSize; memcpy(BitmapData, cbInfo.pBuffer, cbInfo.lBufferSize); } }




What do I need to do, if I want at least 1 webcam image per second?
I already tried setting SetOneShot() to false, but then the whole program doesn''t work anymore...
And what does SetBufferSamples() do?

Thanks in advance for your help!

Check if the following link helps http://msdn.microsoft.com/en-us/library/ms630368(VS.85).aspx[^]


I don''t understand how this can help me with my problem with SampleGrabber...
All I ask is how I can grab multiple frames in a row with SampleGrabber. Setting the SetOneShot() to false and then what else do I have to do?


这篇关于从网络摄像头获取图像(ISampleGrabber)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆