通过Java 轻松实现 AI 人脸识别登录

2022-06-07 00:00:00 代码 测试 的是 图片 封装



想自己搞一个人脸识别玩玩,随着开始查找资料来研究这方面的信息,还好有好几家公司都有提供这方面的免费API,也是省下来很多功夫。一开始采用的是face++,但是在执行到后一步人脸搜索时出现问题,一直提示INVALID_OUTER_ID,跟着官方文档,一步步抽离再封装,终还是以失败告终,无奈只能选择放弃。

接着辗转第二家 百度AI ,这次还是比较顺利的,中间只出现过一次错误 ❌ ,而且官方大大还给出了解决方案,很是贴心,终还是实现了开始的预想:成功使用人脸来实现注册和登录功能。

难度分析

由于使用的是百度云AI/face++这两个平台的现有的Api接口,所以分别对二者的难度进行分析介绍:

  • face++

旷视face++的难度在于需要自己对官方提供的代码段进行独立封装,这就比较考验开发者的代码抽取能力和 自我独立封装的技能,如果不能很好地进行抽取封装,就会造成代码的冗余以及内存的浪费,这样封装的效 果并不能达到佳。比较耗费时间,在抽取face++平台的代码段时需要对IO流有着比较好的理解,从而读取 读取配置文件中的内容,这里就不多做介绍。

  • 百度云AI

百度云AI可以让开发者对开发难度有所选择,因为该平台提供了两种方式:种方式类似于face++需要抽 取代码然后进行代码封装,难度分析见上述face++对分析;第二种方式则是百度云提供了Maven仓库,可以 直接导入依赖,直接调用相应的Api进行开发即可!有较好的选择性!

  • 前端使用JQuery调用本地摄像头进行拍摄(自我感觉这是❗️❗️难❗️❗️的部分)

项目回顾(百度云AI)

终效果演示:

技术选型:

  • SpringBoot

  • BootStrap

  • Thymeleaf

  • 百度云AI / Face++

项目需求分析

为了用户登录的便捷,不再输入账号密码进行手动登录与注册,而是使用JQuery调用本机的摄像头进行拍摄照片,然后调用人脸识别接口将人脸信息自动注册进所使用的平台(百度云/Face++)后,用户即可进行人脸扫描实现登录操作。

项目搭建

1. 前期准备

① 进入百度云的人脸识别控制台

如果没有百度账号可以使用手机号快速进行注册进入百度云AI控制台:

https://login.bce.baidu.com/?account=&redirect=http%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F%3F_%3D1652174073259%26fromai%3D1#/ai/face/overview/index

②创建人脸识别应用

【1】创建应用

【2】可以选择自己想要使用的接口:比如人脸识别、语音技术等,本次项目采用的是人脸识别,官方也默认选择了人脸识别的全部接口,所以也不需要做改动,只需要填写应用名称即可!

【3】获取秘钥

2. 测试百度云API

① 导入依赖

<dependency>
  <groupId>com.baidu.aip</groupId>
  <artifactId>java-sdk</artifactId>
  <version>4.9.0</version>
</dependency>

② 测试部分API(人脸注册、人脸检测、人脸搜索等)

  • 人脸注册

用于从人脸库中新增用户,可以设定多个用户所在组及组内用户的人脸图片

典型应用场景:构建属于自己人脸库,比如:会员人脸注册、已有用户补全人脸信息

测试代码

//人脸注册
@Test
public void testFaceRegister() throws IOException
{
  //1. 创建Java代码和百度云交互的Client对象
  AipFace client = new AipFace("AppId","Api_key","Api_secret");
  //2. 参数设置(示例下表格对参数进行介绍)
  HashMap<String,String> map = new HashMap<>();
  map.put("quality_control","NORMAL");//图片质量
  map.put("liveness_control","LOW");//活体检测
  //3. 构造图片
  String path = "本地图片路径";
  //上传的图片 两种格式:url地址 Base64字符串形式
  byte[] bytes = Files.readAllBytes(Paths.get(path));
  String encode = Base64Util.encode(bytes);
  //4.调用api方法完成人脸注册
  /**
  * 参数1:图片的url或者base64字符串
  * 参数2:图片形式(URL,BASE64)
  * 参数3:组Id(固定一个字符串)
  * 参数4:用户Id
  * 参数5:hashMap基本参数配置
  */

  JSONObject res = client.addUser(encode, "BASE64", "pdx", "1000", map);
  System.out.println(res.toString());
}

测试结果:只要后error_code为0则表示测试成功,后续封装代码也是需要判断error_code的值


  • 人脸检测

判断图片是否具有面部信息

测试代码

@Test
public void testFaceCheck() throws IOException
{
        //1. 创建Java代码和百度云交互的Client对象
        AipFace client = new AipFace("AppId","Api_key","Api_secret");
        //2. 构造图片
        String path = "本地图片路径";
        //上传的图片 两种格式:url地址 Base64字符串形式
        byte[] bytes = Files.readAllBytes(Paths.get(path));
        String encode = Base64Util.encode(bytes);

        //调用Api方法进行人脸检测
        /**
         * 参数1:图片的url或者base64字符串
         * 参数2:图片形式(URL,BASE64)
         * 参数3:hashMap中的基本参数配置(null:使用默认配置)
         */

        JSONObject res = client.detect(encode, "BASE64", null);
        System.out.println(res.toString(2));
    }

测试结果:


  • 人脸搜索

根据用户上传的图片和指定人脸库中的所有人脸进行比较,获取相似度高的一个或者某几个的评分返回值(数据,只需要条,相似度高的数据)score:相似度评分(80分以上可以认为是同一个人)

测试代码:

@Test
public void testFaceSearch() throws IOException
{
        //1. 创建Java代码和百度云交互的Client对象
    AipFace client = new AipFace("AppId","Api_key","Api_secret");
        //2. 构造图片
        String path = "本地图片路径";
        //上传的图片 两种格式:url地址 Base64字符串形式
        byte[] bytes = Files.readAllBytes(Paths.get(path));
        String encode = Base64Util.encode(bytes);
        //人脸搜索
        JSONObject res = client.search(encode, "BASE64", "pdx", null);
        System.out.println(res.toString(2));

    }

测试结果:


小结:

整体测试下来,和平常对数据库的操作类似,都是增删改查的操作,除了这些Api,还有其他的就不再赘述了,操作类似!所有测试代码也会同项目案例一并上传到Gitee仓库中!

3. 搭建项目(使用Thymeleaf模板引擎)

① 创建Maven项目

引入相关依赖,构建所需文件目录


② 编写properties配置文件

ai.appId="api_id"
ai.apiKey="api_key"
ai.secretKey="api_secret"
ai.imageType=BASE64
ai.groupId="自定义组"
server.max-http-header-size=1000KB
spring.thymeleaf.cache=false

③ 展示对上述部分Api接口进行二次封装

private AipFace client;

    private HashMap<String,String> map = new HashMap<>();

    private BaiduAiUtils(){
        map.put("quality_control","NORMAL");//图片质量
        map.put("liveness_control","LOW");//活体检测
    }

    @PostConstruct
    public void init()
{
        client = new AipFace(APP_ID,API_KEY,SECRET_KEY);
    }

    /**
     * 人脸注册,将用户照片存入人脸库中
     * @param userId
     * @param image
     * @return
     */

    public Boolean faceRegister(String userId,String image){
        //人脸注册
        JSONObject res = client.addUser(image, IMAGE_TYPE, groupId, userId, map);
        Integer errorCode = res.getInt("error_code");
        return errorCode == ? true : false;
    }

    /**
     * 人脸更新,更新人脸库中的用户照片
     * @param userId
     * @param image
     * @return
     */

    public Boolean faceUpdate(String userId,String image){
        //人脸更新
        JSONObject res = client.updateUser(image, IMAGE_TYPE, groupId, userId, map);
        Integer errorCode = res.getInt("error_code");
        return errorCode ==  ? true : false;
    }

想要了解全部封装代码请移步Gittee仓库

④ 编写Controller前端控制器代码

创建一个FaceLoginController类

  • 跳转到人脸登录页面的控制器

@RequestMapping("/")
public String toLogin(){
  return "index";
}
  • 实现人脸登录逻辑

/**
 * 人脸登录
 * @return
 * @throws Exception
 */

@RequestMapping("/face-login")
@ResponseBody
public  String searchface(@RequestBody @RequestParam(name = "imagebast64") StringBuffer imagebast64, HttpServletRequest request) throws Exception {
    String userId = faceLoginService.loginByFace(imagebast64);
    request.getSession().setAttribute("userId",userId);
    request.getSession().setAttribute("username","派大星");
    return userId;
}


  • 实现人脸登录业务逻辑层

由于在封装接口时设定的imageType为Base64,所以在实现前端拍照时使用的是Canvas Api提供了toDataURL()方法将画布中的图形转换为图片,而默认情况下,toDataURL()方法把图形转变成Base64编码格式的png,其格式为data:image/png;base64,xxxxx,而,后面的内容才是接口中需要的部分,所以需要对字符串进行切割处理。前端部分具体见下图:

注意事项(项目搭建前了解)

① 出现qps不足如何解决

Open api qps request limit reached

这个问题官方也给出了具体的解决方案,在百度云控制台可以免费领取测试额度,也是对开发者的一个福利。

② oauth 获取错误

 [main] WARN com.baidu.aip.client.BaseClient - oauth get error, current state: STATE_TRUE_CLOUD_USER
{
  "error_msg": "IAM Certification failed",
  "error_code": 14
}

具体原因:

仔细检查:APP_ID、API_KEY、SECRET_KEY字符串中是否有空格

项目总结

使用百度云AI把项目整体搭建下来,可以很完美的实现终的效果,人脸的识别速度也是相当迅速的,一些细节处理的特别到位,比如:在进行人脸识别的过程中眼睛必须对准摄像头,当你的眼睛有所阻碍时,会提示的某眼处有阻碍等等。但是在并发方面支持的并不是很到位!

////// END //////

相关文章