天天看点

视频采集卡二次开发(天敏SDK2500+openCV)视频开发难点主题知识参考附录

视频开发难点

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

主题知识

这次的视频采集卡(又称“板卡”)考虑到性价比的问题,采用的是天敏SDK2500,使用openCV作为图像处理函数库,天敏SDK2500的二次开发包在他们官网可以下载,至于如何安装驱动等问题,开发包上都有介绍,不过要提醒的是操作系统Windows XP和Win7 32位机,一开始用了Windows Server和Win7 64位都无法驱动,后来打去官网客服才意识这个问题, 之前用海康威视的从windows 64位到Linux的开发包都有,果然是国内第一视频厂商,不过他们的板卡实在是贵,而且没有低于四路的板卡,所以只能选择天敏,加上我们对图像要求没有那么高。  安装好驱动后,运行SDK里面的Demo就可以看到画面了,但是这个离可以对图像进行处理还有很长一段路。主要是以下三步:  1. 要获取视频流数据(两种方法,调用缓冲区和使用windows剪贴板) 板卡自带的函数库提供两类捕获当前帧图像数据的函数。一类将图像数据以文件形式保存到磁盘上,另一类将图像数据复制到剪贴板上。 使用第一类的话,主要是用到函数:

HRESULT WINAPI VCAEnableCapSourceStream(int nCards, BOOL bCapStream, VideoFieldType enVideoFieldType, PrcCapSourceStream pCapStream)
           

ProCapSourceStream是回调函数,需要注册一个回调函数:

typedef void (CALLBACK *PrcCapSourceStream)( long lnCardID, long pBuf, long lnWidth, long lnHeight, long lnBiCount ); 
           

不过我没有用这个方法,理由后面会详细说,不过这个回调函数本身貌似也有问题,long格式的buffer需要先成功转换会byte的,这个涉及到复杂的数据存储问题,主要是long数据占用4个字节,而byte只占用1个字节。 如果确实要用这个方法的话,我建议使用天敏的VC4000采集卡会好很多,这个的函数库相对改进了,调用的函数是这个:

VCARegVidCapCallBack( dwCard, VCAPrcVidCapCallBack )
           

回调函数是这个:

void CALLBACK VCAPrcVidCapCallBack(DWORD dwCard, BYTE *pbuff,DWORD dwSize)
           

获得的是YUV的数据,然后把YUV转化为RGB就可以了,参考内容里面有一个相关项目的代码.

        使用第二类的话, 我就是使用第二种方法的, 就是剪贴板, 由于剪贴板是Windows系统中单独预留出来的一块内存,内存读写速度是银盘读写速度的十倍以上,同时使用剪贴板也可以避免对硬盘的反复读写,因此利用剪贴板捕获图像数据个人觉得更高效写。 代码如下:

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格式. 代码如下:

//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的话,可以不用这步)   代码如下:

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