zhanghua
2024-09-28 7873c6f56380d28e1ae6958f77a84081797c817f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.dahua.netsdk.lib.callback.impl;
 
import com.dahua.netsdk.lib.NetSDKLib;
import com.dahua.netsdk.lib.ToolKits;
import com.dahua.netsdk.lib.Utils;
import com.sun.jna.Pointer;
 
import java.io.File;
import java.nio.charset.Charset;
 
/**
 * @author : 47040
 * @since : Created in 2020/7/18 10:51
 */
public 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());   // 特征版本版本号
                            // 这里的特征是设备用于比对的二进制数据,不是图片,具体内容请咨询设备研发
                            System.out.println("FeatureVectorList[" + k + "].stuFeatureVector.dwOffset:" + stInfo.stuFeatureVectorList[k].stuFeatureVector.dwOffset);    // 人脸小图特征值在二进制数据块中的偏移
                            System.out.println("FeatureVectorList[" + k + "].stuFeatureVector.dwLength:" + stInfo.stuFeatureVectorList[k].stuFeatureVector.dwLength);    // 人脸小图特征值长度,单位:字节
                            // 人脸抓拍角度、质量数据
                            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;
                    }
                    //目标识别
                    case NetSDKLib.EM_ANALYSE_EVENT_TYPE.EM_ANALYSE_EVENT_FACE_RECOGNITION: {
                        /*NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO stInfo = new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO();
                        ToolKits.GetPointerDataToStruct(info.pstEventInfo, 0, stInfo);
                        System.out.println("objectType: " + new String(stInfo.stuObject.szObjectType, Charset.forName(Utils.getPlatformEncode())));
                        System.out.println("人脸匹配到的候选对象数量:" + stInfo.nCandidateNum + ",人员信息,相似度:" + stInfo.stuCandidates[0].bySimilarity);*/
                        //msg读字节
 
                        msg.getPointer().write(0,info.pstEventInfo.getByteArray(0,msg.size()),0,msg.size());
                        //读取nCandidateNum属性
                        int nCandidateNum=(int)msg.readField("nCandidateNum");
                        //获取stuCandidates结构体偏移量
                        int offset=msg.fieldOffset("stuCandidates");
                        //获取CANDIDATE_INFO结构体大小
                        int size=msg.stuCandidates[0].size();
                        for (int m = 0; m < nCandidateNum; m++) {
                            //按照偏移量写入stuCandidates数组
                            msg.stuCandidates[m].getPointer().write(0,info.pstEventInfo.getByteArray(offset+size*m, size),0,size);
                            //读取相似度
                            byte similarity=(byte)msg.stuCandidates[m].readField("bySimilarity");
                            //读取stPersonInfo结构体对象
                            msg.stuCandidates[m].readField("stPersonInfo");
                            msg.stuCandidates[m].stPersonInfo.read();
                            //人员唯一标示(证件号码,工号,或其他编号)
                            String personId=new String(msg.stuCandidates[m].stPersonInfo.szID,Charset.forName(Utils.getPlatformEncode())).trim();
                            //人员唯一标识符,首次由服务端生成,区别于ID字段
                            String personUId=new String(msg.stuCandidates[m].stPersonInfo.szUID,Charset.forName(Utils.getPlatformEncode())).trim();
                            //
                            System.out.println("id:"+personId+",uid: "+personUId+",similarity: "+similarity);
                        }
                        msg.readField("stuObject");
                        //保存图片
                        //下发的图片
                        String picture = picturePath + "/my-" + System.currentTimeMillis() + ".jpg";
                        ToolKits.savePicture(pBuf, 0, msg.stuObject.stPicInfo.dwFileLenth, picture);
                        //匹配的图片
                        picture = picturePath + "/search-" + System.currentTimeMillis() + ".jpg";
                        ToolKits.savePicture(pBuf, msg.stuObject.stPicInfo.dwFileLenth, dwBufSize, picture);
                        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;
    }
}