您的位置:首页 > 理论基础 > 计算机网络

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

2017-09-01 15:11 609 查看
最近要使用海康威视摄像机获取数据做处理。主要是借助Opencv这个工具,所以做了一下步骤。

我用的是基于Qt+opencv的来显示海康数据的。本人海康的型号为:DS-2CD2820FD

1、海康sdk开发环境的配置(我只给出我的配置路径,视具体情况而定)

LIBS += -LD:\Softwares\HaiKang\x64\lib\
-lHCNetSDK \
-lGdiPlus \
-lHCCore \
-lPlayCtrl

LIBS += -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
4000
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: