MFC中使用opencv获取海康摄像头视频

来源:互联网 发布:怎么校准网络时间 编辑:程序博客网 时间:2024/05/02 01:50

1.MFC-opencv配置:

新建一个空白项目,点击项目(菜单项)-属性-VC++目录,按照下图提示,添加目录:

可执行文件目录D:\Program Files\opencv\build\x86\vc10\bin 

包含目录D:\Program Files\opencv\build\include 

     D:\Program Files\opencv\build\include\opencv 

             D:\Program Files\opencv\build\include\opencv2 

库目录D:\Program Files\opencv\build\x86\vc10\lib  (本人64位机选64位错误,海康的也要选x86的lib,原因不懂,小白阶段)

配置连接器:项目(菜单项)->…属性->连接器->输入->附加依赖项(Debug版本,Release的**.lib),遇到无法解析的外部符号一般是忘了添加lib了。以下仅为opencv的lib,海康的lib自行脑补。

opencv_calib3d248d.libopencv_contrib248d.libopencv_core248d.libopencv_features2d248d.libopencv_flann248d.libopencv_gpu248d.libopencv_highgui248d.libopencv_imgproc248d.libopencv_legacy248d.libopencv_ml248d.libopencv_nonfree248d.libopencv_objdetect248d.libopencv_ocl248d.libopencv_photo248d.libopencv_stitching248d.libopencv_superres248d.libopencv_ts248d.libopencv_video248d.libopencv_videostab248d.lib
2.捕获实时流,将实时流解码成YV12,然后转换成RGB(转自http://blog.csdn.net/wanghuiqi2008/article/details/31410509)

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  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 rowptr=row*width;  
  34.   
  35.       for (col=0; col<width; col++)  
  36.       {  
  37.          //int colhalf=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. }  


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

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

 

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

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

0 0
原创粉丝点击