1.MFC-opencv配置:

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

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

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

             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.lib
opencv_contrib248d.lib
opencv_core248d.lib
opencv_features2d248d.lib
opencv_flann248d.lib
opencv_gpu248d.lib
opencv_highgui248d.lib
opencv_imgproc248d.lib
opencv_legacy248d.lib
opencv_ml248d.lib
opencv_nonfree248d.lib
opencv_objdetect248d.lib
opencv_ocl248d.lib
opencv_photo248d.lib
opencv_stitching248d.lib
opencv_superres248d.lib
opencv_ts248d.lib
opencv_video248d.lib
opencv_videostab248d.lib

2.

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

    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. 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. int) inYv12[row*width+col];  
    45. int) inYv12[width*height+width*height/4+tmp];  
    46. 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. //得到图像的Y分量    
    77. //得到全部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. "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. "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. "----------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. 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. "10.102.7.88", 8000, "admin", "12345", &struDeviceInfo);  
    207. if (lUserID < 0)  
    208.   {  
    209. "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. //Channel number 设备通道号  
    224. //窗口为空,设备SDK不解码只取流  
    225. //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. "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. "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