海康抓拍机SDK开发
前言
项目采购的海康威视的抓拍机,需要首先获取抓拍图片,之后基于抓拍图片进行图像处理。本文基于海康SDK开发文档,按照开发步骤,咨询海康技术人员,现将开发过程记录如下。
主要过程的c++代码:
/************************************************************************
* Copyright(c) 2016 ZRJ
* All rights reserved.
*
* File: snap.h
* Brief: 抓拍机配置头文件
* Version: 1.0
* Author: ZRJ
* Email: happyamyhope@163.com
* Date: 2016/12/08
* History:
* 20161202: 添加布防级别与退出撤防功能;
* 20161207: 设置抓拍等待时间等;添加系统时间;
* 20161208: 添加复制文件夹操作;
* 20161208: 添加启动程序初始化图片不保存;删除网络触发抓拍部分;
* 20161209: 删除网络触发抓拍部分;
* 20161220: 现场调试增加的功能;
* 20170109: 删除FIFO队列数据;
* 20170123: 添加创建文件夹功能,删除预览取流部分; ************************************************************************/
//-------------------------------------------------------------------------
//头文件
#include <stdio.h>
#include <iostream>
#include "Windows.h"
#include "HCNetSDK.h"
//获取系统时间
#include <time.h> //OPENCV库文件
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2\opencv.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std; typedef HWND(WINAPI *PROCGETCONSOLEWINDOW)();
PROCGETCONSOLEWINDOW Getconsolewindow; //-----------------------------------------------------------------------
//调参
int iNum = ;//抓拍图片的数目初始化值
int pic_number = ;//抓拍文件夹存图数目
//int j = 1;//显示抓拍图片的数目
//注册设备
LONG IUserID;//摄像机设备
char *sDVRIP = "10.0.10.3";//抓拍摄像机设备IP地址
short wDVRPort = ;//设备端口号
char* sUserName = "admin";//登录的用户名
char* sPassword = "admin123";//用户密码
//
time_t t;
char now[]; //
int fifo_flag = ;//队列标志;
double interval_time;//当前抓拍图片与前一帧抓拍时间之差;单位是ms;
double interval_time_thres = ;//前后两帧抓拍时间间隔阈值40s;单位是ms;
double pre_time;//系统开始时间;前一次抓拍图片的时间点;
double cur_time; //
LONG IHandle = -;//报警布防;
bool snap_flag = false;//是否抓拍的标志位
NET_DVR_DEVICEINFO_V30 struDeviceInfo;//设备信息 //---------------------------------------------------------------------------------
//函数声明
BOOL SHDeleteFolder(LPCTSTR pstrFolder);//删除指定目录
void CopyFolder(SHFILEOPSTRUCT fop);//抓拍图片文件夹操作
void CreateFolder(char* filename);//不存在则创建文件夹;
void Init();//初始化
void Connect();//设置连接事件与重连时间
bool Login(char *sDVRIP, short wDVRPort, char *sUserName, char *sPassword);//注册摄像机设备
void CALLBACK MSesGCallback(LONG ICommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void *pUser);//报警回调函数
void SetMessageCallBack();//设置报警回调函数
void SetupAlarm();//报警布防
void CloseAlarm();//报警撤防
void OnExit(void);//退出
extern int snap();//抓拍 //-----------------------------------------------------------------------------------------
//函数定义 //初始化
void Init()
{
NET_DVR_Init();
}
//设置连接事件与重连时间
void Connect()
{
NET_DVR_SetConnectTime(, );
NET_DVR_SetReconnect(, true);
}
//注册摄像机设备
bool Login(char *sDVRIP, short wDVRPort, char *sUserName, char *sPassword)
{
IUserID = NET_DVR_Login_V30(sDVRIP, wDVRPort, sUserName, sPassword, &struDeviceInfo); if (IUserID < )
{
std::cout << "Login Failed! Error number:" << NET_DVR_GetLastError() << std::endl;
NET_DVR_Cleanup();
return false;
}
else
{
std::cout << "Login Successfully!" << std::endl;
return true;
} }
//报警回调函数
void CALLBACK MSesGCallback(LONG ICommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void *pUser)
{
//unsigned int i = 0;
char filename[];
FILE *fSnapPic = NULL;
//std::cout << "Callback MSesGCallback one time..." << std::endl;
//std::cout << "ICommand:" << ICommand << std::endl;
//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理 switch (ICommand)
{
case COMM_UPLOAD_PLATE_RESULT://交通抓拍结果(老报警消息)
{
NET_DVR_PLATE_RESULT struPlateResult = { };
memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult)); //获取场景图
if (struPlateResult.dwPicLen != && struPlateResult.byResultType == )
{
snap_flag = true;
//计时
cur_time = (double)getTickCount();//当前抓拍图片的时间点;
t = time(NULL);//系统当前时间
strftime(now, sizeof(now), "%Y%m%dT%H%M%S", localtime(&t));
sprintf(filename, ".\\pic\\testpic%d_%s.jpg", iNum, now);
fSnapPic = fopen(filename, "wb");
fwrite(struPlateResult.pBuffer1, struPlateResult.dwPicLen, , fSnapPic); //前后两次抓拍图片的时间差
if (fifo_flag == )//系统开始
{
interval_time = ;
fifo_flag = ;
}
else
{
interval_time = (cur_time - pre_time) * / (getTickFrequency());//单位是ms;
} //fifo标志位转换
if (interval_time > interval_time_thres)
{
if (fifo_flag == )
{
fifo_flag = ;
}
else if (fifo_flag == )
{
fifo_flag = ;
}
}
//std::cout << "fifo_flag: " << fifo_flag << std::endl;
//获取抓拍图片队列
if (fifo_flag == )
{
std::cout << "fifo1 push back one time..." << std::endl;
}
else if (fifo_flag == )
{
std::cout << "fifo2 push back one time..." << std::endl;
} iNum++;
if (pic_number == iNum)
{
iNum = ;
CopyFolder(fop);//抓拍图片文件夹操作
}
else
{ }
pre_time = cur_time;
fclose(fSnapPic);
}
else
{
snap_flag = false;
} //其他信息处理
break; }
case COMM_ITS_PLATE_RESULT://交通抓拍结果(新报警信息)
{
NET_ITS_PLATE_RESULT struITSPlateResult = { };//识别结果结构体;dwPicNum
memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));
struITSPlateResult.dwPicNum = ;//图片数量(与byGroupNum不同,代表本条信息附带的图片数量)
//保存场景图
if ((struITSPlateResult.struPicInfo[].dwDataLen != ) && (struITSPlateResult.struPicInfo[].byType == ))
{
snap_flag = true;
//计时
cur_time = (double)getTickCount();
//系统当前时间
t = time(NULL);
strftime(now, sizeof(now), "%Y%m%dT%H%M%S", localtime(&t));
sprintf(filename, ".\\pic\\testITSpic%d_%s.jpg", iNum, now);
fSnapPic = fopen(filename, "wb");
fwrite(struITSPlateResult.struPicInfo[].pBuffer, struITSPlateResult.struPicInfo[].dwDataLen, , fSnapPic); //前后两次抓拍图片的时间差
if (fifo_flag == )//系统开始
{
interval_time = ;
fifo_flag = ;
}
else
{
interval_time = (cur_time - pre_time) * / (getTickFrequency());//单位是ms;
}
//std::cout << "interval_time: " << interval_time << std::endl; //fifo标志位转换
if (interval_time > interval_time_thres)
{
if (fifo_flag == )
{
fifo_flag = ;
}
else if (fifo_flag == )
{
fifo_flag = ;
}
}
//std::cout << "fifo_flag: " << fifo_flag << std::endl;
//获取抓拍图片队列
if (fifo_flag == )
{
std::cout << "fifo1 push back one time..." << std::endl;
}
else if (fifo_flag == )
{
std::cout << "fifo2 push back one time..." << std::endl;
} iNum++;
if (pic_number == iNum)
{
iNum = ;
CopyFolder(fop);//抓拍图片文件夹操作
}
else
{ }
pre_time = cur_time;
//std::cout << "pre_time: " << pre_time << std::endl; fclose(fSnapPic);
}
else
{
snap_flag = false;
}
//其他处理信息......
break;
} default:
break; } return;
}
//设置报警回调函数
void SetMessageCallBack()
{
NET_DVR_SetDVRMessageCallBack_V30(MSesGCallback, NULL);
}
//报警布防
void SetupAlarm()
{
//启动布防
NET_DVR_SETUPALARM_PARAM struSetupParam = { };
struSetupParam.dwSize = sizeof(NET_DVR_SETUPALARM_PARAM); //上传报警信息类型:0-老报警信息(NET_DVR_PLATE_RESULT), 1-新报警信息(NET_ITS_PLATE_RESULT)
struSetupParam.byAlarmInfoType = ;
struSetupParam.byLevel = ;//布防优先级:0- 一等级(高),1- 二等级(中),2- 三等级(低)
//bySupport 按位表示,值:0 - 上传,1 - 不上传; bit0 - 表示二级布防是否上传图片; IHandle = NET_DVR_SetupAlarmChan_V41(IUserID, &struSetupParam);//建立报警上传通道,获取报警等信息。
if (IHandle < )
{
std::cout << "NET_DVR_SetupAlarmChan_V41 Failed! Error number:" << NET_DVR_GetLastError() << std::endl;
NET_DVR_Logout(IUserID);
NET_DVR_Cleanup();
return;
}
std::cout << "\n" << endl; }
//报警撤防
void CloseAlarm()
{
//撤销布防上传通道
if (!NET_DVR_CloseAlarmChan_V30(IHandle))//布防句柄IHandle
{
std::cout << "NET_DVR_CloseAlarmChan_V30 Failed! Error number:" << NET_DVR_GetLastError() << std::endl;
NET_DVR_Logout(IUserID);
NET_DVR_Cleanup();
return;
}
IHandle = -;//布防句柄;
} void OnExit(void)
{
std::cout << "Begin exit..." << std::endl; //报警撤防
CloseAlarm(); //释放相机
NET_DVR_Logout(IUserID);//注销用户
NET_DVR_Cleanup();//释放SDK资源
}
//抓拍
extern int snap()
{
atexit(OnExit);
int CycleCount = ;
bool LoginSuccess = false; //获取控制台窗口句柄
HMODULE hKernel32 = GetModuleHandle("kernel32");
Getconsolewindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32, "GetConsoleWindow"); CreateFolder(picfile);//不存在则创建文件夹;
CreateFolder(savepicfile);//不存在则创建文件夹;
Init();//初始化
Connect();//设置连接事件与重连时间
//注册设备
if (Login(sDVRIP, wDVRPort, sUserName, sPassword))
{
LoginSuccess = true;
SetMessageCallBack();//设置报警回调函数
SetupAlarm();//报警布防
return ;
}
else
{
for (int i = ; i < CycleCount; i++)
{
std::cout << "Begin to Login again......" << std::endl;
if (Login(sDVRIP, wDVRPort, sUserName, sPassword))
{
LoginSuccess = true;
SetMessageCallBack();//设置报警回调函数
SetupAlarm();//报警布防
break;
}
}
if (!LoginSuccess)
{
std::cout << "Failed! The application has tried 10 times to login. But still can not login! Press any key to exit......" << std::endl;
}
}
return -; } int main()
{
atexit(OnExit);
snap();
getchar(); }
注意:
1.第一步需要配置SDK和opencv相关文件;
2.熟悉抓拍机SDk的开发流程,可参见开发文档;
3.布防成功之后,需要添加退出撤防功能;
4.保存图片可能需要用到相关文件夹操作;
5.预览取流部分可以根据需要选择,为了实时性本文没有使用;
6.为了之后的图像处理过程,将图片数据存在FIFO队列中,但一定要记得及时删除相应的队列,否则会造成内存泄漏,从而导致系统崩溃(宝宝就不小心犯了这样的低级错误,以此为戒!!!);
7.布防级别的设置,这个一定要问清楚技术支持,因为你根本就查不到,反正宝宝没有查到!!!宝宝委屈但宝宝不说~~~
体会
第一次接触SDk开发,期间真是各种心酸,说多了都是泪~~~不过,整个过程首先你需要知道大致的框架和流程,认真研读需要部分的开发文档,一般也会有代码示例可以参考,按照文档的思路走你就一定会成功的,相信自己!!!中间过程如果遇到任何问题可以及时咨询技术支持,最好邮件联系,那段时间海康的技术支持可能都记着宝宝啦~~另外,第一次做某件事情担心害怕也是正常的,但是你一定要相信自己,静下心去做,只有真正去实践了,才会遇到问题,遇到问题也不要怕更不要急躁,可以查资料,可以问大神,可以问技术支持,总会解决的!!!无论做什么事情都要一步步去做,在实践的过程中所有问题和答案就会越来越清晰了~~
完
海康抓拍机SDK开发的更多相关文章
- 海康设备网络SDK 编程
http://www.cnblogs.com/qtblog/p/5366276.html http://www.hikvision.com/Cn/download_more_401.html
- C#制作ActiveX控件中调用海康SDK的问题
事情是这样的,有一台海康威视的摄像头,客户需要一个ActiveX控件嵌入到网页中,通过点击按钮开始录制和结束录制来进行视频的录制和保存,关于海康摄像头的二次开发在此就不多说了,可以参考SDK中的说明. ...
- Java 实现 海康摄像头抓拍图像 Windows、Linux
先抱怨一下,打死都想不到,海康的摄像头SDK居然是一个Java类,还有必须的两个jar包(jna.jar,examples.jar).鬼能想得到会这么命名. 下面开始吧. Windows 把从官网下载 ...
- 海康PTZ云台摄像头调试之直接控制云台(C#)
众所周知,海康的摄像头sdk较为完善,但是对于新手来说还是有点麻烦. 今天写一篇随笔给大家展示下怎么控制海康摄像头的云台(前提是有ptz云台设备) 1.sdk准备 本文基于C#的frame来开发一个p ...
- 使用golang对海康sdk进行业务开发
目录 准备工作 开发环境信息 改写HCNetSDK.h头文件 开发过程 基本数据类型转换 业务开发 参考 项目最近需要改造升级:操作海康摄像头(包括登录,拍照,录像)等基本功能.经过一段时间研究后,发 ...
- Java二次开发海康SDK-对接门禁机
写在最前 SDK版本:CH-HCNetSDKV6.1.6.45_build20210302_win64 参考文档:海康SDK使用手册_V6.1 对接测试设备型号:DS-K1T671M 设备序列号:E5 ...
- 海康SDK编程指南(C#二次开发版本)
海康SDK编程指南 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文 ...
- 海康相机SDK二次开发只有视频无声音问题
海康SDK相信做企业开发的的同仁,在项目中经常会用到,毕竟使用范围这么广. 本次就开发遇到的奇葩问题来说明一下我们的解决方案. 场景 虽然海康有4200客户端,但是对于高度定制化的项目,肯定不能再使用 ...
- 海康相机开发(1) SDK安装和开发
1.1 安装包获取 从官网下载最新版本的MVS安装包,支持Windows xp.Windows 7.Windows 8.Windows 10的32和64位系统.安装过程默认即可. 官网下载链接:htt ...
随机推荐
- zzw原创_LIKE与regexp_like中的_及转义符
1.select table_name from user_tables where table_name like 'MENU%';查出以下表MENUMENUGGG_131MENU_132MENU ...
- IDEA如何导入一个web+maven以及如何运行项目
IDEA如何导入一个web+maven以及如何运行项目 然后就可以运行你的maven项目了....
- 九校模拟——餐馆(restaurant)
1 餐馆(restaurant) 1.1 题目背景 铜企鹅是企鹅餐馆的老板,他正在计划如何使得自己本年度收益增加. 1.2 题目描述 共有n 种食材,一份食材i 需要花ti 小时不间断地进行播种,施肥 ...
- iOS 面试总结
APP崩溃 启动秒退 在新 iOS 上正常的应用,到了老版本 iOS 上秒退最常见原因是系统动态链接库或Framework无法找到.这种情况通常是由于 App 引用了一个新版操作系统里的动态库(或者某 ...
- Linux 环境下 网络IO模型
本文讨论的背景是Linux环境下的network IO. IO发生时涉及的对象和步骤: 对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的proce ...
- Python线程二
转自:https://www.cnblogs.com/chengd/articles/7770898.html 1. threading.Lock() import threading balance ...
- 使用python将excel数据导入数据库
使用python将excel数据导入数据库 因为需要对数据处理,将excel数据导入到数据库,记录一下过程. 使用到的库:xlrd 和 pymysql (如果需要写到excel可以使用xlwt) 直接 ...
- ie edge 自动给数字加下划线
<meta name="format-detection" content="telephone=no,email=no,address=no">
- 尚学堂java答案解析 第一章
本答案为本人个人编辑,仅供参考,如果读者发现,请私信本人或在下方评论,提醒本人修改 一.选择题: 1.C 解析:java为了安全,中并没有引入C语言的指针概念. 2.AD 解析:B:Java先通过ja ...
- Dom操作注意事项
Dom操作注意事项 基本概念: 在 HTML DOM (文档对象模型)中,每个部分都是节点: 文档本身是文档节点 所有 HTML 元素是元素节点 所有 HTML 属性是属性节点 HTML 元素内的文本 ...