# dh-face-recognition **Repository Path**: 495300897/dh-face-recognition ## Basic Information - **Project Name**: dh-face-recognition - **Description**: JAVA对接大华SDK实现人脸识别功能,人脸识别回调事件。 - **Primary Language**: Unknown - **License**: AFL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-09-16 - **Last Updated**: 2025-10-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: SpringBoot, Java, 大华SDK, 人脸识别 ## README # dh-face-recognition #### 介绍 JAVA对接大华SDK实现人脸识别功能,人脸识别回调事件。 #### 软件架构 软件架构说明 SPRING,SPRINGBOOT,JDK1.8,MYSQL8.0,MAVEN3.8,DH_SDK #### 安装教程 1. windows,linux集成大华SDK 2. springboot,mysql,maven 3. 带人脸识别算法的大华摄像机 #### 使用说明 1. 登录大华摄像机WEB页面,按以下设置 - 事件管理 -> 报警设置 -> 启用 -> 应用 ![输入图片说明](0.png) - 相机设置 - 编码设置 - 视频叠加 - 人脸检测(启用), 人脸识别(启用)- 应用 ![输入图片说明](1.png) - 智能 - 智能配置 - 智能方案 - 智能模式选择 - 人脸识别 - 启用 ![输入图片说明](2.png) 2. JAVA实现摄像机添加人脸库、添加人员、通道布控、人脸识别 ![输入图片说明](3.png) /** * 添加人脸库 * @param groupName 需要添加的人脸库名称 */ public static String addGroup(String groupName) { NET_ADD_FACERECONGNITION_GROUP_INFO addGroupInfo = new NET_ADD_FACERECONGNITION_GROUP_INFO(); // 人脸库名称 try { System.arraycopy(groupName.getBytes("GBK"), 0, addGroupInfo.stuGroupInfo.szGroupName, 0, groupName.getBytes("GBK").length); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } /* * 入参 */ NET_IN_OPERATE_FACERECONGNITION_GROUP stuIn = new NET_IN_OPERATE_FACERECONGNITION_GROUP(); // 添加人员组信息 stuIn.emOperateType = EM_OPERATE_FACERECONGNITION_GROUP_TYPE.NET_FACERECONGNITION_GROUP_ADD; stuIn.pOPerateInfo = addGroupInfo.getPointer(); /* * 出参 */ NET_OUT_OPERATE_FACERECONGNITION_GROUP stuOut = new NET_OUT_OPERATE_FACERECONGNITION_GROUP(); addGroupInfo.write(); boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionGroup(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000); addGroupInfo.read(); String groupId = null; if (bRet) { groupId = new String(stuOut.szGroupId).trim(); // 新增记录的人员组ID,唯一标识一组人员 log.info("人员组ID: {}", groupId); } return groupId; } /** * 添加人员 * @param groupId 人脸库ID * @param passengerDO 人员信息 * @return uid */ public static String addPerson(String groupId, PassengerDO passengerDO) { // 入参 NET_IN_OPERATE_FACERECONGNITIONDB stuIn = new NET_IN_OPERATE_FACERECONGNITIONDB(); stuIn.emOperateType = EM_OPERATE_FACERECONGNITIONDB_TYPE.NET_FACERECONGNITIONDB_ADD; ///////// 使用人员扩展信息 ////////// stuIn.bUsePersonInfoEx = 1; // 人脸库ID System.arraycopy(groupId.getBytes(), 0, stuIn.stPersonInfoEx.szGroupID, 0, groupId.getBytes().length); // 生日设置 /* * 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) passengerDO.getSex(); // 人员名字 try { System.arraycopy(passengerDO.getPersonName().getBytes("GBK"), 0, stuIn.stPersonInfoEx.szPersonName, 0, passengerDO.getPersonName().getBytes("GBK").length); } catch (UnsupportedEncodingException ex) { log.error("添加人员名字错误:", ex); return "ERR:" + ex.getMessage(); } // 证件类型 stuIn.stPersonInfoEx.byIDType = (byte) passengerDO.getIdType(); // 证件号 System.arraycopy(passengerDO.getSzId().getBytes(), 0, stuIn.stPersonInfoEx.szID, 0, passengerDO.getSzId().getBytes().length); // 图片张数 try { add3Pics(stuIn, passengerDO.getPassengerPhotoUrl()); } catch (IOException ex) { log.error("添加图片错误:", ex); return "ERR:" + ex.getMessage(); } // 出参 NET_OUT_OPERATE_FACERECONGNITIONDB stuOut = new NET_OUT_OPERATE_FACERECONGNITIONDB(); stuIn.write(); boolean bRet = LoginModule.netsdk.CLIENT_OperateFaceRecognitionDB(LoginModule.m_hLoginHandle, stuIn, stuOut, 3000); stuIn.read(); String szUid = new String(stuOut.szUID).trim(); if (bRet) { log.info("szUID: {}", szUid); } else { szUid = "ERR:" + LoginModule.netsdk.CLIENT_GetLastError(); log.error("添加人员失败: {}", szUid); } // 清理引用 KEEP_MEM_REFS.clear(); return szUid; } ![输入图片说明](4.png) /** * 以人脸库的角度进行布控 * @param groupId 人脸库ID * @param hashMap key:撤控通道 value:相似度 */ public static boolean putDisposition(String groupId, HashMap hashMap) { /* * 入参 */ NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO stuIn = new NET_IN_FACE_RECOGNITION_PUT_DISPOSITION_INFO(); // 人脸库ID System.arraycopy(groupId.getBytes(), 0, stuIn.szGroupId, 0, groupId.getBytes().length); int i = 0; for (Map.Entry entry : hashMap.entrySet()) { stuIn.stuDispositionChnInfo[i].nChannelID = entry.getKey() - 1; stuIn.stuDispositionChnInfo[i].nSimilary = entry.getValue(); i ++; } // 布控视频通道个数 stuIn.nDispositionChnNum = hashMap.size(); /* * 出参 */ NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO stuOut = new NET_OUT_FACE_RECOGNITION_PUT_DISPOSITION_INFO(); boolean bRet = LoginModule.netsdk.CLIENT_FaceRecognitionPutDisposition(LoginModule.m_hLoginHandle, stuIn, stuOut, 4000); if (bRet) { log.info("通道布控结果个数: {}", stuOut.nReportCnt); } else { log.error("通道布控失败: {}", LoginModule.netsdk.CLIENT_GetLastError()); } return bRet; } - 人脸识别事件订阅 ![输入图片说明](5.png) @Override public int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType, Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize, Pointer dwUser, int nSequence, Pointer reserved) throws UnsupportedEncodingException { // 279 = dwAlarmType 人脸识别 log.info("收到事件, dwAlarmType = {}", dwAlarmType); if (dwAlarmType == NetSDKLib.EVENT_IVS_FACERECOGNITION) { NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO recognitionInfo = new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO(); ToolKits.GetPointerData(pAlarmInfo, recognitionInfo); NetSDKLib.NET_FACE_DATA faceData = recognitionInfo.stuFaceData; String netTime = recognitionInfo.UTC.toStringTime(); log.info("事件发生时间: {}", netTime); // 保存全景图 // saveImage(pBuffer, recognitionInfo); log.info("nCandidateNum: {}, nRetCandidatesExNum: {}", recognitionInfo.nCandidateNum, recognitionInfo.nRetCandidatesExNum); NetSDKLib.CANDIDATE_INFO[] stuCandidates = recognitionInfo.stuCandidates; for (int i = 0; i < recognitionInfo.nCandidateNum; i++) { NetSDKLib.FACERECOGNITION_PERSON_INFO personInfo = stuCandidates[i].stPersonInfo; // 保存识别结果 saveRecognition(netTime, recognitionInfo.nChannelID, personInfo); } log.info("人脸数据: 性别 = {}, 年龄 = {}, 质量 = {}", faceData.emSex, faceData.nAge, faceData.nFaceQuality); log.info("nChannelID: {}, szName: {}", recognitionInfo.nChannelID, new String(recognitionInfo.szName)); log.info("检测到的物体: {}, 置信度(0~255): {}\n", new String(recognitionInfo.stuObject.szObjectType), recognitionInfo.stuObject.nConfidence); } return 0; } } ![输入图片说明](6.png) 3. 联系方式 WX: fzhihui, QQ: 495300897 #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)