SpringBoot项目集成腾讯云人脸识别服务实现人员库管理

一、准备工作

1. 创建腾讯云人员库

  1. 登录腾讯云控制台,进入人脸识别服务
  2. 创建人员库:
    • 设置人员库ID
    • 设置人员库名称    
  3. 创建API密钥:

    • 获取SecretId和SecretKey
    • 特别注意​:SecretKey创建后需立即保存,页面不会再次显示

二、项目配置

1. 配置文件设置

application.yml中添加以下配置:

upload-path:
  url: http://localhost:8080/
  face: D:/community/upload/face/
  
plateocr:
  secretId: 你的secretId
  secretKey: 你的secretKey
  server: iai.tencentcloudapi.com  # 固定值
  region: ap-beijing 
  groupId: 你创建的人员库的id
  used: true       # 是否启用人脸识别功能
  passPercent: 80  # 相似度达到80%认为通过

2. 配置类编写

创建ApiConfiguration配置类:

package com.qcby.AICommunity.config;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(value="plateocr")
@Component
@Data
@ApiModel(value = "ApiConfiguration", description = "人脸识别参数描述")
public class ApiConfiguration {
    @ApiModelProperty("人脸识别secretId")
    private String secretId;
    
    @ApiModelProperty("人脸识别secretKey")
    private String secretKey;
    
    @ApiModelProperty("人脸识别服务器ip")
    private String serverIp;
    
    @ApiModelProperty("人脸识别服务器区域")
    private String area;
    
    @ApiModelProperty("人脸识别默认分组")
    private String groupId;
    
    @ApiModelProperty("人脸识别用户id前缀")
    private String personIdPre;
    
    @ApiModelProperty("人脸识别随机数")
    private String nonceStr;
    
    @ApiModelProperty("是否启用人脸识别功能")
    private boolean used = false;
    
    @ApiModelProperty("人脸识别比对准确度(如80表示80%通过)")
    private float passPercent;
}

三、核心工具类实现

1. FaceApi工具类

完整实现腾讯云人脸识别API调用:

package com.qcby.AICommunity.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qcby.AICommunity.config.ApiConfiguration;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.*;
import org.apache.log4j.Logger;

public class FaceApi {
    private Logger logger = Logger.getLogger(FaceApi.class);

    // 人脸分析
    public RootResp detectFace(ApiConfiguration config, String url) {
        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("Url", url);
            paramObj.put("MaxFaceNum",1);
            paramObj.put("MinFaceSize",34);
            paramObj.put("NeedFaceAttributes",0);
            paramObj.put("NeedQualityDetection",1);
            DetectFaceRequest req = DetectFaceRequest.fromJsonString(paramObj.toJSONString(),DetectFaceRequest.class);
            DetectFaceResponse resp = client.DetectFace(req);
            result.setData(DetectFaceResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }

    // 添加个体
    public RootResp newperson(ApiConfiguration config, String personId, String personName, 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("GroupId", config.getGroupId());
            paramObj.put("PersonId", config.getPersonIdPre() + personId);
            paramObj.put("PersonName", personName);
            paramObj.put("Image", image);
            CreatePersonRequest req = CreatePersonRequest.fromJsonString(paramObj.toJSONString(), CreatePersonRequest.class);
            CreatePersonResponse resp = client.CreatePerson(req);
            result.setData(CreatePersonResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }

    // 删除个体
    public RootResp delperson(ApiConfiguration config, String personId) {
        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("PersonId", config.getPersonIdPre() + personId);
            DeletePersonRequest req = DeletePersonRequest.fromJsonString(paramObj.toJSONString(), DeletePersonRequest.class);
            DeletePersonResponse resp = client.DeletePerson(req);
            result.setData(DeletePersonResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }

    // 增加人脸
    public RootResp addface(ApiConfiguration config, String personId, 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();
            JSONArray images = new JSONArray();
            images.add(image);
            paramObj.put("PersonId", config.getPersonIdPre() + personId);
            paramObj.put("Images", images);
            CreateFaceRequest req = CreateFaceRequest.fromJsonString(paramObj.toJSONString(), CreateFaceRequest.class);
            CreateFaceResponse resp = client.CreateFace(req);
            result.setData(CreateFaceResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }

    // 删除人脸
    public RootResp delface(ApiConfiguration config, String personId, String faceId) {
        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();
            JSONArray faces = new JSONArray();
            faces.add(faceId);
            paramObj.put("PersonId", config.getPersonIdPre() + personId);
            paramObj.put("FaceIds", faces);
            DeleteFaceRequest req = DeleteFaceRequest.fromJsonString(paramObj.toJSONString(), DeleteFaceRequest.class);
            DeleteFaceResponse resp = client.DeleteFace(req);
            result.setData(DeleteFaceResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }

    // 人脸验证
    public RootResp faceVerify(ApiConfiguration config, String personId, 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("PersonId", config.getPersonIdPre() + personId);
            paramObj.put("Image", image);
            VerifyFaceRequest req = VerifyFaceRequest.fromJsonString(paramObj.toJSONString(), VerifyFaceRequest.class);
            VerifyFaceResponse resp = client.VerifyFace(req);
            result.setData(VerifyFaceResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }

    // 人员搜索(按库返回)
    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);
            paramObj.put("NeedPersonInfo", 1);
            paramObj.put("MaxFaceNum", 1);
            SearchFacesReturnsByGroupRequest req = SearchFacesReturnsByGroupRequest.fromJsonString(paramObj.toJSONString(), SearchFacesReturnsByGroupRequest.class);
            SearchFacesReturnsByGroupResponse resp = client.SearchFacesReturnsByGroup(req);
            result.setData(VerifyFaceResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            result.setRet(-1);
            result.setMsg(e.toString());
            logger.error(e.toString());
        }
        logger.info(result);
        return result;
    }
}

四、业务接口实现

1. 人员信息实体类

@Data
public class PersonForm {
    private Long personId;      // 人员ID
    private String extName;     // 图片扩展名
    private String fileBase64;  // 图片Base64编码
}

2. 控制器实现

@RestController
@RequestMapping("/person")
public class PersonController {
    
    @Autowired
    private IPersonService personService;

    @Autowired
    private PersonMapper personMapper;

    @Autowired
    private ICommunityService communityService;

    @Autowired
    private ApiConfiguration apiConfiguration;

    @Value("${upload-path.face}")
    private String faceLocalUrl;

    @Value("${upload-path.url}")
    private String uploadUrl;   

    /​**​
     * 添加人员信息及人脸数据
     */
    @PostMapping("/addPerson")
    public Result addPerson(@RequestBody PersonForm form) throws Exception {
        // 只有used为true时才进行人脸上传
        if(apiConfiguration.isUsed()){
            // 根据id查到人员信息方便后续更新状态
            Person person = personService.getById(form.getPersonId());
            // 调用自定义的newPerson方法进行文件上传
            String faceId = newPerson(form, person.getUserName());
            
            if(faceId == null || faceId.equals("")){
                return Result.error("人脸识别失败");
            } else {
                // 构建文件名和访问URL
                String fileName = faceId + "." + form.getExtName();
                String faceUrl = uploadUrl + faceLocalUrl.substring(3) + fileName;
                
                // 更新人员信息
                person.setFaceUrl(faceUrl);
                person.setState(2);  // 设置状态为已采集
                person.setFaceBase(form.getFileBase64().substring(0,60)); // 保存部分base64用于展示
                personService.updateById(person);
                
                return Result.ok();
            }
        } else {
            return Result.error("人脸上传失败");
        }
    }

    /​**​
     * 创建人脸信息并调用腾讯云接口
     */
    private String newPerson(PersonForm form, String userName) throws Exception {
        String faceId = null;
        String fileBase64 = form.getFileBase64();
        String extName = form.getExtName();
        String personId = String.valueOf(form.getPersonId());
        String savePath = faceLocalUrl;
        
        if(fileBase64 != null && !fileBase64.equals("")){
            FaceApi faceApi = new FaceApi();
            // 调用腾讯云接口添加人员
            RootResp newperson = faceApi.newperson(apiConfiguration, personId, userName, fileBase64);
            
            if(newperson.getRet() == 0){
                JSONObject jsonObject = JSON.parseObject(newperson.getData().toString());
                faceId = jsonObject.getString("FaceId");
                
                if(faceId != null && !faceId.equals("")){
                    // 保存文件到本地
                    savePath = savePath + faceId + "." + extName;
                    Base64Util.decoderBase64File(fileBase64, savePath);
                }
            } else {
                return faceId;
            }
        }
        return faceId;
    }
}

五、Base64工具类

public class Base64Util {
    /​**​
     * 将Base64字符串解码并保存为文件
     */
    public static void decoderBase64File(String base64Code, String savePath) throws Exception {
        byte[] buffer = Base64.getDecoder().decode(base64Code);
        FileOutputStream out = new FileOutputStream(savePath);
        out.write(buffer);
        out.close();
    }
}

六、数据库设计

人员表(person)结构

 

七、实现流程说明

api接口文档:

  1. 前端调用流程​:

    • 居民管理页面点击"人脸采集"
    • 上传图片并转换为Base64编码
    • 调用后端接口传递personId、extName和fileBase64
  2. 后端处理流程​:

    • 接收参数并验证
    • 调用腾讯云API将人脸添加到人员库
    • 保存图片到本地服务器
    • 更新数据库中的状态和URL信息
  3. 数据存储位置​:

    • 腾讯云人员库:存储人脸特征数据
    • 本地服务器:存储原始人脸图片
    • 数据库:存储人员信息和图片访问路径

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐