智慧社区(八)——社区人脸识别出入管理系统设计与实现

在社区安全管理日益智能化的背景下,传统的人工登记方式已难以满足高效、精准的管理需求。本文将详细介绍一套基于人脸识别技术的社区出入管理系统,该系统通过整合腾讯云 AI 接口、数据库设计与业务逻辑,实现了居民出入自动识别、记录追踪与访客管理的全流程数字化,为社区安全管理提供了高效解决方案。

系统核心模块概述

系统主要包含三大功能模块:

  • 人脸识别出入管理:通过调用第三方人脸识别 API,实现居民身份自动核验与出入状态记录
  • 出入记录查询统计:对居民出入数据进行多条件查询、分页展示与统计分析
  • 访客登记管理:支持访客信息的增删改查,补充非居民出入的管理场景

一、人脸识别出入管理模块

1.1 实现思路

人脸识别是系统的核心功能,其设计目标是实现 "刷脸" 即可完成身份核验与出入记录,核心流程如下:

  1. 小区信息加载:前端通过接口获取所有小区列表,供用户选择当前操作的小区(用于后续权限校验)
  2. 人脸信息核验:调用腾讯云人脸识别 API,验证传入图片中是否包含有效人脸(且仅一张)
  3. 身份匹配:将人脸信息与系统人员库比对,确认是否为已登记居民
  4. 权限校验:验证该居民是否属于当前选择的小区,确保仅本小区居民可正常出入
  5. 出入状态记录 :根据居民当前的出入状态(通过outTime字段是否为空判断),更新或创建出入记录,同时保存出入时的人脸图片

1.2 核心代码实现

1.2.1 小区列表接口

小区列表是权限校验的基础,接口通过查询数据库返回所有小区信息,供前端下拉选择:

java 复制代码
/**
 * 获取小区列表(用于前端选择与权限校验)
 * @return 包含小区列表的响应结果
 */
@GetMapping("/communityList")
public Result communityList() {
    // 查询所有小区信息(社区名称、ID等核心字段)
    List<Community> communityList = communityService.list();
    return Result.ok().put("data", communityList);
}

该接口直接调用 MyBatis-Plus 的list()方法查询全量小区数据,确保前端能实时获取最新的小区信息,为后续 "居民 - 小区" 权限匹配提供基础。

1.2.2 人脸识别核心接口

该接口是整个模块的核心,整合了人脸比对、权限校验、记录更新等全流程逻辑:

java 复制代码
/**
 * 人脸识别与出入记录处理
 * @param inOutFaceForm 包含人脸图片Base64编码、文件格式、小区ID的表单
 * @return 识别结果与操作状态
 */
@PostMapping("/add")
public Result add(@RequestBody InOutFaceForm inOutFaceForm) {
    // 1. 调用腾讯云人脸识别API,在人员库中搜索匹配人脸
    FaceApi faceApi = new FaceApi();
    RootResp resp = faceApi.searchPersonsReturnsByGroup(apiConfiguration, inOutFaceForm.getFileBase64());
    
    // 2. 处理API响应结果
    if (resp.getRet() == 0) { // 接口调用成功
        // 解析API返回的JSON数据,提取匹配的人员信息
        JSONObject object = JSONObject.parseObject(resp.getData().toString());
        JSONArray resultsReturnsByGroup = object.getJSONArray("ResultsReturnsByGroup");
        JSONObject returnsByGroup = resultsReturnsByGroup.getJSONObject(0);
        JSONArray groupCandidates = returnsByGroup.getJSONArray("GroupCandidates");
        JSONObject candidatesObj = groupCandidates.getJSONObject(0);
        JSONArray candidates = candidatesObj.getJSONArray("Candidates");
        
        // 3. 匹配系统中的居民信息(人员库ID与本地数据库关联)
        Person targetPerson = null;
        for (int i = 0; i < candidates.size(); i++) {
            JSONObject personInfo = candidates.getJSONObject(i);
            String personId = personInfo.getString("PersonId").substring(4); // 截取实际ID(去除前缀)
            long pid = Integer.parseInt(personId);
            Person person = personService.getById(pid);
            
            // 校验人脸ID与本地存储的人脸图片ID是否匹配(确保身份唯一)
            if (person != null) {
                String faceUrl = person.getFaceUrl();
                if (faceUrl != null && !faceUrl.isEmpty()) {
                    String faceId = personInfo.getString("FaceId");
                    String localFaceId = faceUrl.substring(faceUrl.lastIndexOf("/") + 1, faceUrl.lastIndexOf("."));
                    if (faceId.equals(localFaceId)) {
                        targetPerson = person;
                        break;
                    }
                }
            }
        }
        
        // 4. 身份与权限校验
        if (targetPerson == null) {
            return Result.ok().put("data", "人员信息不存在(未登记)");
        }
        // 校验当前选择的小区是否与居民所属小区一致
        if (inOutFaceForm.getCommunityId() != targetPerson.getCommunityId()) {
            return Result.ok().put("data", "非本小区居民,请联系管理员");
        }
        
        // 5. 处理出入记录(判断是"进入"还是"离开")
        InOutRecord record = new InOutRecord();
        record.setCommunityId(targetPerson.getCommunityId());
        record.setPersonId(targetPerson.getPersonId());
        
        // 保存人脸图片(Base64解码为文件,存储到服务器)
        String newFileName = UUID.randomUUID() + "." + inOutFaceForm.getExtName();
        String filePath = face + newFileName; // 本地存储路径
        Base64Util.decoderBase64File(inOutFaceForm.getFileBase64(), filePath);
        String picUrl = urlPrefix + "community/upload/face/" + newFileName; // 访问URL
        
        // 查询该居民是否有未完成的出入记录(outTime为空表示"在小区内")
        InOutRecord existingRecord = inOutRecordMapper.getInOutRecord(record);
        
        if (existingRecord == null) {
            // 无未完成记录 → 新增"进入"记录
            record.setInPic(picUrl);
            record.setInTime(LocalDateTime.now());
            inOutRecordMapper.insert(record);
            return Result.ok().put("data", "【" + targetPerson.getUserName() + "】进入小区");
        } else {
            // 有未完成记录 → 更新"离开"记录
            existingRecord.setOutPic(picUrl);
            existingRecord.setOutTime(LocalDateTime.now());
            inOutRecordMapper.updateById(existingRecord);
            return Result.ok().put("data", "【" + targetPerson.getUserName() + "】离开小区");
        }
    } else {
        // API调用失败(如人脸不清晰、无有效人脸等)
        return Result.ok().put("data", "人脸识别失败:错误码=" + resp.getRet() + ",原因=" + resp.getMsg());
    }
}

1.3 技术细节说明

  • 人脸图片处理 :前端传入的人脸图片以 Base64 编码格式传输,后端通过Base64Util解码为文件,存储到服务器指定目录,并生成可访问的 URL(用于记录与后续查看)
  • 腾讯云 API 封装 :通过FaceApi类统一封装人脸识别相关接口(如searchPersonsReturnsByGroup用于人脸搜索),简化业务层调用
  • 出入状态判断 :通过查询in_out_record表中是否存在outTime为空的记录,判断居民当前是 "进入" 还是 "离开",确保记录的连续性与准确性
  • 权限校验逻辑:通过比对居民所属小区 ID 与当前选择的小区 ID,防止非本小区居民随意出入,增强社区安全性

二、出入记录查询统计模块

2.1 表结构设计

in_out_record表用于存储居民出入的详细信息,核心字段设计如下:

字段名 类型 说明
in_out_record_id int 主键 ID(自增)
person_id int 关联居民 ID(外键)
community_id int 关联小区 ID(外键)
in_time datetime 进入时间
out_time datetime 离开时间(可为空,标识未离开)
in_pic varchar 进入时人脸图片 URL
out_pic varchar 离开时人脸图片 URL

2.2 核心功能实现

2.2.1 出入记录分页查询

支持按时间范围、小区、居民等条件查询,返回分页结果:

java 复制代码
/**
 * 出入记录多条件查询
 * @param form 包含查询条件(开始时间、结束时间、小区ID等)
 * @return 分页的出入记录列表
 */
@GetMapping("/list")
public Result getInOutList(InOutRecordListForm form) {
    PageVO pageVO = inOutRecordService.getInOutRecordList(form);
    return Result.ok().put("data", Collections.singletonMap("pageList", pageVO));
}

服务层通过InOutRecordListForm接收前端参数,整合 MyBatis-Plus 的分页插件,实现带条件的分页查询,支持前端表格展示与分页交互。

2.2.2 数据统计分析

提供小区出入数据的统计图表(如每日出入次数、高峰时段等):

java 复制代码
/**
 * 小区出入数据统计
 * @return 统计结果(按天/按时段的出入次数等)
 */
@GetMapping("/chart")
public Result chart() {
    Map<String, Object> stats = inOutRecordService.chart();
    return Result.ok().put("data", stats);
}

通过 SQL 聚合查询(如按日期分组统计in_time数量),生成可视化所需的数据,辅助社区管理人员掌握出入规律。

三、访客登记管理模块

对于非小区居民的访客,系统提供专门的访客登记模块,通过manual_record表管理访客信息,核心功能包括:

  • 访客信息添加:登记访客姓名、身份证号、到访事由、访问时间等信息
  • 访客记录查询:支持按时间、姓名、小区等条件查询历史访客
  • 记录维护:提供访客信息的修改、删除功能,满足管理需求

相关推荐
万粉变现经纪人6 分钟前
如何解决pip安装报错ModuleNotFoundError: No module named ‘keras’问题
人工智能·python·深度学习·scrapy·pycharm·keras·pip
Chan167 分钟前
【智能协同云图库】第七期:基于AI调用阿里云百炼大模型,实现AI图片编辑功能
java·人工智能·spring boot·后端·spring·ai·ai作画
xiangweiqiang15 分钟前
用phpstudy安装php8.2后报错:意思是找不到php_redis.dll拓展时
开发语言·php
mitt_29 分钟前
go语言变量
开发语言·后端·golang
TravisBytes1 小时前
gRPC C++ 从 0 到 1 → 到线上:**超详细** 环境搭建、编码范式、性能调优与 DevOps 全攻略
开发语言·c++·devops
kngines1 小时前
【Node.js从 0 到 1:入门实战与项目驱动】1.1 什么是 Node.js?(定义、运行环境、与浏览器 JavaScript 的区别)
开发语言·javascript·node.js
java1234_小锋1 小时前
【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 词云图-微博评论词云图实现
python·自然语言处理·flask·nlp·nlp舆情分析
hrrrrb1 小时前
【Spring Boot 快速入门】六、配置文件
java·spring boot·intellij-idea
codists2 小时前
《AI-Assisted Programming》读后感
python
Asu52022 小时前
思途Mybatis学习 0805
java·spring boot·学习·mybatis