当前位置: 首页 > ai >正文

Spring Boot集成腾讯云人脸识别实现智能小区门禁系统

1. 项目概述

本文将介绍如何基于Spring Boot集成腾讯云人员库实现人脸识别门禁系统。系统功能包括:

  • 前端拍照或上传人脸照片
  • 调用腾讯云AI接口进行人脸识别
  • 验证人员身份及小区归属
  • 生成出入记录并保存人脸图片
  • 数据库实时更新出入状态

2. 系统架构设计

前端页面 → Spring Boot后端 → 腾讯云AI接口 → 本地数据库↑        ↑人脸图片    出入记录

3. 前端页面实现

前端页面需要实现以下功能:

  • 摄像头实时拍照功能
  • 人脸图片上传功能
  • 小区选择下拉菜单
  • 识别结果展示区域
  • 出入记录显示面板

4. 后端接口实现

4.1 出入记录控制器(InOurRecordController)

@PostMapping("/add")
public Result add(@RequestBody InOutForm inOutFaceForm) {// 调用腾讯AI接口进行人脸识别FaceApi faceApi = new FaceApi();RootResp resp = faceApi.searchPersonsReturnsByGroup(apiConfiguration, inOutFaceForm.getFileBase64());if (resp.getRet() != 0) {return Result.error("人脸识别失败: " + resp.getMsg());}// 解析腾讯云返回数据JSONObject result = parseTencentResponse(resp);if (result == null) {return Result.error("未识别到有效人脸信息");}// 验证人员身份和小区归属Person person = validatePerson(result, inOutFaceForm.getCommunityId());if (person == null) {return Result.error("身份验证失败");}// 生成出入记录return generateInOutRecord(inOutFaceForm, person);
}// 解析腾讯云返回数据
private JSONObject parseTencentResponse(RootResp resp) {JSONObject object = JSONObject.parseObject(resp.getData().toString());JSONArray resultsReturnsByGroup = object.getJSONArray("ResultsReturnsByGroup");JSONObject returnsByGroup = resultsReturnsByGroup.getJSONObject(0);JSONArray groupCandidates = returnsByGroup.getJSONArray("GroupCandidates");JSONObject groupCandidate = groupCandidates.getJSONObject(0);JSONArray candidates = groupCandidate.getJSONArray("Candidates");// 获取相似度最高的候选人JSONObject candidate = candidates.getJSONObject(0);if (candidate.getInteger("Score") < 80) {return null; // 相似度过低}return candidate;
}// 验证人员信息
private Person validatePerson(JSONObject candidate, Integer communityId) {String personId = candidate.getString("PersonId").substring(4);Person person = personService.getById(Long.parseLong(personId));if (person == null) {return null;}if (!communityId.equals(person.getCommunityId())) {throw new BusinessException("非本小区居民");}return person;
}// 生成出入记录
private Result generateInOutRecord(InOutForm form, Person person) {InOutRecord record = new InOutRecord();record.setCommunityId(person.getCommunityId());record.setPersonId(person.getPersonId());try {// 保存人脸图片String fileName = saveFaceImage(form.getFileBase64(), form.getExtName());String imagePath = urlPrefix + "community/upload/face/" + fileName;// 检查现有记录InOutRecord existingRecord = inOutRecordMapper.getInOutRecord(record);if (existingRecord == null) {// 进入记录record.setInTime(LocalDateTime.now());record.setInPic(imagePath);inOutRecordMapper.insert(record);return Result.ok("【" + person.getUserName() + "】进入小区");} else {// 离开记录existingRecord.setOutTime(LocalDateTime.now());existingRecord.setOutPic(imagePath);inOutRecordMapper.updateById(existingRecord);return Result.ok("【" + person.getUserName() + "】离开小区");}} catch (Exception e) {logger.error("记录生成失败", e);return Result.error("系统异常");}
}// 保存图片到本地
private String saveFaceImage(String base64Data, String extName) {String fileName = UUID.randomUUID() + "." + extName;Base64Util.decoderBase64File(base64Data, faceImagePath + fileName);return fileName;
}

4.2 出入记录表单(InOutForm)

@Data
public class InOutForm {private Integer communityId;  // 小区IDprivate String extName;       // 图片扩展名private String fileBase64;    // Base64编码的图片数据
}

5. 腾讯云接口封装(FaceApi)

5.1 关键方法:人员搜索

public RootResp searchPersonsReturnsByGroup(ApiConfiguration config, String image) {RootResp result = new RootResp();try {Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();paramObj.put("GroupIds", new String[]{config.getGroupId()});paramObj.put("Image", image);paramObj.put("MaxPersonNumPerGroup", 5); // 返回最相似的5个候选人paramObj.put("NeedPersonInfo", 1);       // 返回人员详细信息paramObj.put("MaxFaceNum", 1);           // 最多识别1张人脸SearchFacesReturnsByGroupRequest req = SearchFacesReturnsByGroupRequest.fromJsonString(paramObj.toJSONString(), SearchFacesReturnsByGroupRequest.class);SearchFacesReturnsByGroupResponse resp = client.SearchFacesReturnsByGroup(req);result.setData(SearchFacesReturnsByGroupResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error("腾讯云接口调用失败", e);}return result;
}

6. 数据库设计与关键SQL

6.1 出入记录表(in_out_record)

字段类型描述
idBIGINT主键ID
community_idINT小区ID
person_idBIGINT人员ID
in_timeDATETIME进入时间
out_timeDATETIME离开时间
in_picVARCHAR(255)进入时照片路径
out_picVARCHAR(255)离开时照片路径

6.2 关键SQL:判断进出状态

<select id="getInOutRecord" resultType="com.qcby.AICommunity.entity.InOutRecord">SELECT * FROM in_out_record WHERE community_id = #{communityId} AND person_id = #{personId} AND out_time IS NULL
</select>
http://www.xdnf.cn/news/18310.html

相关文章:

  • 【C++去除整数某一位数字求新数和倍数保留2位小数控制】2022-10-22
  • 人工智能 -- 循环神经网络day1 -- 自然语言基础、NLP基础概率、NLP基本流程、NLP特征工程、NLP特征输入
  • 打造医疗新质生产力
  • 如何用算力魔方4060安装PaddleOCR MCP 服务器
  • visual studio更改git提交的用户名和邮件
  • Seaborn数据可视化实战:Seaborn基础与实践-数据可视化的艺术
  • 高效处理NetCDF文件经纬度转换:一个纯CDO驱动的Bash脚本详解
  • [大模型微调]基于llama_factory用 LoRA 高效微调 Qwen3 医疗大模型:从原理到实现
  • WPF中UI线程频繁操作造成卡顿的处理
  • 中文房间悖论:人工智能理解力的哲学拷问
  • 深度解析游戏引擎中的相机:视图矩阵
  • 小体积晶振1610/2016/3225选型参数
  • 小游戏AssetBundle加密方案解析
  • 5.Shell脚本修炼手册---Linux正则表达式(Shell三剑客准备启动阶段)
  • 电能质量监测装置 分布式光伏安全并网“准入证”
  • 8.21 随机森林
  • conda create 报错:Unable to read repodata JSON(镜像 pkgs/free 导致)
  • Neovim clangd LSP 配置出现 “attempt to call field ‘ge‘”
  • C# 13 与 .NET 9 跨平台开发实战(第一章:开发环境搭建与.NET概述-下篇)
  • 鸿蒙中基础耗时分析:Time分析
  • 音视频面试题集锦第 29 期
  • JetBrains Mono字体
  • Vue3组件系统完全指南:从入门到面试通关
  • (第二十期下)超链接的更多分类
  • 血缘元数据采集开放标准:OpenLineage Dataset Facets
  • java开发面试题(提高篇)
  • 大数据毕业设计选题推荐-基于大数据的北京气象站数据可视化分析系统-Hadoop-Spark-数据可视化-BigData
  • JavaScript基础语法five
  • Python学习 -- MySQL数据库的查询及案例
  • 计算两幅图像在特定交点位置的置信度评分。置信度评分反映了该位置特征匹配的可靠性,通常用于图像处理任务(如特征匹配、立体视觉等)