前言

项目采购的海康威视的抓拍机,需要首先获取抓拍图片,之后基于抓拍图片进行图像处理。本文基于海康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开发的更多相关文章

  1. 海康设备网络SDK 编程

    http://www.cnblogs.com/qtblog/p/5366276.html http://www.hikvision.com/Cn/download_more_401.html

  2. C#制作ActiveX控件中调用海康SDK的问题

    事情是这样的,有一台海康威视的摄像头,客户需要一个ActiveX控件嵌入到网页中,通过点击按钮开始录制和结束录制来进行视频的录制和保存,关于海康摄像头的二次开发在此就不多说了,可以参考SDK中的说明. ...

  3. Java 实现 海康摄像头抓拍图像 Windows、Linux

    先抱怨一下,打死都想不到,海康的摄像头SDK居然是一个Java类,还有必须的两个jar包(jna.jar,examples.jar).鬼能想得到会这么命名. 下面开始吧. Windows 把从官网下载 ...

  4. 海康PTZ云台摄像头调试之直接控制云台(C#)

    众所周知,海康的摄像头sdk较为完善,但是对于新手来说还是有点麻烦. 今天写一篇随笔给大家展示下怎么控制海康摄像头的云台(前提是有ptz云台设备) 1.sdk准备 本文基于C#的frame来开发一个p ...

  5. 使用golang对海康sdk进行业务开发

    目录 准备工作 开发环境信息 改写HCNetSDK.h头文件 开发过程 基本数据类型转换 业务开发 参考 项目最近需要改造升级:操作海康摄像头(包括登录,拍照,录像)等基本功能.经过一段时间研究后,发 ...

  6. Java二次开发海康SDK-对接门禁机

    写在最前 SDK版本:CH-HCNetSDKV6.1.6.45_build20210302_win64 参考文档:海康SDK使用手册_V6.1 对接测试设备型号:DS-K1T671M 设备序列号:E5 ...

  7. 海康SDK编程指南(C#二次开发版本)

    海康SDK编程指南 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文 ...

  8. 海康相机SDK二次开发只有视频无声音问题

    海康SDK相信做企业开发的的同仁,在项目中经常会用到,毕竟使用范围这么广. 本次就开发遇到的奇葩问题来说明一下我们的解决方案. 场景 虽然海康有4200客户端,但是对于高度定制化的项目,肯定不能再使用 ...

  9. 海康相机开发(1) SDK安装和开发

    1.1 安装包获取 从官网下载最新版本的MVS安装包,支持Windows xp.Windows 7.Windows 8.Windows 10的32和64位系统.安装过程默认即可. 官网下载链接:htt ...

随机推荐

  1. -bash: /etc/init.d/nginx: /bin/bash^M: bad interpreter: No such file or directory

    -bash: /etc/init.d/nginx: /bin/bash^M:bad interpreter: No such file or directory 这个使为了弄nginx自启的,然后在官 ...

  2. 设计模式之单例模式-C++

    单例模式也称单子模式.单件模式,通过单例模式可以保证系统中只有一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享 对于系统中的某些类来说,只有一个实例很重要,比如一个打印机可以 ...

  3. java高级---->Serializable的过程分析

    本次讲解中我们在上次的基础上,深入的了解一下序列化的流程以及其中的原理.关于序列化的一些知识与使用,请参见我的另一篇博客:java基础---->Serializable的使用.好了,我们进行以下 ...

  4. [LeetCode] Network Delay Time 网络延迟时间——最短路算法 Bellman-Ford(DP) 和 dijkstra(本质上就是BFS的迭代变种)

    There are N network nodes, labelled 1 to N. Given times, a list of travel times as directed edges ti ...

  5. span 超出部分换行

    span{ word-break: normal; width: auto; display: block; white-space: pre-wrap; word-wrap: break-word; ...

  6. svg 学习笔记

    http://git.oschina.net/heboliufengjie/demo/tree/master/svg?dir=1&filepath=svg&oid=3a44203972 ...

  7. 实现django admin后台到xadmin后台的转变

    虽然不做前端,还是喜欢好看的东西~.~ 之前同事估计也是功能实现没空管这个后台,前段时间闲的,稍微改了下外貌,前后对比下: Python3.5+Django1.9.7+Xadmin0.6.1 步骤如下 ...

  8. Tomcat错误:getOutputStream() has already been called for this response

    使用weblogic部署时,没有报错.客户现场使用tomcat后报错. 在tomcat下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有妥善处理好的原因.具体的原 ...

  9. sqlalchemy(一)常用连接参数及包

    简介: 本文默认你已经有了一定的数据库基础.我们不喜欢写原生SQL语句,那个写着费劲,日常开发时候,我们怎么CRUD数据库呢?一般使用ORM,对象关系映射(英语:Object Relational M ...

  10. maven scope和项目发布需要注意的地方

    Maven Scope的使用: http://www.cnblogs.com/wangyonghao/p/5976055.html servlet-api和jsp-api等jar包,一般由servle ...