基于CameraDS修改版,增加对DirectShow回调模式的支持
来源:互联网 发布:政府债务数据 编辑:程序博客网 时间:2024/06/06 07:11
由于工作中要做立体视觉相关开发,使用到摄像头的图像采集,而使用了于老师基于Directshow的CameraDS类, 但遇到使用明美某款摄像头是,QueryFrame()总是抓到同一帧画面,不会更新,细看CameraDS,发现使用的是DS的缓冲区模式,估计是该摄像头对于缓冲区模式支持存在问题。于是,我尝试使用回调模式,由于回调也存在两种小的模式,即SetOneShot(FALSE or TRUE),这两种模式。SetOneShot(FALSE),只用Run()一次即可。如果SetOneShot(TRUE)的话,也可以每请求一帧Run()一次,然后WaitForCompletion,再从回调函数的buffer中取出数据,这种其实和缓冲区 模式一样,只不过缓冲区变成了在回调函数中。
下面是模式用于回调抓图的类,实现了ISampleGrabberCB的接口
class CSampleGrabberCB : public ISampleGrabberCB {public:long lWidth ; long lHeight ; BOOL bGrabVideo ; // add yeleiBOOL bReadyGO;double dblSampleTime;BYTE *pBuffer;long lBufferSize;public:CSampleGrabberCB(){ lWidth = 0 ; lHeight = 0 ; bGrabVideo = FALSE ;bReadyGO = FALSE;pBuffer = NULL;}~CSampleGrabberCB(){ if (pBuffer) {delete []pBuffer;pBuffer = NULL;}}STDMETHODIMP_(ULONG) AddRef() { return 2; }STDMETHODIMP_(ULONG) Release() { return 1; }STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) {if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){*ppv = static_cast<void *>( this );return NOERROR;} return E_NOINTERFACE;}STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ) {return 0;}STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ) {if (!pBuffer) return E_POINTER;if (!this->pBuffer) this->pBuffer = new BYTE[lBufferSize];this->dblSampleTime = dblSampleTime;this->lBufferSize = lBufferSize;if(!bGrabVideo) {bReadyGO = FALSE; //确保原子操作memcpy(this->pBuffer, pBuffer, lBufferSize);bReadyGO = TRUE;}// 只使用标志位的话,你没法保证一个线程在对标志位做判断和修改// 标志位这两个操作之间不会有其它的线程修改标志位。所以需要有// 一个原子操作去一次性的互斥的完成判断和修改这两个操作。但这// 里只有一个线程会执行该段代码,所以标志位足矣return 0;}};
打开Camera时,设置回调模式
m_pSampleGrabber->SetBufferSamples(FALSE);m_pSampleGrabber->SetOneShot(FALSE);m_pCB->lWidth = m_nWidth = nWidth;m_pCB->lHeight = m_nHeight = nHeight;hr = m_pSampleGrabber->SetCallback(m_pCB, 1);m_pMediaControl->Run();最后抓图时
static double lastSampleTime=0;if (lastSampleTime == m_pCB->dblSampleTime) return NULL; //若时间戳一样,说明和上一帧是同一帧,则返回NULLif (m_pCB->lBufferSize == 0) return NULL;if ( m_nBufferSize != m_pCB->lBufferSize) { if (m_pFrame) cvReleaseImage(&m_pFrame); m_nBufferSize = m_pCB->lBufferSize; m_pFrame = cvCreateImage(cvSize(m_nWidth, m_nHeight), IPL_DEPTH_8U, 3);}lastSampleTime = m_pCB->dblSampleTime;m_pCB->bGrabVideo = TRUE;while (!m_pCB->bReadyGO) { Sleep(0); // 切到下一个时间片,确保复制(原子)操作完成}memcpy(m_pFrame->imageData, (char*)m_pCB->pBuffer, m_nBufferSize);m_pCB->bGrabVideo = FALSE;至此,可以使用DS的回调模式来抓图了,操作方式跟缓冲区模式一样,只是为了支持某些不支持缓冲区模式的相机。
0 0
- 基于CameraDS修改版,增加对DirectShow回调模式的支持
- CameraDS类Directshow camera raw10
- DirectShow对硬件的支持原理
- DirectShow对硬件的支持原理
- Directshow RTP对网络多媒体应用适配的支持
- 增加u-boot对ubi的支持
- 增加u-boot对ubi的支持
- SqlDbx 增加了对PostgreSQL的支持
- Delphi增加对动画Gif的支持
- SourceInsight 增加对Lua语言的支持
- 增加u-boot对ubi的支持
- MyEclipse6.5增加对Tomcat7的支持
- MyEclipse6.5增加对JavaEE6的支持
- android ndk增加对stl的支持
- Android 增加对鼠标的支持
- MyEclipse6.5增加对Tomcat7的支持
- MyEclipse6.5增加对JavaEE6的支持
- SourceInsight 增加对Lua语言的支持
- JAVA如何通过正则表达式获取文本中数字
- 正式部署elastalert
- hive字符串函数
- Redis RabbitMQ启动
- shell 中export
- 基于CameraDS修改版,增加对DirectShow回调模式的支持
- 夕拾算法初级篇:5)1020. 月饼(贪心)
- @Controller和@RestController的区别?
- 【Spring AOP】【AspectJ】【CGLIB】【JDK动态代理】【JDK静态代理】区别
- Fragment.setArguments()方法向fragment对象传递数据的重要作用
- 红黑树原理解析以及Java实现
- Android中的一键退出功能实现
- Dubbox 基本特性之直接调用
- Android Studio 学习之 Android SDK快速更新