package com.dahua.netsdk.module;
|
|
import com.dahua.netsdk.lib.NetSDKLib;
|
import com.dahua.netsdk.lib.ToolKits;
|
import com.dahua.netsdk.lib.Utils;
|
import com.dahua.netsdk.lib.enumeration.EM_DATA_SOURCE_TYPE;
|
import com.dahua.netsdk.lib.enumeration.ENUMERROR;
|
import com.dahua.netsdk.lib.structure.NET_MATCH_TWO_FACE_IN;
|
import com.dahua.netsdk.lib.structure.NET_MATCH_TWO_FACE_OUT;
|
import com.dahua.netsdk.module.entity.AddAnalyseTaskResult;
|
import com.dahua.netsdk.module.entity.ImageCompareInfo;
|
import com.dahua.netsdk.module.entity.PushAnalysePictureInfo;
|
import com.sun.jna.Memory;
|
import com.sun.jna.Pointer;
|
import com.sun.jna.Structure;
|
|
import javax.imageio.ImageIO;
|
import java.awt.image.BufferedImage;
|
import java.io.*;
|
import java.nio.charset.Charset;
|
import java.util.List;
|
|
/**
|
* @author 47081
|
* @version 1.0
|
* @description 智能分析任务模块, 对智能分析任务相关接口进行二次封装, 方便调用
|
* @date 2020/10/19
|
*/
|
public class AnalyseTaskModule extends BaseModule {
|
|
public AnalyseTaskModule(NetSDKLib netSdkApi) {
|
super(netSdkApi);
|
}
|
|
public AnalyseTaskModule() {
|
super();
|
}
|
|
/**
|
* 1:1图片比对
|
*
|
* @param originImage 原图片
|
* @param compareImage 需要对比的图片
|
* @param waitTime 超时时间,默认超时时间3000
|
* @return 相似度 0-100
|
*/
|
public int matchImage(long loginHandler, InputStream originImage, InputStream compareImage, int waitTime) throws IOException {
|
BufferedImage image = ImageIO.read(originImage);
|
NET_MATCH_TWO_FACE_IN inParam = new NET_MATCH_TWO_FACE_IN();
|
ImageCompareInfo originInfo = readImage(image);
|
//偏移量
|
inParam.stuOriginalImage.dwoffset = 0;
|
|
inParam.stuOriginalImage.dwLength = originInfo.getLength();
|
inParam.stuOriginalImage.dwWidth = originInfo.getWidth();
|
inParam.stuOriginalImage.dwHeight = originInfo.getHeight();
|
image = ImageIO.read(compareImage);
|
|
ImageCompareInfo compareInfo = readImage(image);
|
//偏移量
|
inParam.stuCompareImage.dwoffset = originInfo.getLength();
|
inParam.stuCompareImage.dwLength = compareInfo.getLength();
|
inParam.stuCompareImage.dwHeight = compareInfo.getHeight();
|
inParam.stuCompareImage.dwWidth = compareInfo.getWidth();
|
//图片写入
|
inParam.pSendBuf = new Memory(originInfo.getLength() + compareInfo.getLength());
|
inParam.pSendBuf.write(0, originInfo.getData(), 0, originInfo.getLength());
|
inParam.pSendBuf.write(originInfo.getLength(), compareInfo.getData(), 0, compareInfo.getLength());
|
//下发的数据大小
|
inParam.dwSendBufLen = originInfo.getLength() + compareInfo.getLength();
|
NET_MATCH_TWO_FACE_OUT outParam = new NET_MATCH_TWO_FACE_OUT();
|
Pointer pInParam = new Memory(inParam.size());
|
ToolKits.SetStructDataToPointer(inParam, pInParam, 0);
|
Pointer pOutParam = new Memory(outParam.size());
|
ToolKits.SetStructDataToPointer(outParam, pOutParam, 0);
|
|
boolean result = getNetsdkApi().CLIENT_MatchTwoFaceImage(new NetSDKLib.LLong(loginHandler), pInParam, pOutParam, waitTime);
|
|
if (!result) {
|
System.out.println("match two image failed. error is " + ENUMERROR.getErrorMessage());
|
return 0;
|
}
|
ToolKits.GetPointerData(pOutParam, outParam);
|
return outParam.nSimilarity;
|
}
|
|
/**
|
* 读取图片信息
|
*
|
* @param image 缓存的图片
|
* @return
|
* @throws IOException
|
*/
|
private ImageCompareInfo readImage(BufferedImage image) {
|
return readImage(image, "jpg");
|
}
|
|
private ImageCompareInfo readImage(BufferedImage image, String format) {
|
ImageCompareInfo info = null;
|
try {
|
info = new ImageCompareInfo();
|
info.setHeight(image.getHeight());
|
info.setWidth(image.getWidth());
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
ImageIO.write(image, format, outputStream);
|
info.setData(outputStream.toByteArray());
|
info.setLength(outputStream.size());
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
|
return info;
|
}
|
|
/**
|
* 添加智能分析任务
|
*
|
* @param loginHandler 登录句柄
|
* @param type 智能分析数据源类型{@link EM_DATA_SOURCE_TYPE}
|
* @param inParam 输入参数,类型参考{@link EM_DATA_SOURCE_TYPE}所对应的结构体
|
* @param waitTime 超时时间
|
* @return 智能分析任务的结果
|
*/
|
public AddAnalyseTaskResult addAnalyseTask(long loginHandler, EM_DATA_SOURCE_TYPE type, NetSDKLib.SdkStructure inParam, int waitTime) {
|
Pointer pointer = new Memory(inParam.size());
|
ToolKits.SetStructDataToPointer(inParam, pointer, 0);
|
NetSDKLib.NET_OUT_ADD_ANALYSE_TASK outParam = new NetSDKLib.NET_OUT_ADD_ANALYSE_TASK();
|
outParam.write();
|
boolean result = getNetsdkApi().CLIENT_AddAnalyseTask(new NetSDKLib.LLong(loginHandler), type.getType(), pointer, outParam, waitTime);
|
AddAnalyseTaskResult taskResult = new AddAnalyseTaskResult();
|
taskResult.setResult(result);
|
if (!result) {
|
System.out.println("add analyseTask failed.error is " + ENUMERROR.getErrorMessage());
|
return taskResult;
|
}
|
outParam.read();
|
taskResult.setTaskId(outParam.nTaskID);
|
taskResult.setVirtualChannel(outParam.nVirtualChannel);
|
return taskResult;
|
}
|
|
/**
|
* 启动智能分析任务
|
*
|
* @param loginHandler 登录句柄
|
* @param taskId 任务id
|
* @param waitTime 超时时间
|
* @return 任务是否启动成功
|
*/
|
public boolean startAnalyseTask(long loginHandler, int taskId, int waitTime) {
|
NetSDKLib.NET_IN_START_ANALYSE_TASK inParam = new NetSDKLib.NET_IN_START_ANALYSE_TASK();
|
inParam.nTaskID = taskId;
|
NetSDKLib.NET_OUT_START_ANALYSE_TASK outParam = new NetSDKLib.NET_OUT_START_ANALYSE_TASK();
|
boolean result = getNetsdkApi().CLIENT_StartAnalyseTask(new NetSDKLib.LLong(loginHandler), inParam, outParam, waitTime);
|
if (!result) {
|
System.out.println("start analyse task failed.error is " + ENUMERROR.getErrorMessage());
|
}
|
return result;
|
}
|
|
/**
|
* 订阅智能分析任务
|
*
|
* @param loginHandler 登录句柄
|
* @param taskIds 分析任务id数组
|
* @param filterAlarmTypes 过滤的事件类型
|
* @param isFilterImage 是否包含图片
|
* @param waitTime 超时时间
|
* @param callBack 智能分析的回调函数
|
* @param dwUser 自定义数据,不需要可传入null
|
* @return 订阅句柄, 句柄为0表示订阅失败, 句柄不为0订阅成功
|
*/
|
public long attachAnalyseTaskResult(long loginHandler, int[] taskIds, int[] filterAlarmTypes, boolean isFilterImage, NetSDKLib.fAnalyseTaskResultCallBack callBack, int waitTime, Structure dwUser) {
|
//对数组长度进行校验
|
if (taskIds.length > NetSDKLib.MAX_ANALYSE_TASK_NUM) {
|
System.out.println("taskIds's length is outOfBounds.please check");
|
return 0;
|
}
|
if (filterAlarmTypes.length > NetSDKLib.MAX_ANALYSE_FILTER_EVENT_NUM) {
|
System.out.println("dwAlarms's length is outOfBounds.Please check.");
|
return 0;
|
}
|
NetSDKLib.NET_IN_ATTACH_ANALYSE_RESULT inParam = new NetSDKLib.NET_IN_ATTACH_ANALYSE_RESULT();
|
//赋值
|
inParam.nTaskIdNum = taskIds.length;
|
System.arraycopy(taskIds, 0, inParam.nTaskIDs, 0, taskIds.length);
|
inParam.stuFilter.nEventNum = filterAlarmTypes.length;
|
System.arraycopy(filterAlarmTypes, 0, inParam.stuFilter.dwAlarmTypes, 0, filterAlarmTypes.length);
|
inParam.stuFilter.nImageDataFlag = isFilterImage ? 1 : 0;
|
inParam.cbAnalyseTaskResult = callBack;
|
if (dwUser != null) {
|
inParam.dwUser = dwUser.getPointer();
|
}
|
NetSDKLib.LLong attachHandler = getNetsdkApi().CLIENT_AttachAnalyseTaskResult(new NetSDKLib.LLong(loginHandler), inParam, waitTime);
|
if (attachHandler.longValue() == 0) {
|
System.out.println("attach analyseTask failed. error is " + ENUMERROR.getErrorMessage());
|
return 0;
|
}
|
return attachHandler.longValue();
|
}
|
|
/**
|
* 订阅智能分析任务
|
*
|
* @param loginHandler 登录句柄
|
* @param taskIds 分析任务id
|
* @param isFilterImage 是否包含图片
|
* @param callBack 订阅回调函数,建议写成单例模式
|
* @param waitTime 超时时间
|
* @param dwUser 自定义数据
|
* @return 订阅句柄, 句柄为0表示订阅失败, 不为0订阅成功
|
*/
|
public long attachAnalyseTaskResult(long loginHandler, int[] taskIds, boolean isFilterImage, NetSDKLib.fAnalyseTaskResultCallBack callBack, int waitTime, Structure dwUser) {
|
return attachAnalyseTaskResult(loginHandler, taskIds, new int[]{}, isFilterImage, callBack, waitTime, dwUser);
|
}
|
|
/**
|
* 智能分析退订
|
*
|
* @param attachHandler 订阅句柄
|
* @return 是否成功退订
|
*/
|
public boolean detachAnalyseTaskResult(long attachHandler) {
|
boolean result = getNetsdkApi().CLIENT_DetachAnalyseTaskResult(new NetSDKLib.LLong(attachHandler));
|
if (!result) {
|
System.out.println("detach analyseTask result failed. error is " + ENUMERROR.getErrorMessage());
|
}
|
return result;
|
}
|
|
///////////////////////////推送图片有两种方式:文件的形式和远程url的方式,选择一种即可//////////////////////////////
|
|
/**
|
* @param type 推送图片还是url,1:图片文件,0:url
|
* @param infos
|
* @return
|
*/
|
public boolean pushAnalysePicture(long loginHandler, int taskId, int type, List<PushAnalysePictureInfo> infos, int waitTime) {
|
if (type != 1 && type != 0) {
|
System.out.println("wrong type.please check.type 1: pictures,0:url");
|
return false;
|
}
|
|
NetSDKLib.NET_IN_PUSH_ANALYSE_PICTURE_FILE inParam = new NetSDKLib.NET_IN_PUSH_ANALYSE_PICTURE_FILE();
|
if (infos.size() > inParam.stuPushPicInfos.length) {
|
System.out.println("infos's length is outOfBounds in stuPushInfos.");
|
}
|
inParam.nTaskID = taskId;
|
inParam.nPicNum = infos.size();
|
PushAnalysePictureInfo info = null;
|
File file = null;
|
int totalLength = 0;
|
//推送图片
|
if (type == 1) {
|
for (int i = 0; i < inParam.nPicNum; i++) {
|
info = infos.get(i);
|
|
byte[] fileId = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
System.arraycopy(fileId, 0, inParam.stuPushPicInfos[i].szFileID, 0, fileId.length);
|
|
//inParam.stuPushPicInfos[i].szFileID = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
if (i == 0) {
|
inParam.stuPushPicInfos[i].nOffset = 0;
|
} else {
|
inParam.stuPushPicInfos[i].nOffset = inParam.stuPushPicInfos[i - 1].nLength;
|
}
|
file = new File(info.getName());
|
inParam.stuPushPicInfos[i].nLength = (int) file.length();
|
totalLength += inParam.stuPushPicInfos[i].nLength;
|
//stuXRayCustomInfo暂不赋值,自定义数据,xX光机专用
|
}
|
inParam.nBinBufLen = totalLength;
|
//写入图片到Pointer
|
inParam.pBinBuf = new Memory(totalLength);
|
byte[] data;
|
int offset = 0;
|
for (PushAnalysePictureInfo picture : infos) {
|
|
try {
|
FileInputStream inputStream = null;
|
file = new File(picture.getName());
|
data = new byte[(int) file.length()];
|
inputStream = new FileInputStream(file);
|
inputStream.read(data);
|
inParam.pBinBuf.write(offset, data, 0, data.length);
|
offset += data.length;
|
inputStream.close();
|
} catch (FileNotFoundException e) {
|
e.printStackTrace();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
} else {
|
//推送url
|
for (int i = 0; i < infos.size(); i++) {
|
info = infos.get(i);
|
// inParam.stuPushPicInfos[i].szFileID = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
byte[] fileId = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
System.arraycopy(fileId, 0, inParam.stuPushPicInfos[i].szFileID, 0, fileId.length);
|
// inParam.stuPushPicInfos[i].szUrl = info.getName().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
byte[] name = info.getName().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
System.arraycopy(name, 0, inParam.stuPushPicInfos[i].szUrl, 0, name.length);
|
}
|
}
|
NetSDKLib.NET_OUT_PUSH_ANALYSE_PICTURE_FILE outParam = new NetSDKLib.NET_OUT_PUSH_ANALYSE_PICTURE_FILE();
|
boolean result = getNetsdkApi().CLIENT_PushAnalysePictureFile(new NetSDKLib.LLong(loginHandler), inParam, outParam, waitTime);
|
if (!result) {
|
System.out.println("push picture failed.error is " + ENUMERROR.getErrorMessage());
|
}
|
return result;
|
}
|
|
/**
|
* 删除(停止)智能分析任务
|
*
|
* @param loginHandler 登录句柄
|
* @param taskId 智能任务id
|
* @param waitTime 超时时间
|
* @return 删除分析任务是否成功
|
*/
|
public boolean removeAnalyseTask(long loginHandler, int taskId, int waitTime) {
|
NetSDKLib.NET_IN_REMOVE_ANALYSE_TASK inParam = new NetSDKLib.NET_IN_REMOVE_ANALYSE_TASK();
|
inParam.nTaskID = taskId;
|
NetSDKLib.NET_OUT_REMOVE_ANALYSE_TASK outParam = new NetSDKLib.NET_OUT_REMOVE_ANALYSE_TASK();
|
boolean result = getNetsdkApi().CLIENT_RemoveAnalyseTask(new NetSDKLib.LLong(loginHandler), inParam, outParam, waitTime);
|
if (!result) {
|
System.out.println("remove analyseTask failed.error is " + ENUMERROR.getErrorMessage());
|
}
|
return result;
|
}
|
|
}
|