大华sdk(java)上传人脸图片到人脸库,订阅人脸识别对比
生活随笔
收集整理的這篇文章主要介紹了
大华sdk(java)上传人脸图片到人脸库,订阅人脸识别对比
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上傳人臉圖片到人臉庫
controller:
@RestController @RequestMapping("/facePicture") public class FacePictureHandleController {@Autowiredprivate FacePictureHandleService facePictureHandleService;@RequestMapping(value = "/handle/uploadFile")public String padUploadFile(@RequestParam("file") MultipartFile file,HttpServletRequest request) {try {FacePicture facePicture=new FacePicture();HttpSession session = request.getSession(true);Map<String, String> userInfo = (Map<String, String>) session.getAttribute(SessionConstants.SESSION_KEY_USER_INFO);facePicture.setCardId(userInfo.get("loginUser"));File f=null;String fileName = file.getOriginalFilename();try {//獲取文件字節數組byte [] bytes = file.getBytes();File pfile = new File("/fileupload/");//判斷文件夾是否存在if(!pfile.exists()){//不存在時,創建文件夾pfile.mkdirs();}//創建文件f = new File(pfile, fileName);//寫入指定文件夾OutputStream out = new FileOutputStream(f);out.write(bytes);} catch (IOException e) {e.printStackTrace();return "上傳失敗";}Integer facePictureRes = facePictureHandleService.saveFacePictureHandle(facePicture,f.getPath());if(facePictureRes==0){return "上傳失敗";}return "上傳成功";} catch (Exception e) {log.error("上傳文件異常", e);}return "上傳失敗";} }service:
@Service public class FacePictureHandleService {/***配置文件*/@Value("${groupId}")private String groupId;@Value("${uploadWaitTime}")private int uploadWaitTime;@Value("${groupName}")private String groupName;@Autowiredprivate FacePictureHandleDao facePictureHandleDao;@Autowiredprivate FaceDetectService faceDetectService;@Autowiredprivate UserInfoDAO userInfoDao;/*** 保存人臉圖片到人臉庫* @return*/public Integer saveFacePictureHandle(FacePicture facePicture, String filePath) throws UnsupportedEncodingException {Memory fileMemory=new Memory(2000000);try {ToolKits.ReadAllFileToMemory(filePath,fileMemory);} catch (IOException e) {e.printStackTrace();}List<UserInfo> byUserNameIn = userInfoDao.findByUserNameIn(Collections.singletonList(facePicture.getCardId()));facePicture.setName(byUserNameIn.get(0).getName());facePicture.setFaceDatabaseName(groupName);String gender = byUserNameIn.get(0).getGender();int sex=0;if("F".equals(gender)){sex=2;}else if("M".equals(gender)){sex=1;}Long fId= facePictureHandleDao.queryFaceDatabaseId(facePicture.getCardId());if(fId==null){ //未上傳圖片//上傳圖片到人臉庫boolean updalodRes = addPerson(groupId, fileMemory, facePicture.getName(), sex, false, "", 0, "",facePicture);if(updalodRes){facePictureHandleDao.save(facePicture);return 1;}}else{ //已上傳過圖片String uId = facePictureHandleDao.queryFaceDatabaseUid(fId);//修改人臉庫圖片boolean updalodRes = modifyPerson(groupId, uId,fileMemory, facePicture.getName(), sex, false, "", 0, "");if(updalodRes){facePicture.setId(fId);int i = facePictureHandleDao.updatePictureData(fId);return i;}}File file=new File(filePath);if(file!=null){file.deleteOnExit();}return 0;}public File transferToFile(MultipartFile multipartFile) {File file = null;try {String originalFilename = multipartFile.getOriginalFilename();String[] filename = originalFilename.split("\\.");file=File.createTempFile(filename[0]+"temp", filename[1]);multipartFile.transferTo(file);} catch (IOException e) {e.printStackTrace();}return file;}/*** 添加人員* @param groupId 人臉庫ID* @param memory 圖片數據* @param personName 姓名* @param sex 性別* @param isBirthday 是否下發生日* @param birthday 生日* @param byIdType 證件類型* @param idNo 證件號* @return*/public boolean addPerson(String groupId,Memory memory,String personName,int sex,boolean isBirthday,String birthday,int byIdType,String idNo,FacePicture facePicture) throws UnsupportedEncodingException {/** 入參*/NetSDKLib.NET_IN_OPERATE_FACERECONGNITIONDB stuIn = new NetSDKLib.NET_IN_OPERATE_FACERECONGNITIONDB();stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_ADD;/ 使用人員擴展信息 //stuIn.bUsePersonInfoEx = 1;// 人臉庫IDSystem.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);// 生日設置if(isBirthday) {String[] birthdays = birthday.split("-");stuIn.stPersonInfoEx.wYear = (short)Integer.parseInt(birthdays[0]);stuIn.stPersonInfoEx.byMonth = (byte)Integer.parseInt(birthdays[1]);stuIn.stPersonInfoEx.byDay = (byte)Integer.parseInt(birthdays[2]);}// 性別,1-男,2-女,作為查詢條件時,此參數填0,則表示此參數無效stuIn.stPersonInfoEx.bySex = (byte)sex;// 人員名字try {System.arraycopy(personName.getBytes("GBK"), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes("GBK").length);} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 證件類型stuIn.stPersonInfoEx.byIDType = (byte)byIdType;// 證件號System.arraycopy(idNo.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, idNo.getBytes().length);// 圖片張數、大小、緩存設置if(memory != null) {stuIn.stPersonInfoEx.wFacePicNum = 1; // 圖片張數stuIn.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = (int)memory.size(); // 圖片大小stuIn.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;stuIn.nBufferLen = (int)memory.size();stuIn.pBuffer = memory;}/** 出參*/NetSDKLib.NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NetSDKLib.NET_OUT_OPERATE_FACERECONGNITIONDB() ;stuIn.write();boolean bRet = faceDetectService.getNetsdk().CLIENT_OperateFaceRecognitionDB(faceDetectService.getLoginHandle(), stuIn, stuOut, uploadWaitTime);stuIn.read();if(bRet) {System.out.println("szUID : " + new String(stuOut.szUID).trim());} else {System.err.println(faceDetectService.netsdk.CLIENT_GetLastError());}facePicture.setFaceDatabaseUid(new String(stuOut.szUID, "GBK").trim());return bRet;}/*** 修改人員信息* @param groupId 人臉庫ID* @param uid 人員唯一標識符* @param memory 圖片數據* @param personName 姓名* @param sex 性別* @param isBirthday 是否下發生日* @param birthday 生日* @param byIdType 證件類型* @param idNo 證件號* @return true:成功 , false:失敗*/public boolean modifyPerson(String groupId,String uid,Memory memory,String personName,int sex,boolean isBirthday,String birthday,int byIdType,String idNo) {// 入參NetSDKLib.NET_IN_OPERATE_FACERECONGNITIONDB stuIn = new NetSDKLib.NET_IN_OPERATE_FACERECONGNITIONDB();stuIn.emOperateType = NetSDKLib.EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_MODIFY;/ 使用人員擴展信息 stuIn.bUsePersonInfoEx = 1;// 人臉庫IDSystem.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length);// 人員唯一標識符System.arraycopy(uid.getBytes(), 0, stuIn.stPersonInfoEx.szUID, 0, uid.getBytes().length);// 生日設置if(isBirthday) {String[] birthdays = birthday.split("-");stuIn.stPersonInfoEx.wYear = (short)Integer.parseInt(birthdays[0]);stuIn.stPersonInfoEx.byMonth = (byte)Integer.parseInt(birthdays[1]);stuIn.stPersonInfoEx.byDay = (byte)Integer.parseInt(birthdays[2]);}// 性別,1-男,2-女,作為查詢條件時,此參數填0,則表示此參數無效stuIn.stPersonInfoEx.bySex = (byte)sex;// 人員名字try {System.arraycopy(personName.getBytes("GBK"), 0, stuIn.stPersonInfoEx.szPersonName, 0, personName.getBytes("GBK").length);} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 證件類型stuIn.stPersonInfoEx.byIDType = (byte)byIdType;// 證件號System.arraycopy(idNo.getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, idNo.getBytes().length);// 圖片張數、大小、緩存設置if(memory != null) {stuIn.stPersonInfoEx.wFacePicNum = 1; // 圖片張數stuIn.stPersonInfoEx.szFacePicInfo[0].dwFileLenth = (int)memory.size(); // 圖片大小stuIn.stPersonInfoEx.szFacePicInfo[0].dwOffSet = 0;stuIn.nBufferLen = (int)memory.size();stuIn.pBuffer = memory;}// 出參NetSDKLib.NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NetSDKLib.NET_OUT_OPERATE_FACERECONGNITIONDB() ;stuIn.write();boolean b = faceDetectService.getNetsdk().CLIENT_OperateFaceRecognitionDB(faceDetectService.getLoginHandle(), stuIn, stuOut, uploadWaitTime);if(!b) {System.err.println("修改人員失敗" + ToolKits.getErrorCodePrint());return false;}stuIn.read();return true;}/*** 查詢人臉庫* @param groupId 需要查找的人臉庫ID; 為空表示查找所有的人臉庫*/public NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[] findGroupInfo(String groupId) {NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[] groupInfoRet = null;/** 入參*/NetSDKLib.NET_IN_FIND_GROUP_INFO stuIn = new NetSDKLib.NET_IN_FIND_GROUP_INFO();System.arraycopy(groupId.getBytes(), 0, stuIn.szGroupId, 0, groupId.getBytes().length);/** 出參*/int max = 20;NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[] groupInfo = new NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[max];for(int i = 0; i < max; i++) {groupInfo[i] = new NetSDKLib.NET_FACERECONGNITION_GROUP_INFO();}NetSDKLib.NET_OUT_FIND_GROUP_INFO stuOut = new NetSDKLib.NET_OUT_FIND_GROUP_INFO();stuOut.pGroupInfos = new Memory(groupInfo[0].size() * groupInfo.length); // Pointer初始化stuOut.pGroupInfos.clear(groupInfo[0].size() * groupInfo.length);stuOut.nMaxGroupNum = groupInfo.length;ToolKits.SetStructArrToPointerData(groupInfo, stuOut.pGroupInfos); // 將數組內存拷貝給Pointerif(faceDetectService.netsdk.CLIENT_FindGroupInfo(faceDetectService.getLoginHandle(), stuIn, stuOut, 4000)) {// 將Pointer的值輸出到 數組 NET_FACERECONGNITION_GROUP_INFOToolKits.GetPointerDataToStructArr(stuOut.pGroupInfos, groupInfo);if(stuOut.nRetGroupNum > 0) {// 根據設備返回的,將有效的人臉庫信息返回groupInfoRet = new NetSDKLib.NET_FACERECONGNITION_GROUP_INFO[stuOut.nRetGroupNum];for(int i = 0; i < stuOut.nRetGroupNum; i++) {groupInfoRet[i] = groupInfo[i];}}} else {System.err.println("查詢人員信息失敗" + ToolKits.getErrorCodePrint());return null;}return groupInfoRet;} }Dao(JPA):
@Repository public interface FaceDatabasePictureDao extends CrudRepository<FacePicture, String> {//查詢是否已上傳過圖片@Query("select id from FacePicture where cardId=?")public Long queryFaceDatabaseId(String cardId);//查詢是否已上傳過圖片@Query("select faceDatabaseUid from FacePicture where id=?")public String queryFaceDatabaseUid(Long id);@Modifying@Query(value="update FacePicture set updatedDate=sysdate() where id=?")@Transactionalpublic int updatePictureData(Long id); }人臉識別對比
由于項目啟動時就要啟動,使用@PostConstruct注解。
service:
@Service public class FaceDetectService{@Value("${mstrIp}")private String m_strIp;@Value("${mnPort}")private int m_nPort;@Value("${mstrUser}")private String m_strUser;@Value("${mstrPassword}")private String m_strPassword;private static boolean bInit = false;private static boolean bLogopen = false;@Autowiredprivate FaceDetectDao faceDetectDaoA;private static FaceDetectDao faceDetectDao;@PostConstructpublic void init() {faceDetectDao=this.faceDetectDaoA;//初始化InitTest(disConnect, haveReConnect);//登錄Login();Run();}public NetSDKLib getNetsdk(){return netsdk;}public NetSDKLib.LLong getLoginHandle(){return loginHandle;}public static final NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;// 登陸句柄public static NetSDKLib.LLong loginHandle = new NetSDKLib.LLong(0);// 訂閱句柄private static NetSDKLib.LLong r_loginHandle = new NetSDKLib.LLong(0);// 設備信息擴展private NetSDKLib.NET_DEVICEINFO_Ex deviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();// 全景圖private static BufferedImage globalBufferedImage = null;// 人臉圖private static BufferedImage personBufferedImage = null;// 候選人圖private static BufferedImage candidateBufferedImage = null;// 用于人臉檢測@Value("${face.groupId}")private int groupId;@Value("${face.channel}")private int channel;@Value("${face.bNeedPicture}")private int bNeedPicture;private static int index = -1;// 設備斷線通知回調private static DisConnect disConnect = new DisConnect();// 網絡連接恢復private static HaveReConnect haveReConnect = new HaveReConnect();public void Run() {//訂閱RealLoadPicture(channel, bNeedPicture, AnalyzerDataCB.getInstance());}// 設備斷線回調: 通過 CLIENT_Init 設置該回調函數,當設備出現斷線時,SDK會調用該函數private static class DisConnect implements NetSDKLib.fDisConnect {public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);}}// 網絡連接恢復,設備重連成功回調// 通過 CLIENT_SetAutoReconnect 設置該回調函數,當已斷線的設備重連成功時,SDK會調用該函數private static class HaveReConnect implements NetSDKLib.fHaveReConnect {public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);}}/*** 寫成靜態主要是防止被回收*/private static class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack {private AnalyzerDataCB() {}private static class AnalyzerDataCBHolder {private static final FaceDetectService.AnalyzerDataCB instance = new FaceDetectService.AnalyzerDataCB();}public static FaceDetectService.AnalyzerDataCB getInstance() {return FaceDetectService.AnalyzerDataCB.AnalyzerDataCBHolder.instance;}public int invoke(NetSDKLib.LLong lAnalyzerHandle,int dwAlarmType,Pointer pAlarmInfo,Pointer pBuffer,int dwBufSize,Pointer dwUser,int nSequence,Pointer reserved) {if (lAnalyzerHandle.longValue() == 0 || pAlarmInfo == null) {return -1;}switch (dwAlarmType) {case NetSDKLib.EVENT_IVS_FACERECOGNITION: // /< 人臉識別事件{// DEV_EVENT_FACERECOGNITION_INFO 結構體比較大,new對象會比較耗時, ToolKits.GetPointerData內容拷貝是不耗時的。// 如果多臺設備或者事件處理比較頻繁,可以考慮將 static DEV_EVENT_FACERECOGNITION_INFO msg = new// DEV_EVENT_FACERECOGNITION_INFO(); 改為全局。// 寫成全局,是因為每次new花費時間較多, 如果改為全局,此case下的處理需要加鎖// 加鎖,是因為共用一個對象,防止數據出錯// 耗時800ms左右NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO msg = new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO();// 耗時20ms左右ToolKits.GetPointerData(pAlarmInfo, msg);//保存人臉對比信息try {saveFaceDetectInfo(msg);} catch (IOException e) {e.printStackTrace();}// 釋放內存msg = null;System.gc();break;}default:break;}return 0;}/*** 保存人臉對比信息*/public void saveFaceDetectInfo(NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO faceMsg) throws IOException {//人臉信息if (faceMsg.stuFaceData != null) {Res res=new Res();FaceDetect faceDetect =new FaceDetect();faceDetect.setName(new String(faceMsg.stuCandidatesEx[0].stPersonInfo.szPersonName, "GBK").trim());faceDetect.setSex(res.getSex(faceMsg.stuFaceData.emSex));faceDetect.setDetectTime(Timestamp.valueOf(faceMsg.UTC.toString()));faceDetect.setFaceDatabaseName(new String(faceMsg.stuCandidatesEx[0].stPersonInfo.szGroupName, "GBK").trim());faceDetect.setSimilarity(String.valueOf(faceMsg.stuCandidatesEx[0].bySimilarity));faceDetect.setFaceDatabaseUid(new String(faceMsg.stuCandidatesEx[0].stPersonInfo.szUID).trim());faceDetectDao.save(faceDetect);}};}// 訂閱public void RealLoadPicture(int channel, int bNeedPicture, NetSDKLib.fAnalyzerDataCallBack callback) {r_loginHandle = netsdk.CLIENT_RealLoadPictureEx(loginHandle, channel,NetSDKLib.EVENT_IVS_ALL, bNeedPicture, callback, null, null);if (loginHandle.longValue() == 0) {System.err.println("CLIENT_RealLoadPictureEx Failed, Error:" + ToolKits.getErrorCodePrint());} else {System.out.println("通道[" + channel + "]訂閱成功!");}}//初始化public static boolean InitTest(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {bInit = netsdk.CLIENT_Init(disConnect, null);if (!bInit) {System.out.println("Initialize SDK failed");return false;}//打開日志,可選NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();File path = new File("./sdklog/");if (!path.exists()) {path.mkdir();}String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + ToolKits.getDate() + ".log";setLog.nPrintStrategy = 0;setLog.bSetFilePath = 1;System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);System.out.println(logPath);setLog.bSetPrintStrategy = 1;bLogopen = netsdk.CLIENT_LogOpen(setLog);if (!bLogopen) {System.err.println("Failed to open NetSDK log");}// 設置斷線重連回調接口,設置過斷線重連成功回調函數后,當設備出現斷線情況,SDK內部會自動進行重連操作// 此操作為可選操作,但建議用戶進行設置netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);//設置登錄超時時間和嘗試次數,可選int waitTime = 5000; //登錄請求響應超時時間設置為5Sint tryTimes = 1; //登錄時嘗試建立鏈接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; // 設置子連接的超時時間netParam.nGetDevInfoTime = 3000;//獲取設備信息超時時間,為0默認1000msnetsdk.CLIENT_SetNetworkParam(netParam);return true;}//登陸public void Login() {// 登陸設備int nSpecCap = NetSDKLib.EM_LOGIN_SPAC_CAP_TYPE.EM_LOGIN_SPEC_CAP_TCP; // TCP登入IntByReference nError = new IntByReference(0);loginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser,m_strPassword, nSpecCap, null, deviceInfo, nError);if (loginHandle.longValue() != 0) {System.out.printf("Login Device[%s] Success!\n", m_strIp);} else {System.err.printf("Login Device[%s] Fail.Error[0x%x]\n", m_strIp, netsdk.CLIENT_GetLastError());LoginOut();}}//登出public void LoginOut() {if (loginHandle.longValue() != 0) {netsdk.CLIENT_Logout(loginHandle);}System.out.println("END...");netsdk.CLIENT_Cleanup();}/*** 設備斷線回調*/private static class DisConnectCallBack implements NetSDKLib.fDisConnect {private DisConnectCallBack() {}private static class CallBackHolder {private static FaceDetectService.DisConnectCallBack instance = new FaceDetectService.DisConnectCallBack();}public static FaceDetectService.DisConnectCallBack getInstance() {return FaceDetectService.DisConnectCallBack.CallBackHolder.instance;}public void invoke(NetSDKLib.LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);}}/*** 設備重連回調*/private static class HaveReConnectCallBack implements NetSDKLib.fHaveReConnect {private HaveReConnectCallBack() {}private static class CallBackHolder {private static FaceDetectService.HaveReConnectCallBack instance = new FaceDetectService.HaveReConnectCallBack();}public static FaceDetectService.HaveReConnectCallBack getInstance() {return FaceDetectService.HaveReConnectCallBack.CallBackHolder.instance;}public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);}} }Dao(JPA):
@Repository public interface FaceDetectDao extends CrudRepository<FaceDetect, String> {}注意:
1、上傳圖片到人臉庫時有一個問題,修改人員信息時,修改的圖片與上一個圖片是同一張時時會導致圖片是空的(不知道什么原因)。
2、new Memory設置太大會導致超時。
總結
以上是生活随笔為你收集整理的大华sdk(java)上传人脸图片到人脸库,订阅人脸识别对比的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 今天好无聊……悟空……你变成女妖精吧……
- 下一篇: echarts饼图, 中间显示总数