Java 对接海康威视摄像头SDK获取抓拍车辆数据教程(附带完整源码)
·
一、功能说明
-
建立卡扣抓拍车辆信息,之后结合业务数据形成智能预警、非法报警等功能。
-
本示例仅做到将抓拍车辆相关信息存入数据库,抓拍图片存放服务器磁盘指定目录,如需求不符合可以绕开,解约您宝贵时间。
二、项目环境
Spring Boot、JDK 1.8、IntelliJ IDEA 2020、SDK V6.1、MySql 5.7、康威视抓拍摄像头(iDS-2CD9545-GSZ/GSJK
)
接触海康摄像头二开少的朋友可以先看看,如何接入海康SDK详细说明:海康威视SDK二次开发JAVA(SpringBoot)
三、 详细步骤
摄像头硬件系统配置和程序编程二次开发记录整个步骤。
3.2 摄像头配置
- 浏览器输入摄像头ip,登录账户密码后面,进入页面配置并保存。

3.3 二开代码
- 如图创建Spring boot项目,整体项目目录结构如图:

数据库创建库>>导入sql>>修改配置文件即可启动项目。抓拍摄像头信息根据实际情况填入sys_camera表。
源码地址:代码地址https://download.csdn.net/download/qq_35719898/92690222?spm=1001.2014.3001.5503
-
HCNetSDK.java,修改为自定义位置。

-
HikVisionService.java摄像头创建连接、布防、建立监听、回调获取抓拍数据,示例关键核心代码,
注:代码注释标注很清楚不过多说明。
package com.xzl.common.hkSdk.HkService;
import com.xzl.common.hkSdk.ClientDemo.HCNetSDK;
import com.xzl.dao.SafeMonitorSiteDAO;
import com.xzl.entity.SafeMonitorSite;
import com.xzl.entity.SysCamera;
import com.xzl.vo.*;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import static com.xzl.common.hkSdk.ClientDemo.HCNetSDK.COMM_ITS_PLATE_RESULT;
public class HikVisionService {
private static Logger logger = LoggerFactory.getLogger(HikVisionService.class);
static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
static short m_sPort = 8000;//端口号,这是默认的
public NativeLong lUserID;//用户句柄
public NativeLong lAlarmHandle;//报警布防句柄
public int lListenHandle;//报警监听句柄
public boolean callback; // 回调状态
public void initMemberFlowUpload(SysCamera camera, Map<String, SysCamera> mapCamera, SafeMonitorSiteDAO safeMonitorSiteDAO, String fileSavePath) throws InterruptedException {
String m_sDeviceIP = camera.getIp();
String m_sUsername = camera.getAccount();
String m_sPassword = camera.getPassword();
// 初始化
boolean flag = hCNetSDK.NET_DVR_Init();
if (flag) {
System.out.println("初始化成功");
} else {
System.out.println("初始化失败");
}
//设置连接时间与重连时间
hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
hCNetSDK.NET_DVR_SetReconnect(100000, true);
//设备信息, 输出参数
HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
// 注册设备-登录参数,包括设备地址、登录用户、密码等
m_strLoginInfo.sDeviceAddress = new byte[hCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
m_strLoginInfo.sUserName = new byte[hCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
m_strLoginInfo.sPassword = new byte[hCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
m_strLoginInfo.wPort = m_sPort;
m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
m_strLoginInfo.write();
//设备信息, 输出参数
lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID.intValue() < 0) {
System.out.println("hCNetSDK.NET_DVR_Login_V30()" + "\n" + hCNetSDK.NET_DVR_GetErrorMsg(null));
hCNetSDK.NET_DVR_Cleanup();
return;
}
callback = hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(new HikVisionService().new FMSGCallBack(safeMonitorSiteDAO, fileSavePath, mapCamera), null);
//设置报警回调函数
if (!callback) {
System.out.println("设置回调函数失败" + hCNetSDK.NET_DVR_GetLastError());
return;
} else {
System.out.println("设置回调函数成功");
}
//启用布防
HCNetSDK.NET_DVR_SETUPALARM_PARAM lpSetupParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
lpSetupParam.dwSize = 0;
lpSetupParam.byLevel = 0;//布防优先级:0- 一等级(高),1- 二等级(中)
lpSetupParam.byAlarmInfoType = 1;//上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, lpSetupParam);
if (lAlarmHandle.intValue() < 0) {
System.out.println("NET_DVR_SetupAlarmChan_V41 error, %d\n" + hCNetSDK.NET_DVR_GetLastError());
hCNetSDK.NET_DVR_Logout(lUserID);
hCNetSDK.NET_DVR_Cleanup();
return;
}
System.out.println("布防成功,开始监测车辆");
//启动监听----------------------------------------------
int iListenPort = 9999;
String m_sListenIP = "127.0.0.1";
lListenHandle = hCNetSDK.NET_DVR_StartListen_V30(m_sListenIP, (short) iListenPort, new HikVisionService().new FMSGCallBack(safeMonitorSiteDAO, fileSavePath, mapCamera), null);
if (lListenHandle < 0) {
System.out.println("启动监听失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
} else {
System.out.println("启动监听成功");
}
}
public class FMSGCallBack implements HCNetSDK.FMSGCallBack {
/**
* 文件存放地址
*/
private String fileSavePath;
/**
* 抓拍数据存储位置
*/
private SafeMonitorSiteDAO safeMonitorSiteDAO;
/**
* 相机
*/
public Map<String, SysCamera> mapCamera;
public FMSGCallBack(SafeMonitorSiteDAO safeMonitorSiteDAO, String fileSavePath, Map<String, SysCamera> mapCamera) {
this.fileSavePath = fileSavePath;
this.safeMonitorSiteDAO = safeMonitorSiteDAO;
this.mapCamera = mapCamera;
}
@Override
public void invoke(NativeLong lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
System.out.println("〈--进入回调,开始识别车牌--〉");
try {
String sAlarmType;
DateTimeFormatter sf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
DateTimeFormatter sfDay = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime now = LocalDateTime.now();
switch (lCommand.intValue()) {
case COMM_ITS_PLATE_RESULT: //交通抓拍的终端图片上传
HCNetSDK.NET_ITS_PLATE_RESULT strItsPlateResult = new HCNetSDK.NET_ITS_PLATE_RESULT();
strItsPlateResult.write();
Pointer pItsPlateInfo = strItsPlateResult.getPointer();
pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, strItsPlateResult.size()), 0, strItsPlateResult.size());
strItsPlateResult.read();
// 全车牌号
String carNumber = new String(strItsPlateResult.struPlateInfo.sLicense, "GBK");
// 车牌号
String plateNumber = carNumber.substring(1).trim();
// //省份
String byCountry = carNumber.substring(1, 2).trim();
// 车牌颜色
String byColor = carNumber.substring(0, 1).trim();
// 相机ip
String cameraIp = new String(pAlarmer.sDeviceIP).trim();
// 车辆类型
String carType = CarType.getCarType(strItsPlateResult.byVehicleType + "".trim());
// 车道
String driveChan = strItsPlateResult.byDriveChan + "".trim();
// 速度
String wSpeed = String.valueOf(new Random().nextInt(55 - 5) + 5);
// 相机对象
SysCamera camera = mapCamera.get(cameraIp);
if (camera == null) {
camera = new SysCamera();
}
String cameraId = camera.getId() == null ? "获取Id失败" : camera.getId();
sAlarmType = driveChan + "车道,抓拍车辆类型:" + carType + ",上传车牌:" + carNumber + ">>" + plateNumber + "相机标识:" + cameraId;
logger.info("识别信息:---》" + sAlarmType + " ip:" + new String(pAlarmer.sDeviceIP).trim() + "时间:" + now);
// 图片保存
String imgName = sf.format(now) + ".jpg";
String pathUrl = cameraId + "/" + sfDay.format(now) + "/";
// 车牌图片地址
String filename = pathUrl + imgName;
// 场景图片地址
String carFileName = pathUrl + "cj_" + imgName;
for (int i = 0; i < strItsPlateResult.dwPicNum; i++) {
if (strItsPlateResult.struPicInfo[i].dwDataLen > 0) {
FileOutputStream fout;
// 车牌照片
if (strItsPlateResult.struPicInfo[i].byType == 0) {
String url = fileSavePath + filename;
File file = new File(url);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
fout = new FileOutputStream(url);
logger.info("文件路径" + url);
//将字节写入文件
long offset = 0;
ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(offset, strItsPlateResult.struPicInfo[i].dwDataLen);
byte[] bytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];
buffers.rewind();
buffers.get(bytes);
fout.write(bytes);
fout.close();
}
// 场景照片
if (strItsPlateResult.struPicInfo[i].byType == 1) {
String url = fileSavePath + carFileName;
File file = new File(url);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
fout = new FileOutputStream(url);
logger.info("文件路径" + url);
//将字节写入文件
long offset = 0;
ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(offset, strItsPlateResult.struPicInfo[i].dwDataLen);
byte[] bytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];
buffers.rewind();
buffers.get(bytes);
fout.write(bytes);
fout.close();
}
}
}
// 创建对接保存数据库
SafeMonitorSite safeMonitorSite = new SafeMonitorSite();
safeMonitorSite.setPictureTime(now);
safeMonitorSite.setPointName(camera.getPointName());
safeMonitorSite.setCarNumber(plateNumber);
safeMonitorSite.setCarPicture(filename);
safeMonitorSite.setLicensePicture(carFileName);
safeMonitorSite.setCarType(carType);
safeMonitorSite.setInOut(0);
safeMonitorSite.setOperator("自动");
safeMonitorSite.setOperatorIp(cameraIp);
safeMonitorSite.setGmtCreate(now);
safeMonitorSite.setGmtModified(now);
safeMonitorSiteDAO.insert(safeMonitorSite);
break;
default:
System.out.println("回调获取数据类型错误:" + lCommand.intValue());
}
} catch (Exception e) {
e.printStackTrace();
logger.info(e.toString() + "故障");
}
}
}
}
4.运行后,开启抓拍调用接口:http://127.0.0.1:8080/dotask。注意:开启后必须有车辆经过才有数据推送,手动布防抓拍车辆,不会推送数据。
5.结果展示

结束赶紧试一下,过程中有问题可以留言一起交流
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)