HkCameraParam
/**
* 海康摄像头相关参数
*/
@Data
public class HkCameraParam {
//已登录设备的IP地址
private String deviceIp;
//设备用户名
private String username;
//设备密码
private String password;
private String nickname;
//端口号
private Short port;
}
init 布防是为了自动抓图并识别车牌,
manualSnap 手动抓图是手动触发抓图并识别车牌。
take 简单抓图而已。
import com.slife.hikvision.config.HkCameraProperty;
import com.slife.hikvision.sdk.HCNetSDK;
import com.slife.hikvision.utils.*;
import com.slife.hikvision.domain.vo.HkCameraParam;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
/**
* 海康车牌摄像头初始化
**/
@Slf4j
@Service
public class HkService {
@Autowired
private HkCameraProperty property;
static HCNetSDK hCNetSDK = null;
/**
* 海康车牌摄像头初始化
*/
@PostConstruct
public void init() {
List<HkCameraParam> cameraList = property.getCamera();
for (HkCameraParam plateNumber :cameraList) {
this.plateNumberInit(plateNumber.getDeviceIp(), plateNumber.getUsername(), plateNumber.getPassword(), plateNumber.getPort());
}
}
/**
* 海康车牌摄像头初始化
*/
public void plateNumberInit(String deviceIp, String username, String password, Short port) {
if (hCNetSDK == null) {
if (!this.createSDKInstance()) {
log.info("【海康车牌摄像头初始化】加载SDK失败");
return;
}
}
// 初始化
if (!hCNetSDK.NET_DVR_Init()) {
log.info("【海康车牌摄像头初始化】初始化失败");
return;
}
log.info("【海康车牌摄像头初始化】初始化成功");
// 设置连接时间与重连时间
this.connect();
// 设备信息
int lUserID = this.login(deviceIp, username, password, port);
if (lUserID < 0) {
return;
}
// 启用布防
this.setupAlarm(lUserID);
// 设置报警回调函数
new Thread(() -> {
try {
for (; ; ) {
this.setMessageCallBack();
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
/**
* 动态库加载
*/
private boolean createSDKInstance() {
if (hCNetSDK == null) {
synchronized (HCNetSDK.class) {
String path;
if (OsSelect.isWindows()) {
path = "\\HCNetSDK.dll";
} else {
path = "/libhcnetsdk.so";
}
log.info("【海康初始化】LOAD_PATH: {}", property.getSdkPath() + path);
hCNetSDK = (HCNetSDK) Native.loadLibrary(property.getSdkPath() + path, HCNetSDK.class);
// linux系统建议调用以下接口加载组件库
this.loadLinuxLib();
}
}
return true;
}
/**
* linux系统建议调用以下接口加载组件库
*/
private void loadLinuxLib() {
if (OsSelect.isWindows()) {
return;
}
// linux系统建议调用以下接口加载组件库
log.info("【海康初始化】linux系统加载组件库");
HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
String strPathCom = property.getSdkPath();
String strPath1 = strPathCom + "/libcrypto.so.1.1";
String strPath2 = strPathCom + "/libssl.so.1.1";
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
ptrByteArray1.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
ptrByteArray2.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
struComPath.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
}
/**
* 设置链接事件与重连时间
*/
private void connect() {
// 设置连接时间与重连时间
hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
hCNetSDK.NET_DVR_SetReconnect(10000, true);
}
/**
* 注册设备
*/
private int login(String deviceIp, String username, String password, Short port) {
// 设备信息, 输出参数
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(deviceIp.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, deviceIp.length());
m_strLoginInfo.sUserName = new byte[hCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
System.arraycopy(username.getBytes(), 0, m_strLoginInfo.sUserName, 0, username.length());
m_strLoginInfo.sPassword = new byte[hCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
System.arraycopy(password.getBytes(), 0, m_strLoginInfo.sPassword, 0, password.length());
m_strLoginInfo.wPort = port;
// 是否异步登录:0- 否,1- 是
m_strLoginInfo.bUseAsynLogin = false;
m_strLoginInfo.write();
// 设备信息, 输出参数
int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID < 0) {
log.info("【海康车牌摄像头初始化】注册登录失败: {}", hCNetSDK.NET_DVR_GetErrorMsg(null));
hCNetSDK.NET_DVR_Cleanup();
return -1;
}
return lUserID;
}
/**
* 设置回调
*/
private void setMessageCallBack() {
// 设置报警回调函数
hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(this::callback, null);
}
/**
* 启用布防
*/
private void setupAlarm(int lUserID) {
// 启用布防
HCNetSDK.NET_DVR_SETUPALARM_PARAM lpSetupParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
lpSetupParam.dwSize = 0;
// 布防优先级:0- 一等级(高),1- 二等级(中)
lpSetupParam.byLevel = 1;
// 上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
lpSetupParam.byAlarmInfoType = 1;
int lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, lpSetupParam);
if (lAlarmHandle < 0) {
log.info("【海康车牌摄像头初始化】启用布防失败: {}", hCNetSDK.NET_DVR_GetLastError());
hCNetSDK.NET_DVR_Logout(lUserID);
hCNetSDK.NET_DVR_Cleanup();
return;
}
log.info("【海康车牌摄像头初始化】布防成功,开始监测车辆");
}
/**
* 回调
*/
public boolean callback(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
log.info("【海康车牌摄像头回调】进入回调 开始识别车牌 lCommand: 0x{}", Integer.toHexString(lCommand));
switch (lCommand) {
case HCNetSDK.COMM_ITS_PLATE_RESULT:
log.info("【海康车牌摄像头回调】交通抓拍的终端图片上传");
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();
try {
String license = new String(strItsPlateResult.struPlateInfo.sLicense, "GBK");
// 车型识别:0- 未知,1- 客车(大型),2- 货车(大型),3- 轿车(小型),4- 非机动车
String host = new String(pAlarmer.sDeviceIP).trim();//ip地址
String type = strItsPlateResult.byVehicleType + "".trim();
String plateNumber = license.substring(1).trim();
String byCountry = license.substring(1, 2).trim();
String byColor = license.substring(0, 1).trim();
log.info("【海康车牌摄像头回调】ip地址: {}", host);
log.info("【海康车牌摄像头回调】车辆类型: {}", type);
log.info("【海康车牌摄像头回调】车牌号: {}", plateNumber);
log.info("【海康车牌摄像头回调】车牌省份: {}", byCountry);
log.info("【海康车牌摄像头回调】车牌颜色: {}", byColor);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
break;
}
return true;
}
/**
* 写到本地
*/
private String writeFile(byte[] bs, String suffix) {
String path = property.getImgPath()+File.separator+DateUtils.getDate().replace("-","");
FileUtils.checkDirExists(path);
String filename =path +File.separator + DateUtils.getDateTimeString() + "_" + suffix + ".jpg";//, path = property.getImgPath() + filename;
File file = new File(filename);
try (FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
bos.write(bs);
} catch (Exception e) {
log.error("【海康摄像头写入图片失败】", e);
return null;
}
return filename;
}
/**
* 海康SDK手动抓拍并获取车牌
*/
public void manualSnap(HkCameraParam camera) {
// 设备信息
int lUserID = this.cameraInit(camera.getDeviceIp(), camera.getUsername(), camera.getPassword(), camera.getPort());
HCNetSDK.NET_DVR_PLATE_RESULT struPlateResultInfo = new HCNetSDK.NET_DVR_PLATE_RESULT();
struPlateResultInfo.pBuffer1 = new Memory(2 * 1024 * 1024);
struPlateResultInfo.pBuffer2 = new Memory( 1024 * 1024);
HCNetSDK.NET_DVR_MANUALSNAP struInter = new HCNetSDK.NET_DVR_MANUALSNAP();
struInter.byLaneNo = 1;
boolean flag = hCNetSDK.NET_DVR_ManualSnap(lUserID, struInter, struPlateResultInfo);
if (flag){
String license = null;
try {
byte[] byteArray = struPlateResultInfo.pBuffer1.getByteArray(0, struPlateResultInfo.dwPicLen);
// img1 车辆场景图片(大图)
String img1 = writeFile(byteArray, camera.getDeviceIp().substring(camera.getDeviceIp().lastIndexOf(".") + 1) + "_s");
byte[] byteArray1 = struPlateResultInfo.pBuffer2.getByteArray(0, struPlateResultInfo.dwPicLen);
// img2 车牌图片(小图)
String img2 = writeFile(byteArray1, camera.getDeviceIp().substring(camera.getDeviceIp().lastIndexOf(".") + 1) + "_p");
license = new String(struPlateResultInfo.struPlateInfo.sLicense, "GBK");
String plateNumber = license.substring(1).trim();
String byCountry = license.substring(1, 2).trim();
String byColor = license.substring(0, 1).trim();
String byType = struPlateResultInfo.byVehicleType + "".trim();
String carType = CarType.getCarType(byType);
log.info("【海康车牌摄像头回调】车牌号: {}", plateNumber);
log.info("【海康车牌摄像头回调】车牌省份: {}", byCountry);
log.info("【海康车牌摄像头回调】车牌颜色: {}", byColor);
log.info("【海康车牌摄像头回调】车牌类型: {}", carType);
log.info("【海康车牌摄像头回调】场景图片: {}", img1);
log.info("【海康车牌摄像头回调】车牌图片: {}", img2);
hCNetSDK.NET_DVR_Logout(lUserID);
hCNetSDK.NET_DVR_Cleanup();
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
/**
* 海康全彩摄像头初始化
*/
private int cameraInit(String deviceIp, String username, String password, Short port) {
if (hCNetSDK == null) {
if (!this.createSDKInstance()) {
log.info("【海康全彩摄像头】加载SDK失败");
return -1;
}
}
// 初始化
if (!hCNetSDK.NET_DVR_Init()) {
log.info("【海康全彩摄像头】初始化失败");
return -1;
}
log.info("【海康全彩摄像头】初始化成功");
// 设备信息
return this.login(deviceIp, username, password, port);
}
/**
* 手动抓图
* @param camera
*/
public void take(HkCameraParam camera){
int lUserID = this.cameraInit(camera.getDeviceIp(), camera.getUsername(), camera.getPassword(), camera.getPort());
String img = this.writeFile(this.takePhoto(lUserID), camera.getDeviceIp().substring(camera.getDeviceIp().lastIndexOf(".") + 1));
hCNetSDK.NET_DVR_Logout(lUserID);
hCNetSDK.NET_DVR_Cleanup();
log.info("文件保存路径:"+img);
}
/**
* 海康全彩摄像头拍照
*/
private byte[] takePhoto(int lUserID) {
// JPEG图像参数
HCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new HCNetSDK.NET_DVR_JPEGPARA();
// 设置图片的分辨率
lpJpegPara.wPicSize = 2;
// 设置图片质量
lpJpegPara.wPicQuality = 0;
// 通道号、输入缓冲区大小
int channel = 1, dwPicSize = 1024 * 1024;
// 保存JPEG数据的缓冲区
Pointer sJpegPicBuffer = new Memory(dwPicSize);
// 返回图片数据的大小
IntByReference reference = new IntByReference();
// 抓拍
hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(lUserID, channel, lpJpegPara, sJpegPicBuffer, dwPicSize, reference);
// 图片大小
int value = reference.getValue();
log.info("【海康全彩摄像头】图片大小: {}", value);
// 图片byte
return sJpegPicBuffer.getByteArray(0, value);
}
}
网友评论