视频采集卡二次开发(天敏SDK2500+openCV)

视频开发难点

做视频二次开发最常遇到的问题有两个,一个是算法分析的问题,就是图像处理的问题,另一个就是视频流的问题,就是串口和数据解码的问题。通常来说,科研领域大多在研究前者,而民间的发烧友大多在弄后者,因为科研机构大多不需要考虑硬件开销,他们的目标就是把结果弄出来,而民间的发烧友大多对算法兴趣不大,喜欢搞硬件。


主题知识

这次的视频采集卡(又称“板卡”)考虑到性价比的问题,采用的是天敏SDK2500,使用openCV作为图像处理函数库,天敏SDK2500的二次开发包在他们官网可以下载,至于如何安装驱动等问题,开发包上都有介绍,不过要提醒的是操作系统Windows XP和Win7 32位机,一开始用了Windows Server和Win7 64位都无法驱动,后来打去官网客服才意识这个问题, 之前用海康威视的从windows 64位到Linux的开发包都有,果然是国内第一视频厂商,不过他们的板卡实在是贵,而且没有低于四路的板卡,所以只能选择天敏,加上我们对图像要求没有那么高。
 安装好驱动后,运行SDK里面的Demo就可以看到画面了,但是这个离可以对图像进行处理还有很长一段路。主要是以下三步:
 1. 要获取视频流数据(两种方法,调用缓冲区和使用windows剪贴板)
板卡自带的函数库提供两类捕获当前帧图像数据的函数。一类将图像数据以文件形式保存到磁盘上,另一类将图像数据复制到剪贴板上。
使用第一类的话,主要是用到函数:
  1. HRESULT WINAPI VCAEnableCapSourceStream(int nCards, BOOL bCapStream, VideoFieldType enVideoFieldType, PrcCapSourceStream pCapStream)  
 HRESULT WINAPI VCAEnableCapSourceStream(int nCards, BOOL bCapStream, VideoFieldType enVideoFieldType, PrcCapSourceStream pCapStream)
ProCapSourceStream是回调函数,需要注册一个回调函数:
  1. typedef void (CALLBACK *PrcCapSourceStream)( long lnCardID, long pBuf, long lnWidth, long lnHeight, long lnBiCount );   
typedef void (CALLBACK *PrcCapSourceStream)( long lnCardID, long pBuf, long lnWidth, long lnHeight, long lnBiCount ); 
不过我没有用这个方法,理由后面会详细说,不过这个回调函数本身貌似也有问题,long格式的buffer需要先成功转换会byte的,这个涉及到复杂的数据存储问题,主要是long数据占用4个字节,而byte只占用1个字节。
如果确实要用这个方法的话,我建议使用天敏的VC4000采集卡会好很多,这个的函数库相对改进了,调用的函数是这个:
  1. VCARegVidCapCallBack( dwCard, VCAPrcVidCapCallBack )  
VCARegVidCapCallBack( dwCard, VCAPrcVidCapCallBack )
回调函数是这个:
  1. void CALLBACK VCAPrcVidCapCallBack(DWORD dwCard, BYTE *pbuff,DWORD dwSize)  
void CALLBACK VCAPrcVidCapCallBack(DWORD dwCard, BYTE *pbuff,DWORD dwSize)
获得的是YUV的数据,然后把YUV转化为RGB就可以了,参考内容里面有一个相关项目的代码.

        使用第二类的话, 我就是使用第二种方法的, 就是剪贴板, 由于剪贴板是Windows系统中单独预留出来的一块内存,内存读写速度是银盘读写速度的十倍以上,同时使用剪贴板也可以避免对硬盘的反复读写,因此利用剪贴板捕获图像数据个人觉得更高效写。
代码如下:
  1. GLOBALHANDLE m_hdl;  
  2. VCACopyToClipBoard(0);//参数是板卡ID号  
  3. OpenClipboard();  
  4. m_hdl=GetClipboardData(CF_DIB);  
  5. LPBITMAPINFO lpBI=(LPBITMAPINFO)GlobalLock(m_hdl);  
  6. void* pDIBBits=(void*)(lpBI+1);  
  7. GlobalUnlock(m_hdl);  
  8. CloseClipboard();  
GLOBALHANDLE m_hdl;
VCACopyToClipBoard(0);//参数是板卡ID号
OpenClipboard();
m_hdl=GetClipboardData(CF_DIB);
LPBITMAPINFO lpBI=(LPBITMAPINFO)GlobalLock(m_hdl);
void* pDIBBits=(void*)(lpBI+1);
GlobalUnlock(m_hdl);
CloseClipboard();

 2. 将视频流数据转化为openCV的图像格式
目前,还没有转化为opencv2.0的Mat格式,只是转化为了1.0的IplImage,后续会把数据直接转化为Mat格式.
代码如下:
  1. //lpBI是从剪贴板获得的数据LPBITMAPINFO lpBI  
  2. byte* p=new byte[lpBI->bmiHeader.biWidth*lpBI->bmiHeader.biHeight*3+1];  
  3. IplImage* m_Image=cvCreateImageHeader(cvSize(lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight),IPL_DEPTH_8U,3);  
  4. memcpy(p,pDIBBits,lpBI->bmiHeader.biWidth*lpBI->bmiHeader.biHeight*3);  
  5. cvSetData(m_Image,p,lpBI->bmiHeader.biWidth*3);  
  6. cvFlip(m_Image,m_Image,0);  
//lpBI是从剪贴板获得的数据LPBITMAPINFO lpBI
byte* p=new byte[lpBI->bmiHeader.biWidth*lpBI->bmiHeader.biHeight*3+1];
IplImage* m_Image=cvCreateImageHeader(cvSize(lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight),IPL_DEPTH_8U,3);
memcpy(p,pDIBBits,lpBI->bmiHeader.biWidth*lpBI->bmiHeader.biHeight*3);
cvSetData(m_Image,p,lpBI->bmiHeader.biWidth*3);
cvFlip(m_Image,m_Image,0);

 3. 设定定时器(如果使用缓冲区buffer的话,可以不用这步)
  代码如下:
  1. void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) //回调函数  
  2. {  
  3.     //处理代码  
  4. }  
  5.   
  6. //Timer的使用代码,放到程序的任意位置,如果和回调函数不在同一个文件,则使用extern外部调用回调函数  
  7. UINT_PTR iTimerID=SetTimer(0, 1000, TimerProc); //间隔1000ms触犯一次,TimerProc是回调函数  
  8. KillTimer(NULL, iTimerID);  
void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) //回调函数
{
    //处理代码
}

//Timer的使用代码,放到程序的任意位置,如果和回调函数不在同一个文件,则使用extern外部调用回调函数
UINT_PTR iTimerID=SetTimer(0, 1000, TimerProc); //间隔1000ms触犯一次,TimerProc是回调函数
KillTimer(NULL, iTimerID);

参考附录

1.《一种多区域视频监控入侵检测报警方法的研究》
下载链接:http://download.csdn.net/detail/luoyun614/8281997
2. 天敏VC3000+opencv的开发案例(源码)
下载地址:http://download.csdn.net/detail/luoyun614/8281999

转载请注明出处:http://blog.csdn.net/luoyun614/article/details/42048373


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值