·您当前的位置:首页 > 技术教程 > 海康大华监控技术 >

[海康监控]海康监控摄像头IPCamera图像捕获

时间:2015-11-19 16:07雪水
[海康监控]利用SDK里面的NET_DVR_CaptureJPEGPicture_NEW进行视频抓图

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

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

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

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

在上一篇博文里,我介绍了第一种方法,但是由于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回调函数(回调函数请看这里!)里面执行的。

不多说了,上代码!

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

http://blog.csdn.net/wanghuiqi2008/article/details/31410509

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器