海康网络摄像机视频数据的获取及使用opencv显示

来源:互联网 发布:安捷伦34401a 编程 编辑:程序博客网 时间:2024/05/21 12:44

最近要使用海康威视摄像机获取数据做处理。主要是借助Opencv这个工具,所以做了一下步骤。
我用的是基于Qt+opencv的来显示海康数据的。本人海康的型号为:DS-2CD2820FD
1、海康sdk开发环境的配置(我只给出我的配置路径,视具体情况而定)

LIBS += -LD:\Softwares\HaiKang\x64\lib\-lHCNetSDK \-lGdiPlus \-lHCCore \-lPlayCtrlLIBS += -LD:\Softwares\HaiKang\x64\lib\HCNetSDKCom\-lHCAlarm \-lHCGeneralCfgMgr \-lHCPreview

2、包含的头文件

#include<stdio.h>#include<iostream>#include<time.h>#include<Windows.h>#include<HCNetSDK.h>#include<plaympeg4.h>#include<cstring>using namespace std;#include"./opencv2/opencv.hpp"using namespace  cv;typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();PROCGETCONSOLEWINDOW GetConsoleWindowAPI;

3、具体的实现代码如下:

LONG nPort=-1; //全局的播放库port号//数据类型转换void yv12toYUV(uchar *outYuv, uchar *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;        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];            outYuv[idx+col*3]   = Y;            outYuv[idx+col*3+1] = U;            outYuv[idx+col*3+2] = V;        }    }}////解码回调 视频为YUV数据(YV12)void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2){    long lFrameType = pFrameInfo->nType;    if(lFrameType ==T_YV12)    {       Mat matYCrCb=Mat(pFrameInfo->nHeight, pFrameInfo->nWidth,CV_8UC3);       Mat matImge=Mat(pFrameInfo->nHeight, pFrameInfo->nWidth,CV_8UC3);       yv12toYUV(matYCrCb.data,(uchar*)pBuf,pFrameInfo->nWidth,pFrameInfo->nHeight,matYCrCb.step);       cvtColor(matYCrCb,matImge,CV_YCrCb2RGB);       imshow("matImge IPCamera",matImge);       waitKey(1);//一定记得加不然会出错    }}void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,void* dwUser){      HWND hWnd=GetConsoleWindowAPI();      DWORD dRet;      switch (dwDataType)      {      case NET_DVR_SYSHEAD:    //系统头          if (!PlayM4_GetPort(&nPort)) //获取播放库未使用的通道号          {              break;          }          if(dwBufSize > 0)          {              if (!PlayM4_OpenStream(nPort,pBuffer,dwBufSize,1024*1024))              {                  dRet=PlayM4_GetLastError(nPort);                  break;              }              //设置解码回调函数 只解码不显示              if (!PlayM4_SetDecCallBack(nPort,DecCBFun))              {                  dRet=PlayM4_GetLastError(nPort);                  break;              }              //设置解码回调函数 解码且显示              //if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL))              //{              //  dRet=PlayM4_GetLastError(nPort);              //  break;              //}              //打开视频解码              if (!PlayM4_Play(nPort,hWnd))              {                  dRet=PlayM4_GetLastError(nPort);                  break;              }              //打开音频解码, 需要码流是复合流              if (!PlayM4_PlaySound(nPort))              {                  dRet=PlayM4_GetLastError(nPort);                  break;              }          }          break;      case NET_DVR_STREAMDATA:   //码流数据          if (dwBufSize > 0 && nPort != -1)          {              BOOL inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);              while (!inData)              {                  Sleep(10);                  inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);                  OutputDebugString(L"PlayM4_InputData failed \n");              }          }          break;      }}void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser){    char tempbuf[256] = {0};    switch(dwType)    {    case EXCEPTION_RECONNECT:    //预览时重连    printf("----------reconnect--------%d\n", time(NULL));    break;    default:    break;    }}void main() {  //---------------------------------------  // 初始化  NET_DVR_Init();  //设置连接时间与重连时间  NET_DVR_SetConnectTime(2000, 1);  NET_DVR_SetReconnect(10000, true);  //---------------------------------------  //设置异常消息回调函数  NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);  //---------------------------------------  // 获取控制台窗口句柄  HMODULE hKernel32 = GetModuleHandle(L"kernel32");  GetConsoleWindowAPI = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");  //---------------------------------------  // 注册设备  LONG lUserID;  //登录参数,包括设备地址、登录用户、密码等  NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};  struLoginInfo.bUseAsynLogin = 0; //同步登录方式  strcpy(struLoginInfo.sDeviceAddress, "192.168.10.64"); //设备IP地址  struLoginInfo.wPort = 8000; //设备服务端口  strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名  strcpy(struLoginInfo.sPassword, "admin123"); //设备登录密码  //设备信息, 输出参数  NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};  lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);  if (lUserID < 0)  {      printf("Login failed, error code: %d\n", NET_DVR_GetLastError());      NET_DVR_Cleanup();      return;  }  //---------------------------------------  //启动预览并设置回调数据流  LONG lRealPlayHandle;  NET_DVR_PREVIEWINFO struPlayInfo = {0};  struPlayInfo.hPlayWnd     = NULL;         //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空  struPlayInfo.lChannel     = 1;       //预览通道号  struPlayInfo.dwStreamType = 0;       //0-主码流,1-子码流,2-码流3,3-码流4,以此类推  struPlayInfo.dwLinkMode   = 0;       //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP  struPlayInfo.bBlocked     = 1;       //0- 非阻塞取流,1- 阻塞取流  lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL);  if (lRealPlayHandle < 0)  {      printf("NET_DVR_RealPlay_V40 error, %d\n", NET_DVR_GetLastError());      NET_DVR_Logout(lUserID);      NET_DVR_Cleanup();      return;  }  Sleep(-1);  //---------------------------------------  //关闭预览  NET_DVR_StopRealPlay(lRealPlayHandle);  //注销用户  NET_DVR_Logout(lUserID);  NET_DVR_Cleanup();  return;}
阅读全文
1 0
原创粉丝点击