一、下载SDK(这里需要注意是海康威视的网络摄像机)
下载SDK的地址:https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10&id=5cda5902f47ae80dd41a54b7
二、通过局域网IP查看摄像机的状况
三、 运行海康威视的DEMO,查看是否可执行,在运行之前需要明确摄像机的IP地址、确保计算机与摄像机处于同一局域网中的同一网段。
四、引入摄像头相关依赖到C#(这里我使用的是.Net Formwork)
首先需要将库文件中的部门驱动程序拷贝到程序的bin文件中
五、摄像机部分配置说明(以抓图为例)
- 在使用摄像机的部分功能之前,需要确定摄像机的配置
- 定时抓图概述
六、SDK开发C#代码示例及说明(以抓图为例)
- 网络摄像机相关的方法可查看SDK中的说明文档
2、C# 代码示例(以抓图为例)
public class HIKVISION
{
// 摄像头抓图处理的两种模式true为抓图到本地文件处理模式,false为本地直接处理模式
// 抓图到本地文件,存在删除报文件占用问题
// 现使用本地缓存直接处理模式
private static bool captureMode = false;
// 摄像头配置信息
public static CameraInfoDAO config = null;
/// <summary>
/// 摄像头登录信息
/// </summary>
class CameraUser
{
public string baseAddress = "";
public string username = "";
public string password = "";
}
class TSInfo
{
// 缓存的数据
public List<Hashtable> imageValues = new List<Hashtable>();
// 缓存的处理数据
public List<Hashtable> imageMathValues = new List<Hashtable>();
// 开始采集抓图之后的计数
public double order = 0;
// 抓图保存的数据库
public string imageDBName = "";
// 抓图处理后的数据库
public string imageMathDBName = "";
// 是否保存单图数据库中
public bool isStorage = false;
// 是否保存单位时间处理,下发数据
public bool isTimeStorage = false;
}
class imageInfo
{
// 用于标识是否正在抓取图
public bool isGrabbing = false;
// 是否为登录状态
public int loginHandle = -1;
// fileIndex用于避免删除图片失败照成的卡顿
public int fileIndex = 0;
}
class taskDataInfo
{
// 煤量累计值
public double coalAll = 0;
// 开始采集时间
public DateTime startTime;
// 创建抓图任务(采集),任务信息
public TaskDAO taskInfo;
// 是否为计时任务
public bool isTimeStatus = false;
// 计时时间
public double timeLongInfo = 0;
}
// 原始图片存储路径
private static string path = RelatedFile.RelatedPath("HIKVISION\\image");
// 任务信息
static taskDataInfo taskData = new taskDataInfo();
// 时序数据库存储信息
private static TSInfo TSData = new TSInfo();
// 摄像头登录信息
private static CameraUser cameraInfo = new CameraUser();
// 图片信息
private static imageInfo imageData = new imageInfo();
// 配置参数调用相机信息
private static CameraInfoDAO cameraConfigInfo = new CameraInfoDAO();
public static void Init()
{
Task.Factory.StartNew(startImg, TaskCreationOptions.LongRunning);
}
private static void InitSDKFile()
{
// 初始化 SDK
bool initResult = NET_DVR_Init();
if (!initResult)
{
Log.logger.Error("SDK 初始化失败!");
throw new Exception("SDK 初始化失败_010");
}
// 登录设备
NET_DVR_DEVICEINFO_V30 deviceInfo = new NET_DVR_DEVICEINFO_V30();
cameraInfo = new CameraUser();
// TODO 参数检查
cameraInfo.baseAddress = config.cameraIp;
cameraInfo.username = config.cameraUserName;
cameraInfo.password = config.cameraPassword;
imageData.loginHandle = NET_DVR_Login_V30(cameraInfo.baseAddress, config.cameraPort, cameraInfo.username, cameraInfo.password, ref deviceInfo);
if (imageData.loginHandle < 0)
{
Log.logger.Error("海康威视登录失败");
NET_DVR_Cleanup();
throw new Exception("摄像头处于未登录状态_010");
}
}
private async static Task startImg()
{
try
{
while (true)
{
if (imageData.isGrabbing && imageData.loginHandle >= 0)
{
// 抓取图片
NET_DVR_JPEGPARA jpegPara = new NET_DVR_JPEGPARA();
jpegPara.wPicQuality = config.wPicQuality; // 图片质量,范围为0-6,其中0表示最好,6表示最差
jpegPara.wPicSize = config.wPicSize; ; // 图片大小,0表示最优
string savePath = "";
int bufferSize = 524288; // 替换为你期望的图像数据缓冲区大小 1M = 1024 * 1024
byte[] jpegBuffer = new byte[bufferSize];
byte[] binaryImageData = new byte[bufferSize / 2];
uint sizeReturned = 0;
bool result = false;
var imageValue = -1.0;
if (captureMode)
{
savePath = path + "\\" + Utils.formatHRealTime(DateTime.Now) + ".jpeg";
result = NET_DVR_CaptureJPEGPicture(imageData.loginHandle, 1, ref jpegPara, savePath);
// 使图片不过度堆积,存在问题
setImageFile();
imageValue = await image.DoubleVImgAForgeFile(savePath);
}
else {
//var ticks = DateTime.Now.Ticks;
result = NET_DVR_CaptureJPEGPicture_NEW(imageData.loginHandle, 1, ref jpegPara, jpegBuffer, (uint)bufferSize,ref sizeReturned);
//Log.logger.Info("图片抓取时间 " + (DateTime.Now - new DateTime(ticks)).TotalMilliseconds);
//result = NET_DVR_GetFrame_NEW(imageData.loginHandle, 1, ref jpegPara, jpegBuffer, (uint)bufferSize, ref sizeReturned);
Tuple<byte[], double> resultImage = await image.DoubleVImgAForgeByte(jpegBuffer, config.median, config.isfile, path + "\\" + taskData.taskInfo.taskName + "\\" + TSData.order + ".jpeg");
binaryImageData = resultImage.Item1;
imageValue = Math.Round(resultImage.Item2, 5); ;
}
if (!result)
{
var code = NET_DVR_GetLastError();
Log.logger.Error("图片抓取失败,错误码:" + code);
}
// 此处需要确定比例与煤炭重量间的关系
taskData.coalAll = taskData.coalAll + imageValue * 1.153;
TSData.imageValues.Add(new Hashtable()
{
{ "imageValue", imageValue },
{ "order", TSData.order},
});
// 将数据保存到任务文件夹
// { "image", Convert.ToBase64String(binaryImageData)}
TSSaveData();
// 避免缓存堆积
if (TSData.imageMathValues.Count > 20)
{
TSData.imageMathValues.RemoveAt(0);
}
var wsInfoPush = new WSPush();
// 推送的部分数据暂时未处理
wsInfoPush.nowStatus = true;
wsInfoPush.nowModel = true;
wsInfoPush.isStroage = TSData.isStorage;
wsInfoPush.isTimeStroage = TSData.isTimeStorage;
wsInfoPush.openTime = TSData.order;
wsInfoPush.cameraHZ = 1;
wsInfoPush.coalAll = taskData.coalAll;
wsInfoPush.nowImage = jpegBuffer;
wsInfoPush.nowDoubleImage = binaryImageData;
wsInfoPush.imageValue = imageValue;
var wsInfo = new Dictionary<string, WSPush>() {
{ "taskInfo",wsInfoPush }
};
WS.broadcast("user", Utils.toJSON(wsInfo));
// 计时任务处理逻辑
if (taskData.isTimeStatus)
{
var dataNow = DateTime.Now;
TimeSpan timeDifference = dataNow - taskData.startTime;
double hours = timeDifference.TotalHours;
if (hours >= taskData.timeLongInfo)
{
stopScreenshot();
}
}
TSData.order++;
}
else
{
var wsInfoPush = new WSPush();
// 推送的部分数据暂时未处理
wsInfoPush.nowStatus = false;
wsInfoPush.nowModel = false;
wsInfoPush.isStroage = false;
wsInfoPush.isTimeStroage = false;
wsInfoPush.openTime = 0;
wsInfoPush.cameraHZ = 0;
wsInfoPush.coalAll = taskData.coalAll;
var wsInfo = new Dictionary<string, WSPush>() {
{ "taskInfo",wsInfoPush }
};
WS.broadcast("user", Utils.toJSON(wsInfo));
System.Threading.Thread.Sleep(1000);
}
}
}
catch (Exception ex)
{
imageData.isGrabbing = false;
Log.logger.Error(Utils.LogTxtString(ex, "海康威视摄像机处理失败"));
}
}
}