所使用海康威视摄像头型号:DS-2CD4026FWD-(A)(P)

海康威视IPCamera图像捕获方法有两种:

(1)利用SDK里面的NET_DVR_CaptureJPEGPicture_NEW进行视频抓图

(2)捕获实时流,将实时流解码成YV12,然后转换成RGB

海康威视IPCamera图像捕获

捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图像(一)

捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图像(二)

所使用海康威视摄像头型号:DS-2CD4026FWD-(A)(P)

海康威视IPCamera图像捕获方法有两种:

(1)利用SDK里面的NET_DVR_CaptureJPEGPicture_NEW进行视频抓图

(2)捕获实时流,将实时流解码成YV12,然后转换成RGB

在这篇博文里,我先介绍第一种方法。

第一种方法,关键是调用NET_DVR_CaptureJPEGPicture_NEW这个函数。关于这个函数的参数,可以在SDK中找到,我这里截个图以作说明。

这个函数Ret是用于返回该图像大小的一个参数,但是该函数的这个参数大概是没有用引用或者指针的方式来传递参数,导致返回值一直是我初始化的0,因此为后面的操作带来了些许的不便——不得不使用一个较大的内存来保存图像一定能存储的下。

NET_DVR_CaptureJPEGPicture_NEW这个函数是将单帧数据捕获并保存成JPEG,存放在指定的内存空间中。也就是内存里的JPEG。为了获得OpenCV能处理的IplImage图像,必须在内存中进行解码。

OpenCV在内存中解码的函数只有一个:imdecode,下图是imdecode的说明

该函数要求buf必须是数组或者是byte类型的vector. 因此需要对char * 类型的JPEG压缩图像进行存储格式转换。

[cpp]  view plain copy print ?
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <ctime>
  4. #include <Windows.h>
  5. #include "HCNetSDK.h"
  6. #include "highgui.h"
  7. #include "cv.h"
  8. using namespace cv;
  9. using namespace std;
  10. //typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
  11. //PROCGETCONSOLEWINDOW GetConsoleWindow;
  12. int main(int argc, char * argv[])
  13. {
  14. //---------------------------------------
  15. // 初始化
  16. NET_DVR_Init();
  17. //设置连接时间与重连时间
  18. NET_DVR_SetConnectTime(2000, 1);
  19. NET_DVR_SetReconnect(10000, true);
  20. //---------------------------------------
  21. //获取控制台窗口句柄
  22. //HMODULE hKernel32 = GetModuleHandle((LPCWSTR)"kernel32");
  23. //GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
  24. //---------------------------------------
  25. // 注册设备
  26. LONG lUserID;
  27. NET_DVR_DEVICEINFO_V30 struDeviceInfo;
  28. lUserID = NET_DVR_Login_V30("10.102.7.88", 8000, "admin", "12345", &struDeviceInfo);
  29. if (lUserID < 0)
  30. {
  31. printf("Login error, %d\n", NET_DVR_GetLastError());
  32. NET_DVR_Cleanup();
  33. return -1;
  34. }
  35. //---------------------------------------
  36. //cvNamedWindow("camera",CV_WINDOW_AUTOSIZE);
  37. IplImage* frame;
  38. //定义JPEG图像质量
  39. LPNET_DVR_JPEGPARA JpegPara = new NET_DVR_JPEGPARA;
  40. JpegPara->wPicQuality = 0;
  41. JpegPara->wPicSize = 9;
  42. char * Jpeg = new char[200*1024];
  43. DWORD len = 200*1024;
  44. LPDWORD Ret = 0;
  45. if(!NET_DVR_SetCapturePictureMode(BMP_MODE))
  46. {
  47. cout<<"Set Capture Picture Mode error!"<<endl;
  48. cout<<"The error code is "<<NET_DVR_GetLastError()<<endl;
  49. }
  50. //bool capture = NET_DVR_CaptureJPEGPicture(lUserID,1,JpegPara,"1111");
  51. vector<char>data(200*1024);
  52. while(1)
  53. {
  54. bool capture = NET_DVR_CaptureJPEGPicture_NEW(lUserID,1,JpegPara,Jpeg,len,Ret);
  55. if(!capture)
  56. {
  57. printf("Error: NET_DVR_CaptureJPEGPicture_NEW = %d", NET_DVR_GetLastError());
  58. return -1;
  59. }
  60. for(int i=0;i<200*1024;i++)
  61. data[i] = Jpeg[i];
  62. Mat img = imdecode(Mat(data),1);
  63. imshow("camera",img);
  64. waitKey(1);
  65. }
  66. //FILE * fp = fopen("3.jpg","wb");
  67. //fwrite(Jpeg,1,123*1024,fp);
  68. //fclose(fp);
  69. return 0;
  70. }

运行这个代码当然OpenCV的配置不能少,HCNetSDK.h也必须包含进工程。

运行这个程序,可以捕获到图像,但是我计算了下时间,在调用 NET_DVR_CaptureJPEGPicture_NEW(lUserID,1,JpegPara,Jpeg,len,Ret);这一句话的时候,用时300ms,这个耗时太长,无法实时!但是如果对实时无要求,用这个也可以了,好理解!

/********************************************************************************************************************************************************************************

第二部分博文内容

********************************************************************************************************************************************************************************、

在上一篇博文里,我介绍了第一种方法,但是由于NET_DVR_CaptureJPEGPicture_NEW该函数执行需要较长时间,无法实时,所以必须继续第二种方法。

在这篇博文里,我将介绍第二种方法,将捕获到的海康威视IPCamera摄像头图像转成OpenCV能处理的IplImage图像。

在实现完捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图像(一)里面的方法后,发现不能实时,这个系统我是要做给给人看的,是需要实时演示的,这样子肯定是不行的。纠结了好久!然后查看海康威视《设备网络SDK使用手册_V4.2》,里面有一个预览模块示例程序,可惜我一直运行不了,报出的错误是PROCGETCONSOLEWINDOW GetConsoleWindow中的GetConsoleWindow被重定义,后来一直调试没调成功。

实在是没辙了,打海康客服,不过海康的客服我实在无语,北京的完全无法接通,直接打杭州的,打了四五遍终于有个人接电话了,对方不懂,然后说让个工程师回电话。OK,终于回了。他告诉我http://www.hikvision.com/cn/download_more_401.html 这里是有例程的,有分功能示例!突然间有了希望了,例程是VC6.0工程,改了一些地方后,终于能运行了。于是,将他的MFC工程相关的代码抠出来,重组。于是实现了捕获YV12格式的视频流的功能,光有YV12还是不行的,需要将YV12转成YUV4:4:4的,然后再将YUV色度空间转换成RGB色度空间,这个过程是在信件的DecBFun回调函数(回调函数请看这里!)里面执行的。

不多说了,上代码!

[cpp]  view plain copy print ?
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include "Windows.h"
  5. #include "HCNetSDK.h"
  6. #include "PlayM4.h"
  7. #include <opencv2\opencv.hpp>
  8. #include "cv.h"
  9. #include "highgui.h"
  10. #include <time.h>
  11. #define USECOLOR 1
  12. using namespace std;
  13. using namespace std;
  14. //--------------------------------------------
  15. int iPicNum=0;//Set channel NO.
  16. LONG nPort=-1;
  17. HWND hWnd=NULL;
  18. void yv12toYUV(char *outYuv, char *inYv12, int width, int height,int widthStep)
  19. {
  20. int col,row;
  21. unsigned int Y,U,V;
  22. int tmp;
  23. int idx;
  24. //printf("widthStep=%d.\n",widthStep);
  25. for (row=0; row<height; row++)
  26. {
  27. idx=row * widthStep;
  28. int rowptr=row*width;
  29. for (col=0; col<width; col++)
  30. {
  31. //int colhalf=col>>1;
  32. tmp = (row/2)*(width/2)+(col/2);
  33. //         if((row==1)&&( col>=1400 &&col<=1600))
  34. //         {
  35. //          printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
  36. //          printf("row*width+col=%d,width*height+width*height/4+tmp=%d,width*height+tmp=%d.\n",row*width+col,width*height+width*height/4+tmp,width*height+tmp);
  37. //         }
  38. Y=(unsigned int) inYv12[row*width+col];
  39. U=(unsigned int) inYv12[width*height+width*height/4+tmp];
  40. V=(unsigned int) inYv12[width*height+tmp];
  41. //         if ((col==200))
  42. //         {
  43. //         printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
  44. //         printf("width*height+width*height/4+tmp=%d.\n",width*height+width*height/4+tmp);
  45. //         return ;
  46. //         }
  47. if((idx+col*3+2)> (1200 * widthStep))
  48. {
  49. //printf("row * widthStep=%d,idx+col*3+2=%d.\n",1200 * widthStep,idx+col*3+2);
  50. }
  51. outYuv[idx+col*3]   = Y;
  52. outYuv[idx+col*3+1] = U;
  53. outYuv[idx+col*3+2] = V;
  54. }
  55. }
  56. //printf("col=%d,row=%d.\n",col,row);
  57. }
  58. //解码回调 视频为YUV数据(YV12),音频为PCM数据
  59. void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
  60. {
  61. long lFrameType = pFrameInfo->nType;
  62. if(lFrameType ==T_YV12)
  63. {
  64. #if USECOLOR
  65. //int start = clock();
  66. IplImage* pImgYCrCb = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);//得到图像的Y分量
  67. yv12toYUV(pImgYCrCb->imageData, pBuf, pFrameInfo->nWidth,pFrameInfo->nHeight,pImgYCrCb->widthStep);//得到全部RGB图像
  68. IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);
  69. cvCvtColor(pImgYCrCb,pImg,CV_YCrCb2RGB);
  70. //int end = clock();
  71. #else
  72. IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 1);
  73. memcpy(pImg->imageData,pBuf,pFrameInfo->nWidth*pFrameInfo->nHeight);
  74. #endif
  75. //printf("%d\n",end-start);
  76. cvShowImage("IPCamera",pImg);
  77. cvWaitKey(1);
  78. #if USECOLOR
  79. cvReleaseImage(&pImgYCrCb);
  80. cvReleaseImage(&pImg);
  81. #else
  82. cvReleaseImage(&pImg);
  83. #endif
  84. //此时是YV12格式的视频数据,保存在pBuf中,可以fwrite(pBuf,nSize,1,Videofile);
  85. //fwrite(pBuf,nSize,1,fp);
  86. }
  87. /***************
  88. else if (lFrameType ==T_AUDIO16)
  89. {
  90. //此时是音频数据,数据保存在pBuf中,可以fwrite(pBuf,nSize,1,Audiofile);
  91. }
  92. else
  93. {
  94. }
  95. *******************/
  96. }
  97. ///实时流回调
  98. void CALLBACK fRealDataCallBack(LONG lRealHandle,DWORD dwDataType,BYTE *pBuffer,DWORD dwBufSize,void *pUser)
  99. {
  100. DWORD dRet;
  101. switch (dwDataType)
  102. {
  103. case NET_DVR_SYSHEAD:    //系统头
  104. if (!PlayM4_GetPort(&nPort)) //获取播放库未使用的通道号
  105. {
  106. break;
  107. }
  108. if(dwBufSize > 0)
  109. {
  110. if (!PlayM4_OpenStream(nPort,pBuffer,dwBufSize,1024*1024))
  111. {
  112. dRet=PlayM4_GetLastError(nPort);
  113. break;
  114. }
  115. //设置解码回调函数 只解码不显示
  116. if (!PlayM4_SetDecCallBack(nPort,DecCBFun))
  117. {
  118. dRet=PlayM4_GetLastError(nPort);
  119. break;
  120. }
  121. //设置解码回调函数 解码且显示
  122. //if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL))
  123. //{
  124. //  dRet=PlayM4_GetLastError(nPort);
  125. //  break;
  126. //}
  127. //打开视频解码
  128. if (!PlayM4_Play(nPort,hWnd))
  129. {
  130. dRet=PlayM4_GetLastError(nPort);
  131. break;
  132. }
  133. //打开音频解码, 需要码流是复合流
  134. if (!PlayM4_PlaySound(nPort))
  135. {
  136. dRet=PlayM4_GetLastError(nPort);
  137. break;
  138. }
  139. }
  140. break;
  141. case NET_DVR_STREAMDATA:   //码流数据
  142. if (dwBufSize > 0 && nPort != -1)
  143. {
  144. BOOL inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);
  145. while (!inData)
  146. {
  147. Sleep(10);
  148. inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);
  149. OutputDebugString(L"PlayM4_InputData failed \n");
  150. }
  151. }
  152. break;
  153. }
  154. }
  155. void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
  156. {
  157. char tempbuf[256] = {0};
  158. switch(dwType)
  159. {
  160. case EXCEPTION_RECONNECT:    //预览时重连
  161. printf("----------reconnect--------%d\n", time(NULL));
  162. break;
  163. default:
  164. break;
  165. }
  166. }
  167. void main() {
  168. //---------------------------------------
  169. // 初始化
  170. NET_DVR_Init();
  171. //设置连接时间与重连时间
  172. NET_DVR_SetConnectTime(2000, 1);
  173. NET_DVR_SetReconnect(10000, true);
  174. //---------------------------------------
  175. // 获取控制台窗口句柄
  176. //HMODULE hKernel32 = GetModuleHandle((LPCWSTR)"kernel32");
  177. //GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
  178. //---------------------------------------
  179. // 注册设备
  180. LONG lUserID;
  181. NET_DVR_DEVICEINFO_V30 struDeviceInfo;
  182. lUserID = NET_DVR_Login_V30("10.102.7.88", 8000, "admin", "12345", &struDeviceInfo);
  183. if (lUserID < 0)
  184. {
  185. printf("Login error, %d\n", NET_DVR_GetLastError());
  186. NET_DVR_Cleanup();
  187. return;
  188. }
  189. //---------------------------------------
  190. //设置异常消息回调函数
  191. NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);
  192. //cvNamedWindow("IPCamera");
  193. //---------------------------------------
  194. //启动预览并设置回调数据流
  195. NET_DVR_CLIENTINFO ClientInfo;
  196. ClientInfo.lChannel = 1;        //Channel number 设备通道号
  197. ClientInfo.hPlayWnd = NULL;     //窗口为空,设备SDK不解码只取流
  198. ClientInfo.lLinkMode = 0;       //Main Stream
  199. ClientInfo.sMultiCastIP = NULL;
  200. LONG lRealPlayHandle;
  201. lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID,&ClientInfo,fRealDataCallBack,NULL,TRUE);
  202. if (lRealPlayHandle<0)
  203. {
  204. printf("NET_DVR_RealPlay_V30 failed! Error number: %d\n",NET_DVR_GetLastError());
  205. return;
  206. }
  207. //cvWaitKey(0);
  208. Sleep(-1);
  209. //fclose(fp);
  210. //---------------------------------------
  211. //关闭预览
  212. if(!NET_DVR_StopRealPlay(lRealPlayHandle))
  213. {
  214. printf("NET_DVR_StopRealPlay error! Error number: %d\n",NET_DVR_GetLastError());
  215. return;
  216. }
  217. //注销用户
  218. NET_DVR_Logout(lUserID);
  219. NET_DVR_Cleanup();
  220. return;
  221. }

终于能够实时捕获图像了,而且转换成了OpenCV能够处理的图像格式。

在这个过程中搜了很多资料,但是没有一个地方能详细说明,不过最终还是把这个给解决了。

附加说明:如果最后要做图像处理而不是像我这样只是将采集的图像显示出来,那么下面的语句是不需要的。

  1. #if USECOLOR
  2. cvReleaseImage(&pImgYCrCb);
  3. cvReleaseImage(&pImg);
  4. #else
  5. cvReleaseImage(&pImg);
  6. #endif

后记:虽然这个功能实现了,但是与我的图像处理函数如何结合到一起?我想到的是用链队列,双线程。链队列代码请看这里!

写这两篇博文的目的其实也是想让处于探索过程中的开发人员能少走些弯路,节省些时间,衷心希望本文能够帮到你!


因为本人已经毕业,项目也早就已经结题了,手头上不再具有可供调试的硬件设备,因此对于大家所碰到的问题,我基本上也已经无法回答了,非常抱歉!如果大家在开发海康威视摄像头的过程中遇到了什么问题可以去跟海康客服去沟通,如果您所在地区的客服无法联系上的话,请直接联系杭州总部的客服。

最后,对之前很长一段时间对大家所提出的问题一直置之不理再次表示道歉!谢谢大家的支持!

**************************************************************************************

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

**************************************************************************************

在上一篇博文里,我介绍了第一种方法,但是由于NET_DVR_CaptureJPEGPicture_NEW该函数执行需要较长时间,无法实时,所以必须继续第二种方法。

在这篇博文里,我将介绍第二种方法,将捕获到的海康威视IPCamera摄像头图像转成OpenCV能处理的IplImage图像。

在实现完捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图像(一)里面的方法后,发现不能实时,这个系统我是要做给给人看的,是需要实时演示的,这样子肯定是不行的。纠结了好久!然后查看海康威视《设备网络SDK使用手册_V4.2》,里面有一个预览模块示例程序,可惜我一直运行不了,报出的错误是PROCGETCONSOLEWINDOW GetConsoleWindow中的GetConsoleWindow被重定义,后来一直调试没调成功。

实在是没辙了,打海康客服,不过海康的客服我实在无语,北京的完全无法接通,直接打杭州的,打了四五遍终于有个人接电话了,对方不懂,然后说让个工程师回电话。OK,终于回了。他告诉我http://www.hikvision.com/cn/download_more_401.html 这里是有例程的,有分功能示例!突然间有了希望了,例程是VC6.0工程,改了一些地方后,终于能运行了。于是,将他的MFC工程相关的代码抠出来,重组。于是实现了捕获YV12格式的视频流的功能,光有YV12还是不行的,需要将YV12转成YUV4:4:4的,然后再将YUV色度空间转换成RGB色度空间,这个过程是在信件的DecBFun回调函数(回调函数请看这里!)里面执行的。

不多说了,上代码!

[cpp]  view plain copy print ?
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include "Windows.h"
  5. #include "HCNetSDK.h"
  6. #include "PlayM4.h"
  7. #include <opencv2\opencv.hpp>
  8. #include "cv.h"
  9. #include "highgui.h"
  10. #include <time.h>
  11. #define USECOLOR 1
  12. using namespace std;
  13. using namespace std;
  14. //--------------------------------------------
  15. int iPicNum=0;//Set channel NO.
  16. LONG nPort=-1;
  17. HWND hWnd=NULL;
  18. void yv12toYUV(char *outYuv, char *inYv12, int width, int height,int widthStep)
  19. {
  20. int col,row;
  21. unsigned int Y,U,V;
  22. int tmp;
  23. int idx;
  24. //printf("widthStep=%d.\n",widthStep);
  25. for (row=0; row<height; row++)
  26. {
  27. idx=row * widthStep;
  28. int rowptr=row*width;
  29. for (col=0; col<width; col++)
  30. {
  31. //int colhalf=col>>1;
  32. tmp = (row/2)*(width/2)+(col/2);
  33. //         if((row==1)&&( col>=1400 &&col<=1600))
  34. //         {
  35. //          printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
  36. //          printf("row*width+col=%d,width*height+width*height/4+tmp=%d,width*height+tmp=%d.\n",row*width+col,width*height+width*height/4+tmp,width*height+tmp);
  37. //         }
  38. Y=(unsigned int) inYv12[row*width+col];
  39. U=(unsigned int) inYv12[width*height+width*height/4+tmp];
  40. V=(unsigned int) inYv12[width*height+tmp];
  41. //         if ((col==200))
  42. //         {
  43. //         printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
  44. //         printf("width*height+width*height/4+tmp=%d.\n",width*height+width*height/4+tmp);
  45. //         return ;
  46. //         }
  47. if((idx+col*3+2)> (1200 * widthStep))
  48. {
  49. //printf("row * widthStep=%d,idx+col*3+2=%d.\n",1200 * widthStep,idx+col*3+2);
  50. }
  51. outYuv[idx+col*3]   = Y;
  52. outYuv[idx+col*3+1] = U;
  53. outYuv[idx+col*3+2] = V;
  54. }
  55. }
  56. //printf("col=%d,row=%d.\n",col,row);
  57. }
  58. //解码回调 视频为YUV数据(YV12),音频为PCM数据
  59. void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
  60. {
  61. long lFrameType = pFrameInfo->nType;
  62. if(lFrameType ==T_YV12)
  63. {
  64. #if USECOLOR
  65. //int start = clock();
  66. IplImage* pImgYCrCb = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);//得到图像的Y分量
  67. yv12toYUV(pImgYCrCb->imageData, pBuf, pFrameInfo->nWidth,pFrameInfo->nHeight,pImgYCrCb->widthStep);//得到全部RGB图像
  68. IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);
  69. cvCvtColor(pImgYCrCb,pImg,CV_YCrCb2RGB);
  70. //int end = clock();
  71. #else
  72. IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 1);
  73. memcpy(pImg->imageData,pBuf,pFrameInfo->nWidth*pFrameInfo->nHeight);
  74. #endif
  75. //printf("%d\n",end-start);
  76. cvShowImage("IPCamera",pImg);
  77. cvWaitKey(1);
  78. #if USECOLOR
  79. cvReleaseImage(&pImgYCrCb);
  80. cvReleaseImage(&pImg);
  81. #else
  82. cvReleaseImage(&pImg);
  83. #endif
  84. //此时是YV12格式的视频数据,保存在pBuf中,可以fwrite(pBuf,nSize,1,Videofile);
  85. //fwrite(pBuf,nSize,1,fp);
  86. }
  87. /***************
  88. else if (lFrameType ==T_AUDIO16)
  89. {
  90. //此时是音频数据,数据保存在pBuf中,可以fwrite(pBuf,nSize,1,Audiofile);
  91. }
  92. else
  93. {
  94. }
  95. *******************/
  96. }
  97. ///实时流回调
  98. void CALLBACK fRealDataCallBack(LONG lRealHandle,DWORD dwDataType,BYTE *pBuffer,DWORD dwBufSize,void *pUser)
  99. {
  100. DWORD dRet;
  101. switch (dwDataType)
  102. {
  103. case NET_DVR_SYSHEAD:    //系统头
  104. if (!PlayM4_GetPort(&nPort)) //获取播放库未使用的通道号
  105. {
  106. break;
  107. }
  108. if(dwBufSize > 0)
  109. {
  110. if (!PlayM4_OpenStream(nPort,pBuffer,dwBufSize,1024*1024))
  111. {
  112. dRet=PlayM4_GetLastError(nPort);
  113. break;
  114. }
  115. //设置解码回调函数 只解码不显示
  116. if (!PlayM4_SetDecCallBack(nPort,DecCBFun))
  117. {
  118. dRet=PlayM4_GetLastError(nPort);
  119. break;
  120. }
  121. //设置解码回调函数 解码且显示
  122. //if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL))
  123. //{
  124. //  dRet=PlayM4_GetLastError(nPort);
  125. //  break;
  126. //}
  127. //打开视频解码
  128. if (!PlayM4_Play(nPort,hWnd))
  129. {
  130. dRet=PlayM4_GetLastError(nPort);
  131. break;
  132. }
  133. //打开音频解码, 需要码流是复合流
  134. if (!PlayM4_PlaySound(nPort))
  135. {
  136. dRet=PlayM4_GetLastError(nPort);
  137. break;
  138. }
  139. }
  140. break;
  141. case NET_DVR_STREAMDATA:   //码流数据
  142. if (dwBufSize > 0 && nPort != -1)
  143. {
  144. BOOL inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);
  145. while (!inData)
  146. {
  147. Sleep(10);
  148. inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);
  149. OutputDebugString(L"PlayM4_InputData failed \n");
  150. }
  151. }
  152. break;
  153. }
  154. }
  155. void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
  156. {
  157. char tempbuf[256] = {0};
  158. switch(dwType)
  159. {
  160. case EXCEPTION_RECONNECT:    //预览时重连
  161. printf("----------reconnect--------%d\n", time(NULL));
  162. break;
  163. default:
  164. break;
  165. }
  166. }
  167. void main() {
  168. //---------------------------------------
  169. // 初始化
  170. NET_DVR_Init();
  171. //设置连接时间与重连时间
  172. NET_DVR_SetConnectTime(2000, 1);
  173. NET_DVR_SetReconnect(10000, true);
  174. //---------------------------------------
  175. // 获取控制台窗口句柄
  176. //HMODULE hKernel32 = GetModuleHandle((LPCWSTR)"kernel32");
  177. //GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
  178. //---------------------------------------
  179. // 注册设备
  180. LONG lUserID;
  181. NET_DVR_DEVICEINFO_V30 struDeviceInfo;
  182. lUserID = NET_DVR_Login_V30("10.102.7.88", 8000, "admin", "12345", &struDeviceInfo);
  183. if (lUserID < 0)
  184. {
  185. printf("Login error, %d\n", NET_DVR_GetLastError());
  186. NET_DVR_Cleanup();
  187. return;
  188. }
  189. //---------------------------------------
  190. //设置异常消息回调函数
  191. NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);
  192. //cvNamedWindow("IPCamera");
  193. //---------------------------------------
  194. //启动预览并设置回调数据流
  195. NET_DVR_CLIENTINFO ClientInfo;
  196. ClientInfo.lChannel = 1;        //Channel number 设备通道号
  197. ClientInfo.hPlayWnd = NULL;     //窗口为空,设备SDK不解码只取流
  198. ClientInfo.lLinkMode = 0;       //Main Stream
  199. ClientInfo.sMultiCastIP = NULL;
  200. LONG lRealPlayHandle;
  201. lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID,&ClientInfo,fRealDataCallBack,NULL,TRUE);
  202. if (lRealPlayHandle<0)
  203. {
  204. printf("NET_DVR_RealPlay_V30 failed! Error number: %d\n",NET_DVR_GetLastError());
  205. return;
  206. }
  207. //cvWaitKey(0);
  208. Sleep(-1);
  209. //fclose(fp);
  210. //---------------------------------------
  211. //关闭预览
  212. if(!NET_DVR_StopRealPlay(lRealPlayHandle))
  213. {
  214. printf("NET_DVR_StopRealPlay error! Error number: %d\n",NET_DVR_GetLastError());
  215. return;
  216. }
  217. //注销用户
  218. NET_DVR_Logout(lUserID);
  219. NET_DVR_Cleanup();
  220. return;
  221. }

终于能够实时捕获图像了,而且转换成了OpenCV能够处理的图像格式。

在这个过程中搜了很多资料,但是没有一个地方能详细说明,不过最终还是把这个给解决了。

附加说明:如果最后要做图像处理而不是像我这样只是将采集的图像显示出来,那么下面的语句是不需要的。

  1. #if USECOLOR
  2. cvReleaseImage(&pImgYCrCb);
  3. cvReleaseImage(&pImg);
  4. #else
  5. cvReleaseImage(&pImg);
  6. #endif

后记:虽然这个功能实现了,但是与我的图像处理函数如何结合到一起?我想到的是用链队列,双线程。链队列代码请看这里!

写这两篇博文的目的其实也是想让处于探索过程中的开发人员能少走些弯路,节省些时间,衷心希望本文能够帮到你!

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

海康威视IPCamera图像捕获 二种方法相关推荐

  1. 海康威视IPCamera图像捕获方法:捕获实时流,将实时流解码成YV12,然后转换成RGB

    将他的MFC工程相关的代码抠出来,重组.于是实现了捕获YV12格式的视频流的功能,光有YV12还是不行的,需要将YV12转成YUV4:4:4的,然后再将YUV色度空间转换成RGB色度空间,这个过程是在 ...

  2. 捕获海康威视IPCamera图像,转成OpenCV能够处理的图像(二)

    海康威视IPCamera图像捕获 捕获海康威视IPCamera图像.转成OpenCV能够处理的IplImage图像(一) 捕获海康威视IPCamera图像.转成OpenCV能够处理的IplImage图 ...

  3. 捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(二)

    捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(二) 标签: 捕获图像海康威视IPCameraOpenCVIplImage 2014-06-16 18:59 15424人阅读 评论( ...

  4. 捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(一)

    海康威视IPCamera图像捕获 捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图像(一) 捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图 ...

  5. matlab批量处理程序设计,Matlab实现批量处理图像的两种方法

    Matlab实现批量处理图像的两种方法 基本上有两个方法:一个是将你的图像统一进行一次重命名如:1.jpg,2.jpg等,然后利用for循环依次进行处理即可,如下面的语句:假设你的图像共有20副: s ...

  6. 几何画板中作函数图像的几种方法

    随着社会的发展,现代教学很多的地方都有了多媒体教学,这就需要一些教学软件的辅助了,几何画板就是其中之一.一些老师在使用几何画板的过程中,常常涉及到函数图象的绘制.因此,很多用户对这方面教程是非常的感兴 ...

  7. debian7更换gcc版本的二种方法分享

    debian7更换gcc版本的二种方法分享 最近在编译qt,之前用的是debian6,gcc版本是gcc-4.4,当使用debian7时,编译遇到了很多跟debian6不一样的问题,debian7的默 ...

  8. mysql远程连接数据库的二种方法_mysql 远程连接数据库的二种方法

    mysql 远程连接数据库的二种方法 一.连接远程数据库: 1.显示密码 如:MySQL 连接远程数据库(192.168.5.116),端口"3306",用户名为"roo ...

  9. oracle 数据导入 mysql_oracle数据库导出和oracle导入数据的二种方法(oracle导入导出数据)...

    这篇文章主要介绍了oracle导入导出数据的二种方法,利用PL/SQL Developer工具导出和利用cmd的操作命令导出的出方法,大家参考使用吧 方法一:利用PL/SQL Developer工具导 ...

最新文章

  1. 【Python】Label组件 Button组件 Checkbutton组件
  2. [patl2-018]多项式A除以B
  3. C# 添加xml节点多了xmlns属性问题
  4. 网络搜索,抵制日货的新方法
  5. 【实战】感恩教师节小程序制作
  6. eclipse关联本地maven仓库和配置
  7. 美国0封伊朗已经6天了,伊石油出口真归零了吗?
  8. 正则表达式如何匹配正反斜杠
  9. 灵魂拷问:到底要不要写单元测试,如何正确进行单元测试?
  10. CCPC-EDG专场——E.Buy and Delete
  11. 【Luogu1345】周游加拿大(动态规划)
  12. Android 四大组件 之 BroadcastReceiver(广播接收者)
  13. 用户计算机MAC地址在哪看,电脑mac地址查询_mac地址怎么查-太平洋IT百科
  14. 自动薅羊毛技术方案总结
  15. Laya.TextInput组件中禁用后改变输入框背景色和文字颜色
  16. 一年中最后一个月的最后一天说说_2020只剩最后一个月的励志说说致自己
  17. 揭开500亿“区块链”骗局
  18. 微信小程序上传图片 预览 删除
  19. mac os 苹果操作系统如何切换输入法
  20. 如何建设一个优质的企业网站?

热门文章

  1. Android9 HWbinder使用-注册service流程解析
  2. Tensorflow变量作用域及变量初始化
  3. 特色棒球夏令营·棒球1号位
  4. 【BZOJ2152】聪聪可可 树分治
  5. 计算天数(C语言)——罡罡同学
  6. python合并word表格单元格_Python-Excel转word表格并合并流程
  7. 华为机试:火星符号运算
  8. 科大奥瑞物理实验——傅里叶光学
  9. Vue3不支持eventBus
  10. 社区智能化视频监控系统建设方案设计