最近玩了一下海康的IPcamera,与普通的WEBcamera输出RGB图像不同,其解码后输出的图像格式为YV12,这使得我们不能用熟悉的两行代码
就获得可以用opencv直接处理的源图像了,这一度造成了不少麻烦。
所以贴出部分代码,希望对正在使用或者也想玩下海康摄像头的朋友一点参考。
能力有限,若有误,勿喷!
转YV12到YCrCb的函数实现有很多,代码不知谁写的,我是从雪水的这篇博客(超链接)看到的,亲测可以实现。
- void yv12toYUV(char *outYuv, char *inYv12, int width, int height,int widthStep)
- {
- int col,row;
- unsigned int Y,U,V;
- int tmp;
- int idx;
- for (row=0; row<height; row++)
- {
- idx=row * widthStep;
- int rowptr=row*width;
- for (col=0; col<width; col++)
- {
-
- tmp = (row/2)*(width/2)+(col/2);
- Y=(unsigned int) inYv12[row*width+col];
- U=(unsigned int) inYv12[width*height+width*height/4+tmp];
- V=(unsigned int) inYv12[width*height+tmp];
-
- if((idx+col*3+2)> (1200 * widthStep))
- {
- //printf("row * widthStep=%d,idx+col*3+2=%d.\n",1200 * widthStep,idx+col*3+2);
- }
- outYuv[idx+col*3] = Y;
- outYuv[idx+col*3+1] = U;
- outYuv[idx+col*3+2] = V;
- }
- }
- }
本文推荐用cvtColor()函数,opencv2.4.8以上版本自定义了宏CV_YUV2BGR_YV12,可以实现这一转换;
以下是主函数:以下是实时流回调函数fRealDataCallBack:以下是解码回调函数,在解码回调之前需声明一个List容器,用以存放帧数据,该List最好定义为全局变量,便于在线程里opencv处理。此处利用解码回调函数做视频格式转换操作,并将RGB图像存入frameQueue。利用多线程编程,在另一个线程里用opencv处理图像或其他操作,我这里是进行跟踪的,其中,实时帧数realframe_count是用来控制取帧间隔时间的,因为opencv图像处理线程会运行相应复杂算法或者别的操作,时间消耗较大,不可能逐一处理每一帧。线程通过一个按钮开启,响应函数如下,由于贴的使部分代码,请自动忽略无关内容!以下为取帧线程函数:到这一步就可以了,另外,在函数中是不需要waitkey来控制帧率的,海康的SDK好像是自动回调的!