houzhongjian
2024-10-30 a28ca3f36d0ace05966a8c0fac1e4b5fe921f882
提交 | 用户 | 时间
ce910c 1 package com.netsdk.demo.module;
H 2
3 import java.io.UnsupportedEncodingException;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import com.netsdk.lib.NativeString;
9 import com.netsdk.lib.NetSDKLib;
10 import com.netsdk.lib.ToolKits;
11 import com.netsdk.lib.NetSDKLib.*;
12
13 import com.sun.jna.Memory;
14 import com.sun.jna.Pointer;
15
16 /**
17  * IVSS 和 IPC-FR 人脸功能接口实现, IPC-FD只支持目标检测事件
18  */
19
20 public class TargetRecognitionModule {
21     // 查找句柄
22     private static LLong m_FindHandle = null;   
23     
24     // 查询密令
25     public static int nToken = 0;
26     
27     ////////////////////////////////  目标识别 和 目标检测 事件  /////////////////////////////////////////////
28     /**
29      * 目标识别事件和目标检测事件订阅
30      * @param channel 通道号
31      * @param callback 回调函数
32      * @return true:成功    false:失败
33      */
34     public static LLong realLoadPicture(int channel, fAnalyzerDataCallBack callback) {
35         int bNeedPicture = 1; // 是否需要图片
36     
37         LLong m_hAttachHandle =  LoginModule.netsdk.CLIENT_RealLoadPictureEx(LoginModule.m_hLoginHandle, channel, 
38                                     NetSDKLib.EVENT_IVS_ALL, bNeedPicture, callback, null, null);
39         if(m_hAttachHandle.longValue() == 0) {
40             System.err.println("CLIENT_RealLoadPictureEx Failed, Error:" + ToolKits.getErrorCodePrint());
41         } else {
42             System.out.println("通道[" + channel + "]订阅成功!");
43         }
44
45         return m_hAttachHandle;
46     }
47     
48     /**
49      * 停止订阅
50      * @param m_hAttachHandle 智能订阅句柄
51      */
52     public static void stopRealLoadPicture(LLong m_hAttachHandle) {
53         if(m_hAttachHandle.longValue() != 0) {
54             LoginModule.netsdk.CLIENT_StopLoadPic(m_hAttachHandle);
55             m_hAttachHandle.setValue(0);
56         }
57     }
58     
59     
60     ///////////////////////////////////////  人脸库的增、删、改、查  ////////////////////////////////
61     
62     /**
63      * 查询人脸库
64      * @param groupId 需要查找的人脸库ID; 为空表示查找所有的人脸库
65      */
66     public static NET_FACERECONGNITION_GROUP_INFO[] findGroupInfo(String groupId) {    
67         NET_FACERECONGNITION_GROUP_INFO[] groupInfoRet = null;
68         
69         /*
70          * 入参
71          */
72         NET_IN_FIND_GROUP_INFO stuIn = new NET_IN_FIND_GROUP_INFO();
73         System.arraycopy(groupId.getBytes(), 0, stuIn.szGroupId, 0, groupId.getBytes().length);   
74
75         /*
76          * 出参
77          */
78         int max = 20;
79         NET_FACERECONGNITION_GROUP_INFO[] groupInfo  = new NET_FACERECONGNITION_GROUP_INFO[max];
80         for(int i = 0; i < max; i++) {
81             groupInfo[i] = new NET_FACERECONGNITION_GROUP_INFO();
82         }
83         
84         NET_OUT_FIND_GROUP_INFO stuOut = new NET_OUT_FIND_GROUP_INFO();   
85         stuOut.pGroupInfos = new Memory(groupInfo[0].size() * groupInfo.length);     // Pointer初始化
86         stuOut.pGroupInfos.clear(groupInfo[0].size() * groupInfo.length);
87         stuOut.nMaxGroupNum = groupInfo.length;
88         
89         ToolKits.SetStructArrToPointerData(groupInfo, stuOut.pGroupInfos);  // 将数组内存拷贝给Pointer
90
91         if(LoginModule.netsdk.CLIENT_FindGroupInfo(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000)) {
92             
93             // 将Pointer的值输出到 数组 NET_FACERECONGNITION_GROUP_INFO
94             ToolKits.GetPointerDataToStructArr(stuOut.pGroupInfos, groupInfo);   
95             
96             if(stuOut.nRetGroupNum > 0) {
97                 // 根据设备返回的,将有效的人脸库信息返回
98                 groupInfoRet = new NET_FACERECONGNITION_GROUP_INFO[stuOut.nRetGroupNum];
99                 for(int i = 0; i < stuOut.nRetGroupNum; i++) {
100                     groupInfoRet[i] = groupInfo[i];
101                 }
102             }
103         } else {
104             System.err.println("查询人员信息失败" + ToolKits.getErrorCodePrint());
105             return null;
106         }
107         
108         return groupInfoRet;
109     }
110     
111     /**
112      * 添加人脸库
113      * @param groupName 需要添加的人脸库名称
114      */
115     public static boolean addGroup(String groupName) {
116         NET_ADD_FACERECONGNITION_GROUP_INFO addGroupInfo = new NET_ADD_FACERECONGNITION_GROUP_INFO();
117         
118         // 人脸库名称
119         try {
120             System.arraycopy(groupName.getBytes("GBK"), 0, addGroupInfo.stuGroupInfo.szGroupName, 0, groupName.getBytes("GBK").length);
121         } catch (UnsupportedEncodingException e) {
122             e.printStackTrace();
123         }   
124         
125         /*
126          * 入参
127          */
128         NET_IN_OPERATE_FACERECONGNITION_GROUP stuIn = new NET_IN_OPERATE_FACERECONGNITION_GROUP();
129         stuIn.emOperateType = EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_ADD; // 添加人员组信息
130         stuIn.pOPerateInfo = addGroupInfo.getPointer();        
131         
132         /*
133          * 出参
134          */
135         NET_OUT_OPERATE_FACERECONGNITION_GROUP stuOut = new NET_OUT_OPERATE_FACERECONGNITION_GROUP();
136         
137         addGroupInfo.write();
138         boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionGroup(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000);
139         addGroupInfo.read();
140         
141         if(bRet) {
142             System.out.println("人员组ID : " + new String(stuOut.szGroupId).trim());  // 新增记录的人员组ID,唯一标识一组人员    
143         } 
144
145         return bRet;
146     }
147     
148     /**
149      * 修改人脸库
150      * @param groupName 修改后的人脸库名称
151      * @param groupId 需要修改的人脸库ID
152      */
153     public static boolean modifyGroup(String groupName, String groupId) {
154         NET_MODIFY_FACERECONGNITION_GROUP_INFO modifyGroupInfo = new NET_MODIFY_FACERECONGNITION_GROUP_INFO();
155         
156         // 人脸库名称
157         try {
158             System.arraycopy(groupName.getBytes("GBK"), 0, modifyGroupInfo.stuGroupInfo.szGroupName, 0, groupName.getBytes("GBK").length);
159         } catch (UnsupportedEncodingException e) {
160             e.printStackTrace();
161         }  
162         
163         // 人脸库ID
164         System.arraycopy(groupId.getBytes(), 0, modifyGroupInfo.stuGroupInfo.szGroupId, 0, groupId.getBytes().length);   
165         
166         /*
167          * 入参
168          */
169         NET_IN_OPERATE_FACERECONGNITION_GROUP stuIn = new NET_IN_OPERATE_FACERECONGNITION_GROUP();
170         stuIn.emOperateType = EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_MODIFY; // 修改人员组信息
171         stuIn.pOPerateInfo = modifyGroupInfo.getPointer();        
172         
173         /*
174          * 出参
175          */
176         NET_OUT_OPERATE_FACERECONGNITION_GROUP stuOut = new NET_OUT_OPERATE_FACERECONGNITION_GROUP();
177         
178         modifyGroupInfo.write();
179         boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionGroup(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000);
180         modifyGroupInfo.read();
181         
182         if(bRet) {
183             System.out.println("修改人脸库成功.");
184         }
185         
186         return bRet;
187     }
188     
189     /**
190      * 删除人脸库
191      * @param groupId 需要删除的人脸库ID; 为空表示删除所有的人脸库
192      */
193     public static boolean deleteGroup(String groupId) {
194         NET_DELETE_FACERECONGNITION_GROUP_INFO deleteGroupInfo = new NET_DELETE_FACERECONGNITION_GROUP_INFO();
195         
196         // 人脸库ID
197         System.arraycopy(groupId.getBytes(), 0, deleteGroupInfo.szGroupId, 0, groupId.getBytes().length);   
198         
199         /*
200          * 入参
201          */
202         NET_IN_OPERATE_FACERECONGNITION_GROUP stuIn = new NET_IN_OPERATE_FACERECONGNITION_GROUP();
203         stuIn.emOperateType = EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_DELETE; // 删除人员组信息
204         stuIn.pOPerateInfo = deleteGroupInfo.getPointer();        
205         
206         /*
207          * 出参
208          */
209         NET_OUT_OPERATE_FACERECONGNITION_GROUP stuOut = new NET_OUT_OPERATE_FACERECONGNITION_GROUP();
210         
211         deleteGroupInfo.write();
212         boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionGroup(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000);
213         deleteGroupInfo.read();
214         
215         if(bRet) {
216             System.out.println("删除人脸库成功.");
217         } 
218
219         return bRet;
220     }
221     
222     /////////////////////////////  按人脸库布控、撤控   ///////////////////////////////////////
223     /**
224      * 以人脸库的角度进行布控
225      * @param groupId 人脸库ID
226      * @param hashMap  key:撤控通道     value:相似度 
227      */
228     public static boolean putDisposition(String groupId, HashMap<Integer, Integer> hashMap) {
229         int i = 0;
230         
231         /*
232          * 入参
233          */
234         NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO stuIn = new NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO();
235         // 人脸库ID
236         System.arraycopy(groupId.getBytes(), 0, stuIn.szGroupId, 0, groupId.getBytes().length);
237             
238         for(Map.Entry<Integer, Integer> entry : hashMap.entrySet()) {
239             stuIn.stuDispositionChnInfo[i].nChannelID = entry.getKey() - 1;
240             stuIn.stuDispositionChnInfo[i].nSimilary = entry.getValue();
241         
242             i++;
243         }
244
245         stuIn.nDispositionChnNum = hashMap.size();        // 布控视频通道个数
246         
247         /*
248          * 出参
249          */
250         NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO stuOut = new NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO();
251         
252         boolean bRet = LoginModule.netsdk.CLIENT_FaceRecognitionPutDisposition(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000);
253         if(bRet) {
254             System.out.println("通道布控结果个数:" + stuOut.nReportCnt);
255         }
256         return bRet;
257     }
258     
259     /**
260      * 以人脸库的角度进行撤控
261      * @param groupId 人脸库ID
262      * @param arrayList 撤控通道列表
263      */
264     public static boolean delDisposition(String groupId, ArrayList<Integer> arrayList) {
265         /*
266          * 入参
267          */
268         NET_IN_FACE_RECOGNITION_DEL_DISPOSITION_INFO stuIn = new NET_IN_FACE_RECOGNITION_DEL_DISPOSITION_INFO();
269         
270         // 人脸库ID
271         System.arraycopy(groupId.getBytes(), 0, stuIn.szGroupId, 0, groupId.getBytes().length);
272         
273         // 撤控视频通道列表
274         for(int i = 0; i < arrayList.size(); i++) {
275             stuIn.nDispositionChn[i] = arrayList.get(i) - 1;  
276         }
277         
278         // 撤控视频通道个数
279         stuIn.nDispositionChnNum = arrayList.size();          
280         
281         /*
282          *  出参
283          */
284         NET_OUT_FACE_RECOGNITION_DEL_DISPOSITION_INFO stuOut = new NET_OUT_FACE_RECOGNITION_DEL_DISPOSITION_INFO();
285         
286         boolean bRet = LoginModule.netsdk.CLIENT_FaceRecognitionDelDisposition(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000);
287         if(bRet) {
288             System.out.println("通道撤控结果个数:" + stuOut.nReportCnt);
289         }
290         return bRet;
291     }
292     
293     /////////////////////////////  按通道布控、撤控   ///////////////////////////////////////
294     /**
295      * 获取布控在视频通道的组信息
296      * @param channel 通道号
297      */
298     public static void GetGroupInfoForChannel(int channel) {
299         /*
300          * 入参
301          */
302         NET_IN_GET_GROUPINFO_FOR_CHANNEL stIn = new NET_IN_GET_GROUPINFO_FOR_CHANNEL();
303         
304         // 通道号
305         stIn.nChannelID = channel;
306         
307         /*
308          * 出参
309          */
310         NET_OUT_GET_GROUPINFO_FOR_CHANNEL stOut = new NET_OUT_GET_GROUPINFO_FOR_CHANNEL();
311         
312         if(LoginModule.netsdk.CLIENT_GetGroupInfoForChannel(LoginModule.m_hLoginHandle, stIn, stOut, 4000)) {
313             for(int i = 0; i < stOut.nGroupIdNum; i++) {
314                 System.out.println("人脸库ID:" + new String(stOut.szGroupIdArr[i].szGroupId).trim());
315                 System.out.println("相似度:" + stOut.nSimilary[i] + "\n");
316             }
317         } else {
318             System.err.println("获取布控在视频通道的组信息失败, " + ToolKits.getErrorCodePrint());
319         }    
320     }
321     /**
322      * 布控通道人员组信息
323      * @param channel
324      * @param groupIds 人脸库ID,长度等于相似度
325      * @param similarys 相似度, 长度等于人脸库ID
326      */
327     public static void SetGroupInfoForChannel(int channel, String[] groupIds, int[] similarys) {
328         /*
329          * 入参
330          */
331         NET_IN_SET_GROUPINFO_FOR_CHANNEL stIn = new NET_IN_SET_GROUPINFO_FOR_CHANNEL();
332         
333         // 通道号
334         stIn.nChannelID = channel;
335         
336         // 人脸库ID个数
337         stIn.nGroupIdNum = groupIds.length;
338         
339         // 相似度个数
340         stIn.nSimilaryNum = similarys.length;
341         
342         for(int i = 0; i < groupIds.length; i++) {
343             // 人脸库ID赋值,用数组拷贝
344             System.arraycopy(groupIds[i].getBytes(), 0, stIn.szGroupIdArr[i].szGroupId, 0, groupIds[i].getBytes().length);
345             
346             // 对应的人脸库的相似度
347             stIn.nSimilary[i] = similarys[i];
348         }
349         
350         /*
351          * 出参
352          */
353         NET_OUT_SET_GROUPINFO_FOR_CHANNEL stOut = new NET_OUT_SET_GROUPINFO_FOR_CHANNEL();
354         
355         if(LoginModule.netsdk.CLIENT_SetGroupInfoForChannel(LoginModule.m_hLoginHandle, stIn, stOut, 4000)) {
356             
357         }
358     }
359     
360     /////////////////////////////   人员操作    ////////////////////////////////////////////
361     /**
362      * 按条件查询目标识别结果
363      * @param groupId  人脸库ID
364      * @param isStartBirthday  查询条件是否下发开始生日
365      * @param startTime  生日起始时间
366      * @param isEndBirthday  查询条件是否下发结束生日
367      * @param endTime  生日结束时间
368      * @param personName  姓名
369      * @param sex  性别
370      * @param idType  证件类型
371      * @param idNo  证件号
372      * @return 查询到的所有人员个数  
373      */
374     public static int startFindPerson(String groupId, 
375                                       boolean isStartBirthday, 
376                                       String startTime, 
377                                       boolean isEndBirthday,
378                                       String endTime, 
379                                       String personName, 
380                                       int sex, 
381                                       int idType, 
382                                       String idNo) {    
383         
384         m_FindHandle = null;
385         nToken = 0;
386         
387         int nTotalCount = 0;  
388         
389         /*
390          * 入参, IVVS设备,查询条件只有  stuInStartFind.stPerson 里的参数有效
391          */
392         NET_IN_STARTFIND_FACERECONGNITION stuIn = new NET_IN_STARTFIND_FACERECONGNITION();
393
394         stuIn.bPersonExEnable = 1;      // 人员信息查询条件是否有效, 并使用扩展结构体
395
396         // 人脸库ID
397         System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length); 
398         
399         // 姓名
400         try {
401             System.arraycopy(personName.getBytes("GBK"), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes("GBK").length);
402         } catch (UnsupportedEncodingException e) {
403             e.printStackTrace();
404         } 
405         
406         // 性别
407         stuIn.stPersonInfoEx.bySex = (byte)sex;
408         
409         // 证件类型
410         stuIn.stPersonInfoEx.byIDType = (byte)idType;
411         
412         // 证件号
413         System.arraycopy(idNo.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, idNo.getBytes().length); 
414         
415         stuIn.stFilterInfo.nGroupIdNum = 1;
416         
417         // 人脸库ID
418         System.arraycopy(groupId.getBytes(), 0, stuIn.stFilterInfo.szGroupIdArr[0].szGroupId, 0, groupId.getBytes().length);  
419
420         // 待查询人脸类型
421         stuIn.stFilterInfo.emFaceType = EM_FACERECOGNITION_FACE_TYPE.EM_FACERECOGNITION_FACE_TYPE_ALL;
422         
423         // 开始生日
424         if(isStartBirthday) {
425             String[] startTimeStr = startTime.split("-");
426             
427             stuIn.stFilterInfo.stBirthdayRangeStart.dwYear = Integer.parseInt(startTimeStr[0]);
428             stuIn.stFilterInfo.stBirthdayRangeStart.dwMonth = Integer.parseInt(startTimeStr[1]);
429             stuIn.stFilterInfo.stBirthdayRangeStart.dwDay = Integer.parseInt(startTimeStr[2]);
430         }
431         
432         // 结束生日
433         if(isEndBirthday) {
434             String[] endTimeStr = endTime.split("-");
435             
436             stuIn.stFilterInfo.stBirthdayRangeEnd.dwYear = Integer.parseInt(endTimeStr[0]);
437             stuIn.stFilterInfo.stBirthdayRangeEnd.dwMonth = Integer.parseInt(endTimeStr[1]);
438             stuIn.stFilterInfo.stBirthdayRangeEnd.dwDay = Integer.parseInt(endTimeStr[2]);
439         }
440         
441         stuIn.stFilterInfo.nRangeNum = 1;
442         stuIn.stFilterInfo.szRange[0] = EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_BLACKLIST;
443
444         /*
445          * 出参
446          */
447         NET_OUT_STARTFIND_FACERECONGNITION stuOut = new NET_OUT_STARTFIND_FACERECONGNITION();
448         stuIn.write();
449         stuOut.write();
450         if(LoginModule.netsdk.CLIENT_StartFindFaceRecognition(LoginModule.m_hLoginHandle, stuIn,  stuOut, 4000)) {        
451             m_FindHandle = stuOut.lFindHandle;
452             nTotalCount = stuOut.nTotalCount;
453             nToken = stuOut.nToken;
454         } else {
455             System.out.println("Failed, Error:" + ToolKits.getErrorCodePrint());
456         }
457         
458         return nTotalCount;
459     }
460     
461     /**
462      * 查找目标识别结果
463      * @param beginNum 查询起始序号
464      * @param nCount  当前想查询的记录条数
465      * @return 返回的人员信息数组
466      */
467     public static CANDIDATE_INFOEX[] doFindPerson(int beginNum, int nCount) {
468         /*
469          *入参
470          */
471         NetSDKLib.NET_IN_DOFIND_FACERECONGNITION  stuIn = new NetSDKLib.NET_IN_DOFIND_FACERECONGNITION();
472         stuIn.lFindHandle = m_FindHandle;
473         stuIn.nCount      = nCount;       // 当前想查询的记录条数
474         stuIn.nBeginNum   = beginNum;     // 查询起始序号
475         
476         /*
477          * 出参
478          */
479         NetSDKLib.NET_OUT_DOFIND_FACERECONGNITION stuOut = new NetSDKLib.NET_OUT_DOFIND_FACERECONGNITION();    
480         stuOut.bUseCandidatesEx = 1;                // 是否使用候选对象扩展结构体
481         
482         // 必须申请内存,每次查询几个,必须至少申请几个,最大申请20个
483         for(int i = 0; i < nCount; i++) {
484             stuOut.stuCandidatesEx[i].stPersonInfo.szFacePicInfo[0].nFilePathLen = 256;
485             stuOut.stuCandidatesEx[i].stPersonInfo.szFacePicInfo[0].pszFilePath = new Memory(256);
486         }
487         
488         stuIn.write();
489         stuOut.write();
490         if(LoginModule.netsdk.CLIENT_DoFindFaceRecognition(stuIn, stuOut, 4000)) {
491             stuIn.read();
492             stuOut.read();
493             
494             if(stuOut.nCadidateExNum == 0) {
495                 return null;
496             }
497             
498             // 查询到的数据
499             CANDIDATE_INFOEX[]    stuCandidatesEx = new CANDIDATE_INFOEX[stuOut.nCadidateExNum];
500             for(int i = 0; i < stuOut.nCadidateExNum; i++) {
501                 stuCandidatesEx[i] = new CANDIDATE_INFOEX();
502                 stuCandidatesEx[i] = stuOut.stuCandidatesEx[i];
503             }   
504             
505             return stuCandidatesEx;
506         } else {
507             System.out.println("Failed, Error:" + ToolKits.getErrorCodePrint());
508         }
509     
510         return null;
511     }
512     
513     /**
514      * 结束查询
515      */
516     public static boolean doFindPerson() {
517         boolean bRet = false;
518         if(m_FindHandle.longValue() != 0) {
519             bRet = LoginModule.netsdk.CLIENT_StopFindFaceRecognition(m_FindHandle);
520         }
521         return bRet;
522     }
523     
524     /**
525      * 添加人员
526      * @param groupId  人脸库ID
527      * @param memory  图片数据
528      * @param personName 姓名
529      * @param sex  性别
530      * @param isBirthday 是否下发生日
531      * @param birthday  生日
532      * @param byIdType  证件类型
533      * @param idNo  证件号
534      * @return
535      */
536     public static boolean addPerson(String groupId, 
537                                     Memory memory, 
538                                     String personName, 
539                                     int sex, 
540                                     boolean isBirthday, 
541                                     String birthday,  
542                                     int byIdType, 
543                                     String idNo) {
544         /*
545          *  入参
546          */
547         NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
548         stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_ADD;
549         
550         ///////// 使用人员扩展信息 //////////
551         stuIn.bUsePersonInfoEx = 1;   
552         
553         // 人脸库ID
554         System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
555         
556         // 生日设置
557         if(isBirthday) {
558             String[] birthdays = birthday.split("-");
559                     
560             stuIn.stPersonInfoEx.wYear = (short)Integer.parseInt(birthdays[0]);
561             stuIn.stPersonInfoEx.byMonth = (byte)Integer.parseInt(birthdays[1]);
562             stuIn.stPersonInfoEx.byDay = (byte)Integer.parseInt(birthdays[2]);
563         }
564         
565         // 性别,1-男,2-女,作为查询条件时,此参数填0,则表示此参数无效    
566         stuIn.stPersonInfoEx.bySex = (byte)sex;    
567         
568         // 人员名字    
569         try {
570             System.arraycopy(personName.getBytes("GBK"), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes("GBK").length);
571         } catch (UnsupportedEncodingException e) {
572             e.printStackTrace();
573         } 
574         
575         // 证件类型
576         stuIn.stPersonInfoEx.byIDType = (byte)byIdType;  
577         
578         // 证件号
579         System.arraycopy(idNo.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, idNo.getBytes().length);                       
580         
581         // 图片张数、大小、缓存设置
582         if(memory != null) {
583             stuIn.stPersonInfoEx.wFacePicNum = 1; // 图片张数
584             stuIn.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = (int)memory.size();  // 图片大小
585             stuIn.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;
586             
587             stuIn.nBufferLen = (int)memory.size();
588             stuIn.pBuffer = memory;
589         }
590         
591         /*
592          * 出参
593          */
594         NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
595         
596         stuIn.write();
597         boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionDB(LoginModule.m_hLoginHandle, stuIn, stuOut, 3000);
598         stuIn.read();
599         
600         if(bRet) {
601             System.out.println("szUID : " + new String(stuOut.szUID).trim());
602         } else {
603             System.err.println(ToolKits.getErrorCodePrint());
604         }
605         
606         return bRet;
607     }
608     
609     /**
610      * 修改人员信息
611      * @param groupId 人脸库ID
612      * @param uid  人员唯一标识符
613      * @param memory  图片数据
614      * @param personName  姓名
615      * @param sex  性别
616      * @param isBirthday  是否下发生日
617      * @param birthday  生日
618      * @param byIdType  证件类型
619      * @param idNo  证件号
620      * @return true:成功 ,  false:失败
621      */
622     public static boolean modifyPerson(String groupId, 
623                                        String uid,
624                                        Memory memory, 
625                                        String personName, 
626                                        int sex, 
627                                        boolean isBirthday, 
628                                        String birthday,  
629                                        int byIdType, 
630                                        String idNo) {
631         // 入参
632         NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
633         stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_MODIFY;
634         
635         ///////// 使用人员扩展信息  ////////
636         stuIn.bUsePersonInfoEx = 1;    
637         
638         // 人脸库ID
639         System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
640         
641         // 人员唯一标识符
642         System.arraycopy(uid.getBytes(), 0, stuIn.stPersonInfoEx.szUID, 0, uid.getBytes().length); 
643         
644         // 生日设置
645         if(isBirthday) {
646             String[] birthdays = birthday.split("-");
647                     
648             stuIn.stPersonInfoEx.wYear = (short)Integer.parseInt(birthdays[0]);
649             stuIn.stPersonInfoEx.byMonth = (byte)Integer.parseInt(birthdays[1]);
650             stuIn.stPersonInfoEx.byDay = (byte)Integer.parseInt(birthdays[2]);
651         }
652         
653         // 性别,1-男,2-女,作为查询条件时,此参数填0,则表示此参数无效    
654         stuIn.stPersonInfoEx.bySex = (byte)sex;    
655         
656         // 人员名字    
657         try {
658             System.arraycopy(personName.getBytes("GBK"), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes("GBK").length);
659         } catch (UnsupportedEncodingException e) {
660             e.printStackTrace();
661         } 
662         
663         // 证件类型
664         stuIn.stPersonInfoEx.byIDType = (byte)byIdType;  
665         
666         // 证件号
667         System.arraycopy(idNo.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, idNo.getBytes().length);                       
668         
669         // 图片张数、大小、缓存设置
670         if(memory != null) {
671             stuIn.stPersonInfoEx.wFacePicNum = 1; // 图片张数
672             stuIn.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = (int)memory.size();  // 图片大小
673             stuIn.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;
674             
675             stuIn.nBufferLen = (int)memory.size();
676             stuIn.pBuffer = memory;
677         }                      
678
679         // 出参
680         NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
681         
682         stuIn.write();
683         if(!LoginModule.netsdk.CLIENT_OperateFaceRecognitionDB(LoginModule.m_hLoginHandle, stuIn, stuOut, 3000)) {
684             System.err.println("修改人员失败" + ToolKits.getErrorCodePrint());
685             return false;
686         }
687         stuIn.read();
688
689         return true;
690     }
691     
692     /**
693      * 删除人员信息
694      * @param groupId 人脸库ID
695      * @param sUID  人员唯一标识符
696      */
697     public static boolean delPerson(String groupId, String sUID) {    
698         /*
699          *  入参
700          */
701         NET_IN_OPERATE_FACERECONGNITIONDB stuIn  = new NET_IN_OPERATE_FACERECONGNITIONDB();
702         stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_DELETE;
703     
704         //////// 使用人员扩展信息  //////////
705         stuIn.bUsePersonInfoEx = 1;    
706         
707         // GroupID 赋值
708         System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
709
710         // UID赋值
711         System.arraycopy(sUID.getBytes(), 0, stuIn.stPersonInfoEx.szUID, 0, sUID.getBytes().length);
712
713         /*
714          *  出参
715          */
716         NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB() ;    
717
718         boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionDB(LoginModule.m_hLoginHandle, stuIn, stuOut, 3000);
719         if(!bRet) {
720             System.err.println(LoginModule.netsdk.CLIENT_GetLastError());
721         }
722         
723         return bRet;
724     }
725     
726     /**
727      * 下载图片, 用于修改人员信息
728      * @param szFileName 需要下载的文件名
729      * @param pszFileDst 存放文件路径
730      */
731     public static boolean downloadPersonPic(String szFileName, String pszFileDst) {
732         /*
733          * 入参
734          */
735         NET_IN_DOWNLOAD_REMOTE_FILE stuIn = new NET_IN_DOWNLOAD_REMOTE_FILE();
736         // 需要下载的文件名
737         stuIn.pszFileName = new NativeString(szFileName).getPointer();
738         
739         // 存放文件路径
740         stuIn.pszFileDst = new NativeString(pszFileDst).getPointer();
741
742         /*
743          * 出参
744          */
745         NET_OUT_DOWNLOAD_REMOTE_FILE stuOut = new NET_OUT_DOWNLOAD_REMOTE_FILE();
746         
747         if(!LoginModule.netsdk.CLIENT_DownloadRemoteFile(LoginModule.m_hLoginHandle, stuIn, stuOut, 5000)) {
748             System.err.println("下载图片失败!" + ToolKits.getErrorCodePrint());
749             return false;
750         }
751         return true;
752     }
753
754     /**
755      * 显示/关闭规则库
756      * @param RealPlayHandle  实时预览
757      * @param bTrue    1-打开, 0-关闭
758      * @return
759      */
760     public static void renderPrivateData(LLong m_hRealPlayHandle, int bTrue) {
761         if(m_hRealPlayHandle.longValue() != 0) {
762             LoginModule.netsdk.CLIENT_RenderPrivateData(m_hRealPlayHandle, bTrue);
763         }    
764     }
765     
766     //////////////////////////  查询事件对比记录   /////////////////////////
767     private static LLong lFindHandle = new LLong(0);    // 查找句柄
768     
769     /**
770      * 获取查找句柄
771      * @param nChn  通道号
772      * @param startTime 开始时间
773      * @param endTime  结束时间
774      */
775     public static boolean findFile(int nChn, String startTime, String endTime) {
776         int type = NetSDKLib.EM_FILE_QUERY_TYPE.NET_FILE_QUERY_FACE;
777
778         /**
779          *  查询条件
780          */
781         MEDIAFILE_FACERECOGNITION_PARAM findContion = new MEDIAFILE_FACERECOGNITION_PARAM();
782         
783         // 开始时间
784         String[] starts = startTime.split(" ");
785         
786         findContion.stStartTime.dwYear = Integer.parseInt(starts[0].split("-")[0]);
787         findContion.stStartTime.dwMonth = Integer.parseInt(starts[0].split("-")[1]);
788         findContion.stStartTime.dwDay = Integer.parseInt(starts[0].split("-")[2]);
789         findContion.stStartTime.dwHour = Integer.parseInt(starts[1].split(":")[0]);
790         findContion.stStartTime.dwMinute = Integer.parseInt(starts[1].split(":")[1]);
791         findContion.stStartTime.dwSecond = Integer.parseInt(starts[1].split(":")[2]);
792
793         // 结束时间
794         String[] ends = endTime.split(" ");
795         findContion.stEndTime.dwYear = Integer.parseInt(ends[0].split("-")[0]);
796         findContion.stEndTime.dwMonth = Integer.parseInt(ends[0].split("-")[1]);
797         findContion.stEndTime.dwDay = Integer.parseInt(ends[0].split("-")[2]);
798         findContion.stEndTime.dwHour = Integer.parseInt(ends[1].split(":")[0]);
799         findContion.stEndTime.dwMinute = Integer.parseInt(ends[1].split(":")[1]);
800         findContion.stEndTime.dwSecond = Integer.parseInt(ends[1].split(":")[2]);
801         
802         // 通道号
803         findContion.nChannelId = nChn;
804         
805         /**
806          * 以下注释的查询条件参数,目前设备不支持,后续会逐渐增加
807          */
808 //        // 地点,支持模糊匹配 
809 //        String machineAddress = "";
810 //        System.arraycopy(machineAddress.getBytes(), 0, findContion.szMachineAddress, 0, machineAddress.getBytes().length);
811 //        
812 //        // 待查询报警类型
813 //        findContion.nAlarmType = EM_FACERECOGNITION_ALARM_TYPE.NET_FACERECOGNITION_ALARM_TYPE_ALL;
814         
815 //        // 人员组数 
816 //        findContion.nGroupIdNum = 1;  
817 //        
818 //        // 人员组ID(人脸库ID)
819 //        String groupId = "";
820 //        System.arraycopy(groupId.getBytes(), 0, findContion.szGroupIdArr[0].szGroupId, 0, groupId.getBytes().length);
821 //        
822 //        // 人员信息扩展是否有效
823 //        findContion.abPersonInfoEx = 1;     
824 //        
825 //        // 人员组ID(人脸库ID)
826 //        System.arraycopy(groupId.getBytes(), 0, findContion.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);
827         
828         findContion.write();
829         lFindHandle = LoginModule.netsdk.CLIENT_FindFileEx(LoginModule.m_hLoginHandle, type, findContion.getPointer(), null, 3000);
830         if(lFindHandle.longValue() == 0) {
831             System.err.println("FindFileEx Failed!" + ToolKits.getErrorCodePrint());
832             return false;
833         }
834         findContion.read();
835         
836         return true;
837     }
838     
839     
840     /**
841      * 查询对比数据
842      * @param nFindCount 每次查询的个数
843      */
844     public static MEDIAFILE_FACERECOGNITION_INFO[] findNextFile(int nFindCount) {
845         MEDIAFILE_FACERECOGNITION_INFO[] msg = new MEDIAFILE_FACERECOGNITION_INFO[nFindCount];
846         for (int i = 0; i < msg.length; ++i) {
847             msg[i] = new NetSDKLib.MEDIAFILE_FACERECOGNITION_INFO();
848             msg[i].bUseCandidatesEx = 1;
849         }
850         
851         int MemorySize = msg[0].size() * nFindCount;
852         Pointer pointer = new Memory(MemorySize);
853         pointer.clear(MemorySize);
854         
855         ToolKits.SetStructArrToPointerData(msg, pointer);
856
857         int nRetCount = LoginModule.netsdk.CLIENT_FindNextFileEx(lFindHandle, nFindCount, pointer, MemorySize, null, 3000);
858         ToolKits.GetPointerDataToStructArr(pointer, msg);
859         
860         if (nRetCount <= 0) {
861             System.err.println("FindNextFileEx failed!" + ToolKits.getErrorCodePrint());
862             return null;
863         } 
864
865         MEDIAFILE_FACERECOGNITION_INFO[] retInfo = new MEDIAFILE_FACERECOGNITION_INFO[nRetCount];
866         for (int i = 0; i < retInfo.length; ++i) {
867             retInfo[i] = new NetSDKLib.MEDIAFILE_FACERECOGNITION_INFO();
868             retInfo[i] = msg[i];
869         }
870         
871         return retInfo;    
872     }
873     
874     public static void findCloseFile() {
875         if(lFindHandle.longValue() != 0) {
876             LoginModule.netsdk.CLIENT_FindCloseEx(lFindHandle);    
877             lFindHandle.setValue(0);
878         }
879     }
880 }