package com.netsdk.demo.customize;
|
|
import com.netsdk.demo.util.CaseMenu;
|
import com.netsdk.lib.NetSDKLib;
|
import com.netsdk.lib.ToolKits;
|
import com.netsdk.lib.Utils;
|
import com.netsdk.lib.callback.impl.DefaultHaveReconnectCallBack;
|
import com.netsdk.lib.enumeration.EM_DATA_SOURCE_TYPE;
|
import com.netsdk.lib.enumeration.EM_EVENT_IVS;
|
import com.netsdk.lib.enumeration.EM_MATCH_TWO_FACE_TYPE;
|
import com.netsdk.lib.enumeration.ENUMERROR;
|
import com.netsdk.lib.structure.BYTE_ARRAY_1024;
|
import com.netsdk.lib.structure.NET_MATCH_TWO_FACE_IN;
|
import com.netsdk.lib.structure.NET_MATCH_TWO_FACE_OUT;
|
import com.netsdk.module.entity.AddAnalyseTaskResult;
|
import com.netsdk.module.entity.ImageCompareInfo;
|
import com.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.text.SimpleDateFormat;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
|
import static com.netsdk.lib.Utils.getOsPrefix;
|
|
public class ImageAnalyseDemo {
|
|
public static void main(String[] args) {
|
ImageAnalyseDemo demo=new ImageAnalyseDemo();
|
demo.initTest();
|
demo.runTest();
|
demo.endTest();
|
}
|
|
// 配置登陆地址,端口,用户名,密码
|
private String m_strIpAddr = "172.12.1.54";
|
private int m_nPort = 37777;
|
private String m_strUser = "admin";
|
private String m_strPassword = "admin123";
|
|
|
// SDk对象初始化
|
public static final NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
|
public static final NetSDKLib configsdk = NetSDKLib.CONFIG_INSTANCE;
|
|
/**
|
* 选择通道
|
*/
|
private int channelId = -1;// 逻辑通道
|
// 判断是否初始化
|
private static boolean bInit = false;
|
// 判断log是否打开
|
private static boolean bLogOpen = false;
|
// 设备信息
|
private NetSDKLib.NET_DEVICEINFO_Ex deviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
|
// 登录句柄
|
private NetSDKLib.LLong loginHandle = new NetSDKLib.LLong(0);
|
// 智能事件订阅句柄
|
private NetSDKLib.LLong m_attachHandle = new NetSDKLib.LLong(0);
|
|
//实现断线重连静态单例
|
public static class DefaultDisconnectCallback implements NetSDKLib.fDisConnect {
|
private static volatile DefaultDisconnectCallback INSTANCE;
|
|
private DefaultDisconnectCallback() {}
|
|
public static DefaultDisconnectCallback getINSTANCE() {
|
if (INSTANCE == null) {
|
synchronized (DefaultDisconnectCallback.class){
|
if (INSTANCE == null){
|
INSTANCE = new DefaultDisconnectCallback();
|
}
|
}
|
}
|
return INSTANCE;
|
}
|
|
@Override
|
public void invoke(NetSDKLib.LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
|
System.out.printf("Device[%s] Port[%d] DisConnected!\n", pchDVRIP, nDVRPort);
|
}
|
}
|
|
// 回调函数需要是静态的,防止被系统回收
|
// 断线回调
|
private static NetSDKLib.fDisConnect disConnectCB = MultiTalkDevDemo.DefaultDisconnectCallback.getINSTANCE();
|
// 重连回调
|
private static NetSDKLib.fHaveReConnect haveReConnectCB = DefaultHaveReconnectCallBack.getINSTANCE();
|
|
//订阅句柄
|
NetSDKLib.LLong lAttachHandle = new NetSDKLib.LLong(0);
|
// 编码格式
|
public static String encode;
|
|
static {
|
String osPrefix = getOsPrefix();
|
if (osPrefix.toLowerCase().startsWith("win32-amd64")) {
|
encode = "GBK";
|
} else if (osPrefix.toLowerCase().startsWith("linux-amd64")) {
|
encode = "UTF-8";
|
}
|
}
|
|
/**
|
* 按照指定格式,获取当前时间
|
*/
|
public static String getDate() {
|
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
return simpleDate.format(new Date()).replaceAll("[^0-9]", "-");
|
}
|
|
/**
|
* 初始化SDK库
|
*/
|
public static boolean initSdk() {
|
bInit = netsdk.CLIENT_Init(disConnectCB, null);// 进程启动时,初始化一次
|
if (!bInit) {
|
System.out.println("Initialize SDK failed");
|
return false;
|
}
|
// 配置日志
|
enableLog();
|
// 设置断线重连回调接口, 此操作为可选操作,但建议用户进行设置
|
netsdk.CLIENT_SetAutoReconnect(haveReConnectCB, null);
|
// 设置登录超时时间和尝试次数,可选
|
// 登录请求响应超时时间设置为3S
|
int waitTime = 3000; //单位为ms
|
// 登录时尝试建立链接 1 次
|
int tryTimes = 1;
|
// 设置连接设备超时时间和尝试次数
|
netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);
|
// 设置更多网络参数, NET_PARAM 的nWaittime , nConnectTryNum 成员与 CLIENT_SetConnectTime
|
// 接口设置的登录设备超时时间和尝试次数意义相同,可选
|
NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
|
// 登录时尝试建立链接的超时时间
|
netParam.nConnectTime = 10000;
|
// 设置子连接的超时时间
|
netParam.nGetConnInfoTime = 3000;
|
//设置登陆网络环境
|
netsdk.CLIENT_SetNetworkParam(netParam);
|
return true;
|
}
|
|
/**
|
* 打开 sdk log
|
*/
|
private static void enableLog() {
|
// SDK全局日志打印信息
|
NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
|
//设置日志路径
|
File path = new File("sdklog/");
|
//判断日志路径是否存在,若不存在则创建
|
if (!path.exists()){
|
path.mkdir();
|
}
|
// 这里的log保存地址依据实际情况自己调整
|
String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + "sdklog" + getDate() + ".log";
|
//日志输出策略,0:输出到文件(默认); 1:输出到窗口,
|
setLog.nPrintStrategy = 0;
|
//是否重设日志路径, 取值0否 ,1是
|
setLog.bSetFilePath = 1;
|
//日志路径(默认"./sdk_log/sdk_log.log")
|
byte[] szLogFilePath = setLog.szLogFilePath;
|
//自定义log保存地址,将数据logPath数据copy到LOG_SET_PRINT_INFO-->szLogFilePath变量中
|
System.arraycopy(logPath.getBytes(), 0, szLogFilePath, 0, logPath.getBytes().length);
|
//是否重设日志打印输出策略 取值0否 ,1是
|
setLog.bSetPrintStrategy = 1;
|
// 打开日志功能
|
bLogOpen = netsdk.CLIENT_LogOpen(setLog);
|
if (!bLogOpen){
|
System.err.println("Failed to open NetSDK log. ErrorCode=%s\n "+ ToolKits.getErrorCode());
|
}else {
|
System.out.println("Success to open NetSDK log ");
|
}
|
}
|
|
/**
|
* 高安全登录
|
*/
|
public void loginWithHighLevel() {
|
// 输入结构体参数
|
NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstlnParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY() {
|
{
|
// IP
|
szIP = m_strIpAddr.getBytes();
|
// 端口
|
nPort = m_nPort;
|
// 用户名
|
szUserName = m_strUser.getBytes();
|
// 密码
|
szPassword = m_strPassword.getBytes();
|
}
|
};
|
// 登录的输出结构体参数
|
NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
|
// 高安全级别登陆
|
loginHandle = netsdk.CLIENT_LoginWithHighLevelSecurity(pstlnParam, pstOutParam);
|
if (loginHandle.longValue() == 0) { //登陆失败
|
System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIpAddr, m_nPort, ToolKits.getErrorCode());
|
|
} else {
|
//登陆成功
|
// 获取设备信息
|
deviceInfo = pstOutParam.stuDeviceInfo;
|
System.out.printf("Login Success Device Address[%s] 设备包含[%d]个通道 \n",m_strIpAddr,deviceInfo.byChanNum);
|
}
|
}
|
|
|
/**
|
* 退出
|
*/
|
public void logOut() {
|
//判断是否已登录
|
if (loginHandle.longValue() != 0) {
|
netsdk.CLIENT_Logout(loginHandle);
|
System.out.println("LogOut Success");
|
}
|
}
|
|
/**
|
* 清理sdk环境并退出
|
*/
|
public static void cleanAndExit() {
|
//判断log是否打开
|
if (bLogOpen) {
|
// 关闭sdk日志打印
|
netsdk.CLIENT_LogClose();
|
}
|
// 进程关闭时,调用一次
|
netsdk.CLIENT_Cleanup();
|
System.exit(0);
|
}
|
|
/**
|
* 初始化测试
|
*/
|
public void initTest() {
|
initSdk();
|
|
this.loginWithHighLevel();
|
}
|
|
/**
|
* 结束测试
|
*/
|
public void endTest() {
|
System.out.println("End Test");
|
this.logOut(); // 登出设备
|
System.out.println("See You...");
|
cleanAndExit(); // 清理资源并退出
|
}
|
|
public void runTest()
|
{
|
System.out.println("Run Test");
|
CaseMenu menu = new CaseMenu();
|
menu.addItem(new CaseMenu.Item(this, "获取能力集", "getAnalyseCaps"));
|
menu.addItem(new CaseMenu.Item(this, "添加智能分析任务", "addTask"));
|
menu.addItem(new CaseMenu.Item(this, "订阅智能分析任务", "attachAnalyseTask"));
|
menu.addItem(new CaseMenu.Item(this, "推送图片", "pushPicture"));
|
menu.addItem(new CaseMenu.Item(this, "特征值比对", "matchPicture"));
|
menu.addItem(new CaseMenu.Item(this, "取消订阅", "detachAnalyseTask"));
|
menu.run();
|
}
|
|
//任务id
|
private int taskId;
|
//能力
|
List<byte[]> analyseCaps = new ArrayList<>();
|
//特征值列表
|
static List<byte[]> featureList = new ArrayList<>();
|
/**
|
* 特征值比对
|
*/
|
public void matchPicture() {
|
try {
|
if(featureList.size() >= 2){
|
int result = matchFeature(loginHandle, featureList.get(0), featureList.get(1), 3000);
|
System.out.println(result);
|
}
|
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
|
|
/**
|
* 特征值比对
|
*
|
* @param originFeature 原图片特征值
|
* @param compareFeature 需要对比的图片特征值
|
* @param waitTime 超时时间,默认超时时间3000
|
* @return 相似度 0-100
|
*/
|
public int matchFeature(NetSDKLib.LLong loginHandle, byte[] originFeature, byte[] compareFeature, int waitTime) throws IOException {
|
System.out.println("size1==" + originFeature.length);
|
System.out.println("size2==" + compareFeature.length);
|
|
NET_MATCH_TWO_FACE_IN inParam = new NET_MATCH_TWO_FACE_IN();
|
//特征值比对 不填默认图片对比
|
inParam.emType = EM_MATCH_TWO_FACE_TYPE.EM_MATCH_TWO_FACE_TYPE_EIGENVALUE.getValue();
|
//特征值参数
|
// 原图片特征值赋值
|
BYTE_ARRAY_1024 byteArray1 = new BYTE_ARRAY_1024();
|
System.arraycopy(originFeature, 0, byteArray1.obj_1024, 0, originFeature.length);
|
System.out.println("originFeature.length==" + originFeature.length);
|
// 需要对比的图片特征值赋值
|
BYTE_ARRAY_1024 byteArray2 = new BYTE_ARRAY_1024();
|
System.arraycopy(compareFeature, 0, byteArray2.obj_1024, 0, compareFeature.length);
|
System.out.println("compareFeature.length==" + compareFeature.length);
|
|
inParam.szFeature[0] = byteArray1;
|
inParam.szFeature[1] = byteArray2;
|
for (int i = 0;i < originFeature.length;i++) {
|
System.out.print(inParam.szFeature[0].obj_1024[i] + " ");
|
}
|
System.out.println("");
|
System.out.println("-------------");
|
for (int i = 0;i < compareFeature.length;i++) {
|
System.out.print(inParam.szFeature[1].obj_1024[i] + " ");
|
}
|
System.out.println("");
|
inParam.nFeatureLen[0] = originFeature.length;
|
inParam.nFeatureLen[1] = compareFeature.length;
|
|
NET_MATCH_TWO_FACE_OUT outParam = new NET_MATCH_TWO_FACE_OUT();
|
inParam.write();
|
outParam.write();
|
|
boolean result = netsdk.CLIENT_MatchTwoFaceImage(loginHandle, inParam.getPointer(), outParam.getPointer(), waitTime);
|
|
if (!result) {
|
System.out.println("match two image failed. ErrorCode=%s\n " + ToolKits.getErrorCode());
|
return outParam.nSimilarity;
|
}
|
inParam.read();
|
outParam.read();
|
return outParam.nSimilarity;
|
}
|
|
|
|
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;
|
}
|
|
|
/******************************************** 获取设备能力集 ********************************************
|
******************************************************************************************************
|
******************************************************************************************************/
|
/**
|
* 设备智能分析服务能力集查询
|
*/
|
public void getAnalyseCaps() {
|
// 查询结构体入参
|
NetSDKLib.NET_ANALYSE_CAPS_ALGORITHM stuCapsOutParam = new NetSDKLib.NET_ANALYSE_CAPS_ALGORITHM();
|
|
int emCapsType = NetSDKLib.EM_ANALYSE_CAPS_TYPE.EM_ANALYSE_CAPS_ALGORITHM; // 智能分析服务能力类型 1
|
|
stuCapsOutParam.write(); // 写入内存
|
boolean ret = netsdk.CLIENT_GetAnalyseCaps(loginHandle, emCapsType, stuCapsOutParam.getPointer(), 3000);
|
stuCapsOutParam.read(); // 从内存重新读取
|
|
if (!ret) {
|
System.err.printf("failed to get analyse caps. ErrorCode=%s\n", ToolKits.getErrorCode());
|
return;
|
}
|
|
System.out.println("当前设备支持特征向量个数:" + stuCapsOutParam.nAlgorithmNum);
|
analyseCaps.clear();//赋值前先清理一下数据
|
for (int i = 0; i < stuCapsOutParam.nAlgorithmNum; i++) {
|
String info = "第" + (i + 1) + "个\n" +
|
"场景类型:" + stuCapsOutParam.stuAlgorithmInfos[i].emClassType + "\n" + // 枚举,参考 EM_SCENE_CLASS_TYPE
|
"特征向量版本号:" + new String(stuCapsOutParam.stuAlgorithmInfos[i].szVersion) + "\n" +
|
"算法商:" + stuCapsOutParam.stuAlgorithmInfos[i].emAlgorithmVendor;
|
analyseCaps.add(stuCapsOutParam.stuAlgorithmInfos[i].szVersion);
|
System.out.println(info);
|
}
|
}
|
|
/**
|
* 添加智能分析任务
|
*/
|
public void addTask() {
|
NetSDKLib.NET_PUSH_PICFILE_INFO inParam = new NetSDKLib.NET_PUSH_PICFILE_INFO();
|
//立刻启动
|
inParam.emStartRule = NetSDKLib.EM_ANALYSE_TASK_START_RULE.EM_ANALYSE_TASK_START_NOW;
|
//配置分析规则
|
//分析规则条数
|
inParam.stuRuleInfo.nRuleCount = 1;
|
//特征提取大类
|
inParam.stuRuleInfo.stuRuleInfos[0].emClassType = NetSDKLib.EM_SCENE_CLASS_TYPE.EM_SCENE_CLASS_FEATURE_ABSTRACT;
|
//特征提取
|
inParam.stuRuleInfo.stuRuleInfos[0].dwRuleType = EM_EVENT_IVS.EVENT_IVS_FEATURE_ABSTRACT.getId();
|
|
//检测物体类型个数
|
inParam.stuRuleInfo.stuRuleInfos[0].nObjectTypeNum = 1;
|
//检测物体类型列表,检测人脸
|
inParam.stuRuleInfo.stuRuleInfos[0].emObjectTypes[0] = NetSDKLib.EM_ANALYSE_OBJECT_TYPE.EM_ANALYSE_OBJECT_TYPE_HUMANFACE;
|
//事件类型EVENT_IVS_FEATURE_ABSTRACT(提取特征)对应的规则配置
|
NetSDKLib.NET_FEATURE_ABSTRACT_RULE_INFO sRuleInfo = new NetSDKLib.NET_FEATURE_ABSTRACT_RULE_INFO();
|
|
sRuleInfo.emAbstractType = NetSDKLib.EM_FEATURE_ABSTRACT_TYPE.EM_FEATURE_ABSTRACT_FACE; // 特征提取的类型:人脸
|
sRuleInfo.nFeature = analyseCaps.size(); // 提取数量
|
|
byte[] version001 = analyseCaps.get(0); // 这里使用的是能力集获取时得到的版本号
|
System.arraycopy(version001, 0, sRuleInfo.szFeatureVersions[0].szFeatureVersion, 0, version001.length);
|
// 出参
|
NetSDKLib.NET_OUT_ADD_ANALYSE_TASK stuOutParam = new NetSDKLib.NET_OUT_ADD_ANALYSE_TASK();
|
|
AddAnalyseTaskResult result = addAnalyseTask(loginHandle, EM_DATA_SOURCE_TYPE.EM_DATA_SOURCE_PUSH_PICFILE, inParam, 3000);
|
if (result.isResult()) {
|
taskId = result.getTaskId();
|
System.out.println("success to addTask.");
|
}else {
|
System.out.printf("failed to addTask. ErrorCode=%s\n", ToolKits.getErrorCode());
|
return;
|
}
|
}
|
|
|
/**
|
* 添加智能分析任务
|
*
|
* @param loginHandle 登录句柄
|
* @param type 智能分析数据源类型{@link EM_DATA_SOURCE_TYPE}
|
* @param inParam 输入参数,类型参考{@link EM_DATA_SOURCE_TYPE}所对应的结构体
|
* @param waitTime 超时时间
|
* @return 智能分析任务的结果
|
*/
|
public AddAnalyseTaskResult addAnalyseTask(NetSDKLib.LLong loginHandle, 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 = netsdk.CLIENT_AddAnalyseTask(loginHandle, type.getType(), pointer, outParam, waitTime);
|
AddAnalyseTaskResult taskResult = new AddAnalyseTaskResult();
|
taskResult.setResult(result);
|
if (!result) {
|
System.out.println("add analyseTask failed. ErrorCode=%s\n " + ToolKits.getErrorCode());
|
return taskResult;
|
}
|
outParam.read();
|
taskResult.setTaskId(outParam.nTaskID);
|
taskResult.setVirtualChannel(outParam.nVirtualChannel);
|
return taskResult;
|
}
|
|
|
/**
|
* 订阅智能分析任务
|
*/
|
public void attachAnalyseTask() {
|
//分析任务id数组
|
int[] taskIds = new int[]{taskId};
|
//过滤的事件类型
|
int[] filterAlarmTypes = new int[]{};
|
//是否包含图片
|
boolean isFilterImage = true;
|
//智能分析的回调函数
|
NetSDKLib.fAnalyseTaskResultCallBack callBack = DefaultAnalyseTaskResultCallBack.getSingleInstance();
|
//超时时间
|
int waitTime = 3000;
|
//自定义数据,不需要可传入null
|
Structure dwUser = null;
|
//对数组长度进行校验
|
if (taskIds.length > NetSDKLib.MAX_ANALYSE_TASK_NUM) {
|
System.out.println("taskIds's length is outOfBounds.please check");
|
return;
|
}
|
if (filterAlarmTypes.length > NetSDKLib.MAX_ANALYSE_FILTER_EVENT_NUM) {
|
System.out.println("dwAlarms's length is outOfBounds.Please check.");
|
}
|
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 = netsdk.CLIENT_AttachAnalyseTaskResult(loginHandle, inParam, waitTime);
|
if (attachHandler.longValue() == 0) {
|
System.out.println("attach analyseTask failed. error is " + ENUMERROR.getErrorMessage());
|
|
}else{
|
System.out.println("attach analyseTask success. attachHandler is" + attachHandler.longValue());
|
}
|
m_attachHandle = attachHandler;
|
}
|
|
|
/**
|
* 主动推送图片
|
*/
|
public void pushPicture() {
|
List<PushAnalysePictureInfo> infos = new ArrayList<>();
|
//推送的图片最好是jg,100k以下
|
infos.add(new PushAnalysePictureInfo("D:/img/2.jpg", "test"));
|
infos.add(new PushAnalysePictureInfo("D:/img/2.jpg", "test"));
|
|
int type = 1;//推送图片,不为1则为推送url
|
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);
|
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;
|
}
|
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);
|
byte[] fileId = info.getFileID().getBytes(Charset.forName(Utils.getPlatformEncode()));
|
System.arraycopy(fileId, 0, inParam.stuPushPicInfos[i].szFileID, 0, fileId.length);
|
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 = netsdk.CLIENT_PushAnalysePictureFile(loginHandle, inParam, outParam, 3000);
|
if (!result) {
|
System.out.println("push picture failed. ErrorCode=%s\n" + ToolKits.getErrorCode());
|
}else{
|
System.out.println("push picture success.");
|
}
|
}
|
|
|
|
/**
|
* 智能分析退订
|
*/
|
public void detachAnalyseTask() {
|
boolean result = netsdk.CLIENT_DetachAnalyseTaskResult(m_attachHandle);
|
if (!result) {
|
System.out.println("detach analyseTask result failed. ErrorCode=%s\n" + ToolKits.getErrorCode());
|
}else {
|
System.out.println("detach analyseTask result success.");
|
}
|
}
|
|
|
public static class DefaultAnalyseTaskResultCallBack implements NetSDKLib.fAnalyseTaskResultCallBack {
|
|
private static DefaultAnalyseTaskResultCallBack singleInstance;
|
private File picturePath;
|
private static NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO msg=new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO();
|
|
private DefaultAnalyseTaskResultCallBack() {
|
picturePath = new File("./AnalyzerPicture/");
|
if (!picturePath.exists()) {
|
picturePath.mkdir();
|
}
|
}
|
|
public static DefaultAnalyseTaskResultCallBack getSingleInstance() {
|
if (singleInstance == null) {
|
singleInstance = new DefaultAnalyseTaskResultCallBack();
|
}
|
return singleInstance;
|
}
|
|
@Override
|
public int invoke(NetSDKLib.LLong lAttachHandle, Pointer pstAnalyseTaskResult, Pointer pBuf, int dwBufSize, Pointer dwUser) {
|
long start=System.currentTimeMillis();
|
NetSDKLib.NET_CB_ANALYSE_TASK_RESULT_INFO task = new NetSDKLib.NET_CB_ANALYSE_TASK_RESULT_INFO();
|
ToolKits.GetPointerData(pstAnalyseTaskResult, task); // 从指针获取智能事件分析信息
|
|
for (int i = 0; i < task.nTaskResultNum; i++) {
|
// nTaskID 和主动推送时的一一对应
|
System.out.println(task.stuTaskResultInfos[i].nTaskID);
|
// 实际的事件个数
|
for (int j = 0; j < task.stuTaskResultInfos[i].nEventCount; j++) {
|
NetSDKLib.NET_SECONDARY_ANALYSE_EVENT_INFO info = task.stuTaskResultInfos[i].stuEventInfos[j];
|
// 事件类型 对应 EM_ANALYSE_EVENT_TYPE
|
System.out.println("type:" + info.emEventType);
|
switch (info.emEventType) {
|
//特征提取
|
case NetSDKLib.EM_ANALYSE_EVENT_TYPE.EM_ANALYSE_EVENT_FEATURE_ABSTRACT: {
|
NetSDKLib.DEV_EVENT_FEATURE_ABSTRACT_INFO stInfo = new NetSDKLib.DEV_EVENT_FEATURE_ABSTRACT_INFO();
|
ToolKits.GetPointerDataToStruct(info.pstEventInfo, 0, stInfo);
|
|
System.out.println("nChannelID:" + stInfo.nChannelID); // 通道号
|
System.out.println("nAction:" + stInfo.nAction); // 0:脉冲 1:开始 2:停止
|
System.out.println("emClassType:" + stInfo.emClassType); // 智能事件所属大类 参考 EM_CLASS_TYPE
|
|
for (int k = 0; k < stInfo.nFeatureNum; k++) {
|
// 错误码、特征版本号
|
System.out.println("FeatureVectorList[" + k + "].FeatureErrCode:" + stInfo.stuFeatureVectorList[k].emFeatureErrCode); // 错误码
|
System.out.println("FeatureVectorList[" + k + "].szFeatureVersion:" + new String(stInfo.stuFeatureVectorList[k].szFeatureVersion).trim()); // 特征版本版本号
|
// 这里的特征是设备用于比对的二进制数据,不是图片,具体内容请咨询设备研发
|
int bufOffset = stInfo.stuFeatureVectorList[k].stuFeatureVector.dwOffset;
|
int bufSize = stInfo.stuFeatureVectorList[k].stuFeatureVector.dwLength;
|
System.out.println("FeatureVectorList[" + k + "].stuFeatureVector.dwOffset:" + bufOffset); // 人脸小图特征值在二进制数据块中的偏移
|
System.out.println("FeatureVectorList[" + k + "].stuFeatureVector.dwLength:" + bufSize); // 人脸小图特征值长度,单位:字节
|
byte[] byteArray = pBuf.getByteArray(bufOffset, bufSize);
|
/**
|
* 保存特征值
|
*/
|
featureList.add(byteArray);
|
System.out.println(byteArray);
|
// 人脸抓拍角度、质量数据
|
System.out.println("FeatureVectorList[" + k + "].stuFaceAttribute.nAngle1:" + stInfo.stuFeatureVectorList[k].stuFaceAttribute.nAngle[0]); // 人脸抓拍角度,三个角度分别是:仰俯角,偏航角,翻滚角;默认值[999,999,999]表示无此数据
|
System.out.println("FeatureVectorList[" + k + "].stuFaceAttribute.nAngle2:" + stInfo.stuFeatureVectorList[k].stuFaceAttribute.nAngle[1]); // 偏航角
|
System.out.println("FeatureVectorList[" + k + "].stuFaceAttribute.nAngle3:" + stInfo.stuFeatureVectorList[k].stuFaceAttribute.nAngle[2]); // 翻滚角
|
System.out.println("FeatureVectorList[" + k + "].stuFeatureVector.nFaceAlignScore:" + stInfo.stuFeatureVectorList[k].stuFaceAttribute.nFaceAlignScore); // 人脸对齐得分分数,取值范围 0~10000,-1为无效值
|
System.out.println("FeatureVectorList[" + k + "].stuFeatureVector.nFaceQuality:" + stInfo.stuFeatureVectorList[k].stuFaceAttribute.nFaceQuality); // 人脸抓拍质量分数,取值范围 0~10000
|
}
|
break;
|
}
|
|
default: {
|
System.out.println("default");
|
break;
|
}
|
}
|
}
|
System.out.println(new String(task.stuTaskResultInfos[i].szFileID, Charset.forName(Utils.getPlatformEncode())).trim());
|
}
|
long end=System.currentTimeMillis();
|
System.out.println("cost millions: "+(end-start));
|
return 0;
|
}
|
}
|
}
|