海康SDK对接 超脑设备-下发人员信息和人脸
文中参数说明和bean 见前面的文章
下发人员
@Override
public void send(IotCommonMsgBodyParam msgBody) {
IotReplyMsgBodyResult bodyResult;
try {
if (StrUtil.isEmpty(msgBody.getAccount()) || StrUtil.isEmpty(msgBody.getBody())) {
return;
}
IotCameraParam cameraParam = JSONUtil.toBean(msgBody.getAccount(), IotCameraParam.class);
List<IotAddFaceParam> faceParamList = JSONUtil.toList(msgBody.getBody(), IotAddFaceParam.class);
if (CollUtil.isEmpty(faceParamList) || faceParamList.size() < 1) {
return;
}
//在保存
List<IotCommDataResult> commDataResults = iotHkFaceApiService.addFace(cameraParam, faceParamList);
if (CollUtil.isNotEmpty(commDataResults) && commDataResults.size() > 0) {
List<IotUserFaceResult> userResults = new ArrayList<>();
for (IotCommDataResult result : commDataResults) {
IotUserFaceResult userResult = new IotUserFaceResult();
userResult.setUserId(result.getId());
userResult.setCode(result.getCode());
userResult.setMsg(result.getMsg());
userResults.add(userResult);
}
bodyResult = msgBody.toResult(JSONUtil.toJsonStr(userResults));
log.info("Hikvision addFace bodyResult:{}", JSONUtil.toJsonStr(bodyResult));
} else {
bodyResult = msgBody.toResult("指令下发成功");
}
} catch (Exception e) {
log.warn("Hikvision addFace e", e);
bodyResult = msgBody.toResult("指令下发失败");
}
// 收集指令执行结果
redisMessageProducer.doSendMessage(IotRedisTopicConstant.REDIS_INSTRUCT_RESPONSE_TOPIC, JSONUtil.toJsonStr(bodyResult));
}
设备登录
/**
* 设备登录
*
* @param ipadress IP地址
* @param user 用户名
* @param psw 密码
* @param port 端口,默认8000
*/
public static int login_V40(String ipadress, String user, String psw, short port) {
if(ObjectUtil.isNull(hKHCNetSDK)){
return -1;
}
//注册
NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new NET_DVR_USER_LOGIN_INFO();//设备登录信息
String m_sDeviceIP = ipadress;//设备ip地址
m_strLoginInfo.sDeviceAddress = new byte[IotHikNetConstant.NET_DVR_DEV_ADDRESS_MAX_LEN];
System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
String m_sUsername = user;//设备用户名
m_strLoginInfo.sUserName = new byte[IotHikNetConstant.NET_DVR_LOGIN_USERNAME_MAX_LEN];
System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
String m_sPassword = psw;//设备密码
m_strLoginInfo.sPassword = new byte[IotHikNetConstant.NET_DVR_LOGIN_PASSWD_MAX_LEN];
System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
m_strLoginInfo.wPort = port; //sdk端口
m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
m_strLoginInfo.write();
NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new NET_DVR_DEVICEINFO_V40();//设备信息
int lUserID = -1;
try {
lUserID = hKHCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
if (lUserID == -1) {
log.warn("登录失败,错误码为:{}", hKHCNetSDK.NET_DVR_GetLastError());
return lUserID;
} else {
log.info("登录成功!");
m_strDeviceInfo.read();
}
} catch (Exception e) {
log.error("海康SDK 登录异常,请检查网络和SDK路径是否正确", e);
} finally {
m_strLoginInfo.clear();
m_strDeviceInfo.clear();
}
return lUserID;
}
设备注销 SDK释放
//设备注销 SDK释放
public static void logout(int lUserID) {
if (lUserID >= 0) {
if (!hKHCNetSDK.NET_DVR_Logout(lUserID)) {
log.warn("注销失败,错误码为: {}", hKHCNetSDK.NET_DVR_GetLastError());
}
log.info("注销成功");
//hCNetSDK.NET_DVR_Cleanup(); //释放SDK
return;
} else {
log.warn("设备未登录");
}
}
下发人员信息和人脸
@Override
public List<IotCommDataResult> addFace(IotCameraParam camera, List<IotAddFaceParam> faceList) {
int loginV40 = login_V40(camera.getIp(), camera.getUsername(), camera.getPassword(), new Short(String.valueOf(camera.getPort())));
List<IotCommDataResult> commDataResults = new ArrayList<>();
for (IotAddFaceParam faceParam : faceList) {
IotCommDataResult result = new IotCommDataResult();
result.setId(faceParam.getUserId());
if (StrUtil.isNotEmpty(FDID)) {
//FDID必填项,只能项指定库添加人脸
uploadPic(loginV40, FDID, faceParam, result);
}else {
result.setCode(500);
result.setMsg("添加人脸失败:未指定人脸库");
}
commDataResults.add(result);
}
logout(loginV40);
return commDataResults;
}
获取所有人脸库信息
/**
* 获取所有人脸库信息
*/
private FDLibBaseCfgList allFaceData(int lUserID) {
String strOutXML = sdkIsApi(lUserID, HKUrlConstant.ALL_FACL_DB, "");
try {
FDLibBaseCfgList fdLibBaseCfgList = XmlUtil.toBean(FDLibBaseCfgList.class, strOutXML);
log.info("查询所有人脸库信息:{}", JSONUtil.toJsonStr(fdLibBaseCfgList));
return fdLibBaseCfgList;
} catch (Exception e) {
log.error("获取所有人脸库信息", e);
}
return null;
}
查询指定人脸库
/**
* 查询指定人脸库
*/
private FDLibBaseCfg specifyFaceLibrary(int lUserID, String FDID) {
// requestUrl = "GET /ISAPI/Intelligent/FDLib/" + FDID;
if (StrUtil.isEmpty(FDID)) {
log.warn("未指定人脸库");
return null;
}
String strOutXML = sdkIsApi(lUserID, HKUrlConstant.ALL_FACL_DB + FDID, "");
try {
FDLibBaseCfg fdLibBaseCfg = XmlUtil.toBean(FDLibBaseCfg.class, strOutXML);
log.info("查询所有人脸库信息:{}", JSONUtil.toJsonStr(fdLibBaseCfg));
return fdLibBaseCfg;
} catch (Exception e) {
log.error("获取所有人脸库信息", e);
}
return null;
}
创建人脸库
/**
* 创建人脸库
*
* @param
*/
private static FDLibInfoList createFaceLibrary(int lUserID, CreateFDLibList createFDLibList) {
String strOutXML = sdkIsApi(lUserID, HKUrlConstant.CREATE_FACE_LIBRARY, fDCreate_XmlCreat(createFDLibList));
// <FDLibInfoList version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
// <FDLibInfo>
// <id>1</id>
// <name>测试001</name>
// <FDID>642446466D424B32B9E50B7A33B4E5B8</FDID>
// </FDLibInfo>
// </FDLibInfoList>
log.info("创建人脸库:{}", strOutXML);
try {
FDLibInfoList fdLibInfoList = XmlUtil.toBean(FDLibInfoList.class, strOutXML);
log.info("创建人脸库:{}", JSONUtil.toJsonStr(fdLibInfoList));
return fdLibInfoList;
} catch (Exception e) {
log.error("获取所有人脸库信息", e);
}
return null;
}
创建人脸库输入XML报文
// 创建人脸库输入XML报文
private static String fDCreate_XmlCreat(CreateFDLibList createFDLibList) {
/*<CreateFDLibList version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
<!--req,创建人脸比对库输入参数-->
<CreateFDLib>
<id>
<!--req, xs:integer,"表示list中子项个数,从"1"开始赋值,依次增加" -->
</id>
<name>
<!--opt, xs:string,"人脸比对库名称"-->
</name>
<thresholdValue>
<!--opt, xs:integer, "检测阈值,阈值越大检测准确率越低, 范围[0,100]"-->
</thresholdValue>
<customInfo>
<!--opt, xs:string, 人脸库附加信息-->
</customInfo>
<customFaceLibID>
<!--opt, xs:string, "自定义人脸库ID, 由上层下发给设备, 该ID由上层维护并确保唯一性,
设备侧需将自定义人脸库ID与设备生成的FDID进行关联, 确保上层可通过下发人脸库ID来替代下发FDID进行后续操作"-->
</customFaceLibID>
</CreateFDLib>
</CreateFDLibList>*/
String requestXm = null;
try {
// XmlUtil 是解析工具 自己封装的
requestXm = XmlUtil.toXml(createFDLibList);
} catch (Exception e) {
log.error("创建人脸库编译xml异常", e);
}
return requestXm;
}
上传人脸图
/**
* 上传人脸图
*
* @param lUserID
* @param fdId 人脸库id
* @param faceParam
* @throws IOException
*/
public static void uploadPic(int lUserID, String fdId, IotAddFaceParam faceParam, IotCommDataResult result) {
try {
NET_DVR_FACELIB_COND struFaceLibCond = new NET_DVR_FACELIB_COND();
struFaceLibCond.read();
struFaceLibCond.dwSize = struFaceLibCond.size();
//人脸库ID
for (int i = 0; i < IotHikNetConstant.NET_SDK_MAX_FDID_LEN; i++) {
struFaceLibCond.szFDID[i] = 0;
}
System.arraycopy(fdId.getBytes(), 0, struFaceLibCond.szFDID, 0, fdId.length());
struFaceLibCond.byConcurrent = 0; //设备并发处理:0- 不开启(设备自动会建模),1- 开始(设备不会自动进行建模)
struFaceLibCond.byCover = 1; //是否覆盖式导入(人脸库存储满的情况下强制覆盖导入时间最久的图片数据):0- 否,1- 是
struFaceLibCond.byCustomFaceLibID = 0;
struFaceLibCond.write();
Pointer pStruFaceLibCond = struFaceLibCond.getPointer();
int iUploadHandle = hKHCNetSDK.NET_DVR_UploadFile_V40(lUserID, IotHikNetConstant.IMPORT_DATA_TO_FACELIB, pStruFaceLibCond,
struFaceLibCond.size(), null, Pointer.NULL, 0);
if (iUploadHandle <= -1) {
int iErr = hKHCNetSDK.NET_DVR_GetLastError();
log.warn("NET_DVR_UploadFile_V40失败,错误号:{}", iErr);
result.setCode(500);
result.setMsg("添加人脸失败:"+IotHkExceptionEnum.getMsg(iErr));
return;
} else {
log.info("NET_DVR_UploadFile_V40成功");
}
NET_DVR_SEND_PARAM_IN struSendParam = new NET_DVR_SEND_PARAM_IN();
struSendParam.read();
//本地jpg图片转成二进制byte数组
String fileName = IdWorker.getId() + ".jpg";
String downloadImgPath = ImageBase64Format.base64ByFilePath(faceParam.getFaceImage(), fileName);
if (StrUtil.isEmpty(downloadImgPath)) {
log.warn("图片解析失败");
result.setCode(500);
result.setMsg("添加人脸失败:"+IotHkExceptionEnum.getMsg(hKHCNetSDK.NET_DVR_GetLastError()));
return;
}
byte[] picbyte = ImageBase64Format.filetoByte(new File(downloadImgPath));
// byte[] picbyte = ImageBase64Format.toByteArray("D:\\dev\\FDLib.jpg");
BYTE_ARRAY arraybyte = new BYTE_ARRAY(picbyte.length);
arraybyte.read();
arraybyte.byValue = picbyte;
arraybyte.write();
struSendParam.pSendData = arraybyte.getPointer();
struSendParam.dwSendDataLen = picbyte.length;
struSendParam.byPicType = 1; //图片格式:1- jpg,2- bmp,3- png,4- SWF,5- GIF
//图片的附加信息缓冲区 图片上添加的属性信息,性别、身份等
//1:xml文本导入方式
/* byte[] AppendData = toByteArray("E:\\2.Demo汇总\\JAVA_DEMO\\01-Windows_Demo\\超脑人脸比对\\Test\\pic\\test.xml");
HCNetSDK.BYTE_ARRAY byteArray = new HCNetSDK.BYTE_ARRAY(AppendData.length);
byteArray.read();
byteArray.byValue = AppendData;
byteArray.write();*/
//2:包含中文姓名的报文上传
byte[] byFDLibName = faceParam.getUserName().getBytes(StandardCharsets.UTF_8);
String strInBuffer1 = "<FaceAppendData version=\"2.0\" xmlns=\"http://www.hikvision.com/ver20/XMLSchema\"><bornTime></bornTime><name>";
String strInBuffer2 = "</name><sex>" + faceParam.getSex() + "</sex><province></province><city></city><certificateType>ID</certificateType><certificateNumber>" + faceParam.getIdCard() + "</certificateNumber><PersonInfoExtendList><PersonInfoExtend><id>1</id><enable>true</enable><name>test1</name><value>test2</value></PersonInfoExtend></PersonInfoExtendList></FaceAppendData>";
int iStringSize = byFDLibName.length + strInBuffer1.length() + strInBuffer2.length();
BYTE_ARRAY ptrByte = new BYTE_ARRAY(iStringSize);
System.arraycopy(strInBuffer1.getBytes(), 0, ptrByte.byValue, 0, strInBuffer1.length());
System.arraycopy(byFDLibName, 0, ptrByte.byValue, strInBuffer1.length(), byFDLibName.length);
System.arraycopy(strInBuffer2.getBytes(), 0, ptrByte.byValue, strInBuffer1.length() + byFDLibName.length, strInBuffer2.length());
ptrByte.write();
struSendParam.pSendAppendData = ptrByte.getPointer();
struSendParam.dwSendAppendDataLen = ptrByte.byValue.length;
struSendParam.write();
int iSendData = hKHCNetSDK.NET_DVR_UploadSend(iUploadHandle, struSendParam, Pointer.NULL);
if (iSendData <= -1) {
int iErr = hKHCNetSDK.NET_DVR_GetLastError();
log.info("NET_DVR_UploadSend失败,错误号:{}", iErr);
result.setCode(500);
result.setMsg("添加人脸失败:"+IotHkExceptionEnum.getMsg(iErr));
return;
}
while (true) {
IntByReference Pint = new IntByReference(0);
int state = hKHCNetSDK.NET_DVR_GetUploadState(iUploadHandle, Pint.getPointer());
if (state == 1) {
log.info("上传成功");
//获取图片ID
NET_DVR_UPLOAD_FILE_RET struUploadRet = new NET_DVR_UPLOAD_FILE_RET();
boolean bUploadResult = hKHCNetSDK.NET_DVR_GetUploadResult(iUploadHandle, struUploadRet.getPointer(), struUploadRet.size());
if (!bUploadResult) {
int iErr = hKHCNetSDK.NET_DVR_GetLastError();
log.info("NET_DVR_GetUploadResult失败,错误号:{}", iErr);
result.setCode(500);
result.setMsg("添加人脸失败:"+IotHkExceptionEnum.getMsg(iErr));
} else {
struUploadRet.read();
log.info("图片ID:{}", new String(struUploadRet.sUrl, StandardCharsets.UTF_8).trim());
result.setCode(200);
result.setMsg("添加人脸成功");
}
break;
} else if (state == 2) {
// log.info("进度:{}", Pint.getValue());
continue;
}
log.info("返回值:{}", state);
break;
}
//关闭图片上传连接
boolean b_Close = hKHCNetSDK.NET_DVR_UploadClose(iUploadHandle);
if (!b_Close) {
int iErr = hKHCNetSDK.NET_DVR_GetLastError();
log.info("关闭图片上传连接NET_DVR_UploadSend失败,错误号:{}", iErr);
return;
}
} catch (Exception e) {
result.setCode(500);
result.setMsg("添加人脸失败,上传数据发生异常");
log.error("添加人脸失败", e);
}
}
/**
* SDK透传ISAPI协议报文接口
*
* @param lUserID
* @param url
* @param inputXml 输入报文
* @return
*/
public static String sdkIsApi(int lUserID, String url, String inputXml) {
String strOutXML = "";
try {
//输入参数
NET_DVR_XML_CONFIG_INPUT struXMLInput = new NET_DVR_XML_CONFIG_INPUT();
struXMLInput.read();
struXMLInput.dwSize = struXMLInput.size();
BYTE_ARRAY stringRequest = new BYTE_ARRAY(1024);
stringRequest.read();
//输入ISAPI协议命令 批量查询人脸库命令:GET /ISAPI/Intelligent/FDLib
System.arraycopy(url.getBytes(), 0, stringRequest.byValue, 0, url.length());
stringRequest.write();
struXMLInput.lpRequestUrl = stringRequest.getPointer();
struXMLInput.dwRequestUrlLen = url.length();
//输入XML文本,GET命令不传输入文本
int inputDataLen = inputXml.getBytes(StandardCharsets.UTF_8).length;
if (inputDataLen > 0) {
BYTE_ARRAY stringInBuffer = new BYTE_ARRAY(inputDataLen);
stringInBuffer.read();
System.arraycopy(inputXml.getBytes(StandardCharsets.UTF_8), 0, stringInBuffer.byValue, 0, inputDataLen);
stringInBuffer.write();
struXMLInput.lpInBuffer = stringInBuffer.getPointer();
struXMLInput.dwInBufferSize = inputDataLen;
} else {
struXMLInput.lpInBuffer = null;
struXMLInput.dwInBufferSize = 0;
}
struXMLInput.write();
BYTE_ARRAY stringXMLOut = new BYTE_ARRAY(8 * 1024);
stringXMLOut.read();
BYTE_ARRAY struXMLStatus = new BYTE_ARRAY(1024);
struXMLStatus.read();
NET_DVR_XML_CONFIG_OUTPUT struXMLOutput = new NET_DVR_XML_CONFIG_OUTPUT();
struXMLOutput.read();
struXMLOutput.dwSize = struXMLOutput.size();
struXMLOutput.lpOutBuffer = stringXMLOut.getPointer();
struXMLOutput.dwOutBufferSize = stringXMLOut.size();
struXMLOutput.lpStatusBuffer = struXMLStatus.getPointer();
struXMLOutput.dwStatusSize = struXMLStatus.size();
struXMLOutput.write();
if (!hKHCNetSDK.NET_DVR_STDXMLConfig(lUserID, struXMLInput, struXMLOutput)) {
int iErr = hKHCNetSDK.NET_DVR_GetLastError();
log.error("NET_DVR_STDXMLConfig失败,错误号:{},URL:{} ", iErr, url);
return null;
} else {
stringXMLOut.read();
log.info("输出文本大小:{}", struXMLOutput.dwReturnedXMLSize);
//打印输出XML文本
strOutXML = new String(stringXMLOut.byValue).trim();
log.info(strOutXML);
struXMLStatus.read();
String strStatus = new String(struXMLStatus.byValue).trim();
log.info(strStatus);
}
} catch (Exception e) {
log.error("ISAPI接口异常:{}", e);
}
return strOutXML;
}