package com.netsdk.demo.customize; import com.netsdk.demo.customize.faceReconEx.DefaultFaceFindStateCallback; import com.netsdk.demo.util.CaseMenu; import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.ToolKits; import com.netsdk.lib.enumeration.EM_PERSON_FEATURE_ERRCODE; import com.netsdk.lib.enumeration.ENUMERROR; import com.netsdk.lib.structure.*; import com.netsdk.lib.utils.Initialization; import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import java.awt.*; public class MultiFaceDemo extends Initialization { static NetSDKLib netsdkApi = NetSDKLib.NETSDK_INSTANCE; static NetSDKLib configApi = NetSDKLib.CONFIG_INSTANCE; private static NetSDKLib.LLong findHandle = new NetSDKLib.LLong(0); private static NetSDKLib.LLong attachFaceHandle = new NetSDKLib.LLong(0); private static int nToken; public class MultiFaceDetectState implements NetSDKLib.fMultiFaceDetectState{ @Override public void invoke(NetSDKLib.LLong lAttachHandle, Pointer pstStates, Pointer dwUser) { //todo } } // private final NetSDKLib.fMultiFaceDetectStateEx = new public class IntPoint extends NetSDKLib.SdkStructure { public int value; public IntPoint() { } public IntPoint(int value) { this.value = value; } } /** * 以图搜图 * * @param longHandle CLIENT_StartFindFaceRecognition 接口返回的查询句柄 * @param count 查询的个数 */ public void doFindSearchByPictureEx(NetSDKLib.LLong longHandle, int count) { int doNextCount = 0; // 分页查找数据 NET_IN_DOFIND_FACERECONGNITION_EX stFindIn = new NET_IN_DOFIND_FACERECONGNITION_EX(); stFindIn.lFindHandle = longHandle; stFindIn.nCount = 10; // 当前想查询的记录条数 stFindIn.nBeginNum = 0; // 每次递增 NET_OUT_DOFIND_FACERECONGNITION_EX stFindOut = new NET_OUT_DOFIND_FACERECONGNITION_EX(); stFindOut.nCadidateEx2Num = count; // stFindOut.bUseCandidatesEx = 1; // 是否使用候选对象扩展结构体 NET_CANDIDATE_INFOEX2[] tmp = new NET_CANDIDATE_INFOEX2[count]; for(int i = 0; i < count; i ++) { tmp[i] = new NET_CANDIDATE_INFOEX2(); } stFindOut.nBufferLen = tmp[0].size()*count; stFindOut.pBuffer = new Memory(tmp[0].size() * count); stFindOut.pBuffer.clear(tmp[0].size() * count); for (int i = 0; i < count; i++) { tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].nFilePathLen = 256; tmp[i].stuCandidatesEx.stPersonInfo.szFacePicInfo[0].pszFilePath = new Memory(256); } stFindOut.pstuCandidatesEx2 = new Memory(tmp[0].size() * count); // Pointer初始化 stFindOut.pstuCandidatesEx2.clear(tmp[0].size() * count); ToolKits.SetStructArrToPointerData(tmp, stFindOut.pstuCandidatesEx2); // 将数组内存拷贝给 Pointer do { stFindIn.write(); stFindOut.write(); if (netsdkApi.CLIENT_DoFindFaceRecognitionEx(stFindIn.getPointer(), stFindOut.getPointer(), 1000)) { System.out.println( "CLIENT_DoFindFaceRecognitionEx Succeed"); stFindOut.read(); ToolKits.GetPointerDataToStructArr(stFindOut.pstuCandidatesEx2, tmp); System.out.printf("Record Number [%d]\n", stFindOut.nRetCadidateEx2Num); if (stFindOut.nRetCadidateEx2Num == 0) { System.out.println("没有查询到相关数据"); break; } for (int i = 0; i < stFindOut.nRetCadidateEx2Num; i++) { int index = i + doNextCount * count; // 查询的总个数 - 1, 从0开始 // 建模状态 /** 0:未知 1:建模失败,可能是图片不符合要求,需要换图片 2:有可用的特征值 3:正在计算特征值 4:已建模,但算法升级导致数据不可用,需要重新建模 */ int status = tmp[i].stuCandidatesEx.stPersonInfo.emFeatureState; System.out.println("建模状态: " + status); // 如果建模失败,打印建模失败原因 if (status == 1) { System.out.println( "失败原因: " + EM_PERSON_FEATURE_ERRCODE.getErrorMessage( tmp[i].stuCandidatesEx.stPersonInfo.emFeatureErrCode)); } } } else { System.out.println( "CLIENT_DoFindFaceRecognitionEx Failed, Error:" + ENUMERROR.getErrorMessage()); break; } if (stFindOut.nRetCadidateEx2Num < stFindIn.nCount) { System.out.println("没有更多数据,结束查询"); break; } else { stFindIn.nBeginNum += count; doNextCount++; } } while (true); netsdkApi.CLIENT_StopFindFaceRecognition(longHandle); } /** * 以图搜图 * * @param startTime 开始时间 * @param endTime 结束时间 * @param chn 通道号 * @param similary 相似度 * @param memory 图片缓存 * @param nPicLen 图片大小 */ public void searchByPictureMultiVer(String startTime, String endTime, int chn, String similary, Memory memory, int nPicLen) { String[] startTimeStr = startTime.split("-"); String[] endTimeStr = endTime.split("-"); NET_IN_STARTMULTIFIND_FACERECONGNITION_EX stInStartFind = new NET_IN_STARTMULTIFIND_FACERECONGNITION_EX(); // 通道号 stInStartFind.nChannelCount = 5; IntPoint[] intPoints = new IntPoint[5]; for (int i = 0; i < 5; i++) { intPoints[i] = new IntPoint(i); } stInStartFind.pChannelID = new Memory(intPoints[0].size() * stInStartFind.nChannelCount); stInStartFind.pChannelID.clear(intPoints[0].size() * stInStartFind.nChannelCount); ToolKits.SetStructArrToPointerData(intPoints, stInStartFind.pChannelID); stInStartFind.bPersonEx2Enable = 1; // 人员信息查询条件是否有效, 并使用扩展结构体 stInStartFind.emObjectType = NetSDKLib.EM_OBJECT_TYPE.EM_OBJECT_TYPE_FACE; // 图片信息 if (memory != null && nPicLen > 0) { System.out.println("detect image"); String picPath = "D:\\tool\\work\\4.jpg"; byte[] picBuf = ToolKits.readPictureToByteArray(picPath); // ToolKits.savePicture(picBuf, "D:\\tool\\work\\wcnm.jpg"); stInStartFind.pBuffer = new Memory(picBuf.length); stInStartFind.pBuffer.write(0,picBuf,0,picBuf.length); stInStartFind.nBufferLen = nPicLen; stInStartFind.bPersonEx2Enable = 1; // 人员信息查询条件是否有效, 并使用扩展结构体 stInStartFind.stPersonInfoEx2.nFacePicNumEx = 1; stInStartFind.stPersonInfoEx2.stuFacePicInfoEx[0].dwOffSet = 0; stInStartFind.stPersonInfoEx2.stuFacePicInfoEx[0].dwFileLenth = nPicLen; // stInStartFind.stPersonInfoEx2.bPersonExEnable = 1; // stInStartFind.stPersonInfoEx2.nFacePicNumEx = 1; // stInStartFind.stPersonInfoEx2.stPersonInfoEx. // stInStartFind.stPersonInfoEx2.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0; // stInStartFind.stPersonInfoEx2.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = nPicLen; } // 相似度 if (!similary.equals("")) { stInStartFind.stMatchOptions.nSimilarity = Integer.parseInt(similary); stInStartFind.stMatchOptions.nMaxCandidate = 5; } stInStartFind.stFilterInfo.nGroupIdNum = 0; stInStartFind.stFilterInfo.nRangeNum = 1; stInStartFind.stFilterInfo.szRange[0] = NetSDKLib.EM_FACE_DB_TYPE.NET_FACE_DB_TYPE_HISTORY; stInStartFind.stFilterInfo.stStartTime.dwYear = Integer.parseInt(startTimeStr[0]); stInStartFind.stFilterInfo.stStartTime.dwMonth = Integer.parseInt(startTimeStr[1]); stInStartFind.stFilterInfo.stStartTime.dwDay = Integer.parseInt(startTimeStr[2]); stInStartFind.stFilterInfo.stEndTime.dwYear = Integer.parseInt(endTimeStr[0]); stInStartFind.stFilterInfo.stEndTime.dwMonth = Integer.parseInt(endTimeStr[1]); stInStartFind.stFilterInfo.stEndTime.dwDay = Integer.parseInt(endTimeStr[2]); stInStartFind.stFilterInfo.emFaceType = NetSDKLib.EM_FACERECOGNITION_FACE_TYPE.EM_FACERECOGNITION_FACE_TYPE_ALL; //让设备根据查询条件整理结果集 NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX stOutParam = new NET_OUT_STARTMULTIFIND_FACERECONGNITION_EX(); stInStartFind.write(); stOutParam.write(); if (netsdkApi.CLIENT_StartMultiFindFaceRecognitionEx(loginHandle, stInStartFind.getPointer(), stOutParam.getPointer(), 2000)) { stOutParam.read(); System.out.println("CLIENT_StartMultiFindFaceRecognitionEx success, count = " + stOutParam.nTotalCount); findHandle = stOutParam.lFindHandle; if(stOutParam.nTotalCount > 0){ doFindSearchByPictureEx(findHandle, 10); } if (stOutParam.nTotalCount == -1) { // -1表示总条数未生成,要推迟获取, 使用CLIENT_AttachFaceFindState接口状态 nToken = stOutParam.nToken; // 入参 NET_IN_MULTIFACE_DETECT_STATE pstInParam = new NET_IN_MULTIFACE_DETECT_STATE(); pstInParam.nTokensNum = 1; pstInParam.nTokens[0] = nToken; // 查询令牌 pstInParam.cbMultiFaceDetectState = new MultiFaceDetectState(); // 出参 NET_OUT_MULTIFACE_DETECT_STATE pstOutParam = new NET_OUT_MULTIFACE_DETECT_STATE(); pstInParam.write(); attachFaceHandle = netsdkApi.CLIENT_AttachDetectMultiFaceState(loginHandle, pstInParam.getPointer(), pstOutParam.getPointer(), 4000); pstInParam.read(); if (attachFaceHandle.longValue() != 0) { System.out.println("AttachFaceFindState Succeed!"); } else { System.out.println( "AttachFaceFindState Failed, Error:" + ToolKits.getErrorCode()); return; } NET_IN_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO stIn = new NET_IN_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO(); stIn.nBigPicNum = 1; String picPath = "D:\\tool\\work\\4.jpg"; byte[] picBuf = ToolKits.readPictureToByteArray(picPath); stIn.stuBigPicInfo[0].dwFileLenth = picBuf.length; stIn.nBufferLen = picBuf.length; stIn.pBuffer = new Memory(picBuf.length); stIn.pBuffer.write(0, picBuf, 0, picBuf.length); stIn.nToken = nToken; NET_OUT_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO stOut = new NET_OUT_FACE_RECOGNITION_DETECT_MULTI_FACE_INFO(); stIn.write(); stOut.write(); boolean bRet = netsdkApi.CLIENT_FaceRecognitionDetectMultiFace(loginHandle, stIn.getPointer(), stOut.getPointer(), 3000); if (bRet) { System.out.println("CLIENT_FaceRecognitionDetectMultiFace success"); } else { System.out.println("CLIENT_FaceRecognitionDetectMultiFace failed"); System.out.println("error = " + ToolKits.getErrorCode()); } } } else { System.out.println( "CLIENT_StartMultiFindFaceRecognitionEx Failed, Error:" + ToolKits.getErrorCode()); } } public void tryMethod(){ String picPath = "D:\\tool\\work\\4.jpg"; byte[] picBuf = ToolKits.readPictureToByteArray(picPath); Memory memory = new Memory(picBuf.length); memory.write(0,picBuf,0,picBuf.length); searchByPictureMultiVer("2022-11-20","2022-11-27",0,"10",memory,picBuf.length); // doFindSearchByPictureEx(loginHandle, 10); } public void RunTest() { System.out.println("Run Test"); CaseMenu menu = new CaseMenu(); menu.addItem((new CaseMenu.Item(this, "tryMethod", "tryMethod"))); menu.run(); } public static void main(String[] args) { MultiFaceDemo multiFaceDemo = new MultiFaceDemo(); InitTest("172.25.239.136", 37777, "admin", "Admin123"); multiFaceDemo.RunTest(); LoginOut(); } }