前言

项目采购的海康威视的抓拍机,需要首先获取抓拍图片,之后基于抓拍图片进行图像处理。本文基于海康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. Hadoop---桥接集群的搭建

    Hadoop---桥接群的搭建 集群分配:(一主四从)   我电脑的虚拟机:hadoop4:namenode+datanode+resourceManager 我one-friend的电脑虚拟机:hm ...

  2. iOS block 机制

    本文要将block的以下机制,并配合具体代码详细描述: block 与 外部变量 block 的存储域:栈块.堆块.全局块 定义 块与函数类似,只不过是直接定义在另一个函数里,和定义它的那个函数共享同 ...

  3. 把旧系统迁移到.Net Core 2.0 日记 (16) --Cors跨域访问

    IE浏览器的Intranet局域网设置默认是可以跨域访问的.chrome就不可以. 这里说的跨域是指javascript代码不能跨域, 当然你在后端controller代码里用HttpClient.G ...

  4. view的focusable属性改变设置是否可获取光标

    注意图中我画的箭头,当时鼠标点击的黑色圈圈的位置,然后按钮出现了按下的效果(黄色的描边) 刚开始看到这种效果很是好奇,不知道是怎么实现的,后来仔细一想,应该是整个啤酒罐是一张图片(ImageView) ...

  5. python 小白学习(1)

    自定义错误类型 class XxxError(Exception): def __init__(self , message): self = Exception("xxxxx") ...

  6. echo * 打印当前目录列表

    所以在脚本中 类似 echo $a*  如果$a为空  则会打印 目录列表.

  7. oracle 如何查看当前用户的表空间名称

    如何查询当前用户的表空间名称?因为oracle建立索引,需要知道当前用户的表空间,查找了一下资料 --查询语法-- select default_tablespace from dba_users w ...

  8. linux用户管理 用户和用户组信息

    用户管理配置文件 用户信息文件  /etc/passwd 密码文件 /etc/shadow 用户配置文件 /etc/login.defs /etc/default/useradd 新用户信息文件 /e ...

  9. 银联支付 Asp.Net 对接开发内容简介

    银联对接开发主要包含测试环境以及生产环境两部分. 其中程序开发部分测试以及生产是相同的. 不同的是,测试环境与生产环境请求支付的Url地址,以及分别使用的证书不同. 一.配置部分 1,测试环境证书获取 ...

  10. EF-关于类库中EntityFramework之CodeFirst(代码优先)的操作浅析

    前有ADO.NET,后有ORM模式的EntityFramework.这两种技术都实现了对数据库的访问操作.如果要说哪种技术好,就看项目架构的大小,使用者的熟练程度等等,毕竟萝卜白菜,各有所爱. 今天要 ...