基于Face++,使用Spring Boot+Elemnet-UI实现人脸识别登录。

这篇具有很好参考价值的文章主要介绍了基于Face++,使用Spring Boot+Elemnet-UI实现人脸识别登录。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上一篇文章只是封装了人脸检测的一些工具类,要实现刷脸登录,我们首先得思考一个问题,就是如何将我们的人脸和登录账户信息进行绑定,让它通过人脸就能识别到当前登录的账户是谁的账户。

这个问题我们可以这样解决,我浏览Face++的官网发现它还有人脸比对的一个API,我点进去一看,这不就是实现人脸登录的关键API吗?

element ui 人脸,Java,spring boot,vue.js,人工智能

 继续查看它需要的参数。

element ui 人脸,Java,spring boot,vue.js,人工智能

 我们可以看到它需要的是两个图片的face_token,用两个图片的face_token,进行对比,得出它是不是同一个人。那就简单多了。许多问题都迎刃而解。接下来就是我具体的实现过程,大家可以参考一下。

1.准备工作

首先,在我们封装的工具类中,添加人脸比对的方法:

   /**
     * 对比两个人脸的face_token
     * @param face_token1
     * @param face_token2
     * @return 如果为true则是同一个人
     * @throws Exception
     */
    public static boolean compareFace(String face_token1, String face_token2) throws Exception {
        String url = "https://api-cn.faceplusplus.com/facepp/v3/compare";
        HashMap<String, byte[]> byteMap = new HashMap<>();
        map.put("face_token1", face_token1);
        map.put("face_token2", face_token2);
        byte[] bacd = HttpUtils.post(url, map, null);
        String str = new String(bacd);
        System.out.println("str = " + str);
        //转为为对象,获取检索的置信度
        if (str.indexOf("error_message") != -1) {
            return false;
        }
        JSONObject jsonObject = JSONObject.parseObject(str);
        JSONObject thresholds = (JSONObject) jsonObject.get("thresholds");
        //获取到十万份之一的阈值
        Double le5 = thresholds.getDoubleValue("1e-5");
        //获取置信率
        Double confidence = jsonObject.getDoubleValue("confidence");
        if (confidence > le5) {
            //说明存在这个人脸,比对成功
            return true;
        }
        return false;
}

其次,在登录账户的数据库中,添加两个字段,用于保存图片的face_token和图片,由于我配置了一个FastDFS的文件服务器,我的图片都是保存在文件服务器上面,所有这里我就用varchar类型的数据保存我的文件地址即可,我还配置了Nginx服务器,所以可以直接通过保存图片的地址直接预览图片,各位可以根据需求设置自己的字段。

注:如果大家没有配置文件服务器,可以增加blob类型的字段,用于保存图片的二进制数据。

element ui 人脸,Java,spring boot,vue.js,人工智能

数据中增加了两个字段,我们映射数据库的实体类也得增加相应的属性。注意属性的命名要和数据库中的字段对应。

element ui 人脸,Java,spring boot,vue.js,人工智能

2.正文开始

完成准备工作之后,开始编写后端的接口。

注:我们在登录时,前端返回的数据是图片的64位编码。(这里有一个坑,也不算坑,就是比较麻烦,因为我们封装的人脸检测的方法,它的参数是File类型,我们需要将图片保存到本地,然后在将图片作为参数去请求接口,后面我发现它的参数除了File类型的文件,还有直接就是Base64编码的图片。如图)

element ui 人脸,Java,spring boot,vue.js,人工智能

所以为了方便,我们在去多封装一个参数是base64编码的图片的人脸检测的方法:

    /**
     * 通过图片的Base64为编码获取图片的face_token
     * @param base64img
     * @return
     * @throws Exception
     */
    public static String getFaceTokenBase64Img(String base64img) throws Exception {
        //定义要请求接口的地址
        String url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
        //封装参数
        map.put("image_base64",base64img);
        //请求Face++人脸检测的图片,拿到Face++接口返回的数据
        byte[] bacd = HttpUtils.post(url, map, null);
        //拿到接口返回的Json数据,提取出Face_Token
        String str = new String(bacd);
        System.out.println(str);
        //判断接口返回的数据是否出错
        if (str.indexOf("error_message") != -1) {
            System.out.println("请求发送错误!");
            return null;
        }
        //转换为Json对象
        JSONObject jsonObject = JSONObject.parseObject(str);
        Integer face_num = jsonObject.getInteger("face_num");
        if (face_num == 1) {
            //存在人脸,取出face_token
            JSONArray facesArray = (JSONArray) jsonObject.get("faces");
            JSONObject faceJson = (JSONObject) facesArray.get(0);
            String face_token = faceJson.getString("face_token");
            return face_token;
        }
        return null;
    }

2.1   后端人脸注册的接口

  我们需要通过人脸就能知道这个人脸属于那个账户,通过人脸识别就能自动登录账户,所以我们需要将人脸和账户绑定起来。

我们知道Face++中对于人脸检测的图片会返回一个face_token,我们只需要将前端传递过来的图片的base64编码,获取到它的face_token ,然后将他和前端返回过来的用户绑定在一起,实际上就是保存用户的face_token,也就是前面我们在登录表中新增face_token字段。

代码如下,代码中有相应的注释:

  /**
     * 注册人脸,将人脸和账户信息绑定在一起
     * @param base64img
     * @param userId
     * @return
     */
    @Override
    public Result registerFace(String base64img, Integer userId) {
        //根据id获取需要绑定的用户
        User user = userMapper.selectById(userId);
        //获取face_token
        try {
            String base = base64img.split(",")[1];
            String faceToken = FaceUtils.getFaceTokenBase64img(base);
            //保存face_token到用户中
            user.setFaceToken(faceToken);
            //获取base64编码数据
            //将base64转化为byte数组
            byte[] img = Base64.getDecoder().decode(base);
            //设置用户的img
            user.setImg(img);
            //最后将其保存到数据库,即可完成人脸绑定
            int updateById = userMapper.updateById(user);
            //如果受影响的行数为1,则保存成功
            if(updateById==1){
                return Result.success("注册成功!");
            }
            return Result.error("注册失败");

        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("出错了!");
        }
    }
}

2.2 人脸注册前端代码编写:

前端使用Vue2.0+Element-UI进行编写,大家可以随意发挥,主要的功能就是点击注册人脸,能够打开摄像头,拍照传递给后端即可。

比如我们前端页面是这样的:

element ui 人脸,Java,spring boot,vue.js,人工智能

 我们给他增加一个列来展示注册的人脸,在操作中增加一个采集人脸的按钮,当我们点击采集人脸,会打开摄像头进行拍照,同时将图片和用户id传递给后端。

修改后的效果如下:

element ui 人脸,Java,spring boot,vue.js,人工智能

 2.3 人脸注册按钮事件编写:

element ui 人脸,Java,spring boot,vue.js,人工智能

 当我们点击registerFace按钮,我们会打开摄像头,进行拍摄,然后将数据传递给后端。

element ui 人脸,Java,spring boot,vue.js,人工智能

主要代码如下:

    startCamera() { //打开摄像头
      const constraints = {
        video: {
          width: {exact: 400},
          height: {exact: 400},
        },
      };
      navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
        this.$refs.video.srcObject = stream;
        this.stream = stream;
      });
    },
    takePhoto() { //点击拍照
      const canvas = document.createElement("canvas");
      const video = this.$refs.video;
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
      this.photo = canvas.toDataURL("image/png");
    },
    beforeDestroy() { //关闭摄像头
      if (this.stream) {
        this.stream.getTracks().forEach((track) => {
          track.stop();
        });
      }
    },
    uploadPhoto() { 
      //封装参数
      const formData = new FormData();
      formData.append('base64img', this.photo); //图片的base64编码
      formData.append('userId', this.user.id);  //用户id
      // 向后端接口发送请求
      this.request.post("/user/login/face/register",formData).then((data) => {
        if (data) {
         this.$message.success("人脸注册成功")
          this.load() //初始化当前数据
          this.beforeDestroy()  //关闭摄像头
          this.dialogVisible1 = false; //关闭dia标签
        }
      })
    },

2.4   后端刷脸登陆的接口

完成人脸注册,将人脸信息和账户绑定之后,我们就可以进行刷脸登录了。

刷脸登录其实很简单,前端向后端传递拍摄到的图片64编码,后端收到图片的base64编码,然后调用人脸检测的接口,得到face_token,然后查询所有的登录用户,得到一个用户列表,遍历列表,拿到每一个用户的face_token,将它和前端传递过来的图片的face_token调用人脸比对的api进行比对,如果返回true,则说明当前登录的是这个用户。接下来就是生成token返回给前端。

下面是刷脸登录的后端接口:

    @PostMapping("/login/face")
    public Result loginFace(@RequestBody String base64img){
        //获取所有的登录用户
        List<User> list = userService.list();
        boolean isFace=false;
        String username=null;
        try {
            //获取前端传递的人脸的face_token
            String base64 = base64img.split(",")[1];
            String face_token = FaceUtils.getFaceTokenBase64img(base64);
            System.out.println("face_token ====================== " + face_token);
            //遍历所有的用户,对内一个用户的face_token进行比较
            for(User user:list) {
                String userFaceTokenfaceToken = user.getFaceToken();
                try {
                    //调用人脸比对的接口
                    if(userFaceTokenfaceToken!=null) {
                        boolean isEqu = FaceUtils.compareFace(face_token, userFaceTokenfaceToken);
                        //说明找到和人脸匹配的张账户,
                        if (isEqu) {
                            isFace = true;
                            username = user.getUsername(); //提取当前登录的用户
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //如果人脸比对成功,说明前端传递过来的人脸,是绑定了账户的,说明人脸验证成功
            //账户名称就是之前提取的username
            //接下来在if中,我们进行登录成功设置,比如生成token返回给前端,设置全局对象等。
            if(isFace){
                //根据用户名称获取到用户
                User user = userService.getOne(new QueryWrapper<User>().eq("username", username));
                // 设置token,编写你自己的登录成功,也就是账号密码验证成功之后的逻辑。
                //TODO
  
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("当前人脸没有绑定账户!请注册人脸后重试!");
    }

2.2   前端刷脸登录

在登录页面增加一个刷脸登录的按钮,点击这个按钮会打开摄像头,然后拍摄一张照片发送给后端登录接口。

关键代码如下(其实和人脸注册差不多):

element ui 人脸,Java,spring boot,vue.js,人工智能

            loginFace(){
                this.dialogVisible=true
                this.startCamera()
                //等待一秒钟进行拍照
                setTimeout(() => {
                    this.takePhoto()
                    const formData = new FormData();
                    formData.append('base64img', this.photo);
                    this.request.post("/user/login/face",formData).then(res=>{
                        console.log(res)
                        if (res.code === '200') {
                            //编写拿到后端返回的数据时的逻辑
                            //比如保存token,保存用户信息等。
    




                                this.$message.success("登录成功")
                                setRoutes()
                                if (res.data.role === 'CUSTOMER') {
                                    // 存储用户信息到浏览器
                                    this.$router.push("/MallHome");
                                } else {
                                    this.$router.push("/")
                                }
                            } else {
                                this.$message.error(res.msg)
                            }
                        })
                }, 1000); // 1000毫秒 = 1秒
            },
            startCamera() {
                const constraints = {
                    video: {
                        width: { exact: 400 },
                        height: { exact: 400 },
                    },
                };
                navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
                    this.$refs.video.srcObject = stream;
                    this.stream = stream;
                });
            },
            takePhoto() {
                const canvas = document.createElement("canvas");
                const video = this.$refs.video;
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
                this.photo = canvas.toDataURL("image/png");
            },
            beforeDestroy() {
                if (this.stream) {
                    this.stream.getTracks().forEach((track) => {
                        track.stop();
                    });
                }
            },

这样我们就实现了刷脸登录,以上内容仅供大家参考,主要的是思路。有问题的小伙伴欢迎在后台私信我。文章来源地址https://www.toymoban.com/news/detail-762169.html

到了这里,关于基于Face++,使用Spring Boot+Elemnet-UI实现人脸识别登录。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring boot +Vue + element-ui实现图片上传和回显

    对于图片上传和显示后台采用SpringBoot实现: 这里要特别注意的是:参数名称必须是 file, 必须是post方式! 前端Vue: 图片上传: 新增: 图片的显示:

    2024年02月13日
    浏览(41)
  • spring boot 配合element ui vue实现表格的批量删除(前后端详细教学,简单易懂,有手就行)

    目录 一.前言: 二. 前端代码: 2.1.element ui组件代码   2.2删除按钮 2.3.data 2.4.methods 三.后端代码: 研究了其他人的博客,找到了一篇有含金量的,进行了部分改写实现前后端分离,参考博主为小白Rachel 先看看页面效果,要是符合你们所需的功能那就继续看下去         1406

    2024年02月04日
    浏览(61)
  • Java之Spring Boot+Vue+Element UI前后端分离项目,前端插件化主流框架和实现原理

    三、设置Axios发起请求统一前缀的路径 https://code100.blog.csdn.net/article/details/123302546 1、HelloWorld.vue getInfo() { this.$http.get(‘blog/queryBlogByPage?title=’ + this.title + ‘page=’ + this.page + ‘rows=’ + this.rows) .then(response = ( this.info = response.data, this.total = this.info.total, this.totalPage = this.info.tota

    2024年04月16日
    浏览(55)
  • redis — 基于Spring Boot实现redis延迟队列

    1. 业务场景 延时队列场景在我们日常业务开发中经常遇到,它是一种特殊类型的消息队列,它允许把消息发送到队列中,但不立即投递给消费者,而是在一定时间后再将消息投递给消费者。延迟队列的常见使用场景有以下几种: 在各种购物平台上下单,订单超过30分钟未支付

    2024年02月13日
    浏览(33)
  • vue脚手架 element-ui spring boot 实现图片上传阿里云 并保存到数据库

    注册登陆就不讲了,登陆进去后如下操作,另外如果服务器进行了拦截过滤的操作的话记得放行。 1. 进入对象存储OSS 创建一个新的Bucket 随后点击新建的bucket 2.去访问RAM 前往RAM控制台 3.去创建用户  4.创建密匙 5.随后返回RAM控制台  给用户增加权限,文件上传所需权限,需要带

    2024年02月07日
    浏览(67)
  • Spring Boot中整合MyBatis(基于xml方式&基于注解实现方式)

    在Spring Boot中整合MyBatis时,你需要导入JDBC(不需要手动添加)、Druid的相关依赖、MySQL相关依赖。 JDBC依赖:在Spring Boot中整合MyBatis时,并不需要显式地添加JDBC的包依赖。这是因为,当你添加 mybatis-spring-boot-starter 依赖时,它已经包含了对JDBC的依赖。 mybatis-spring-boot-starter 是

    2024年02月15日
    浏览(44)
  • 基于Spring Boot的宠物领养系统的设计与实现

    目录 前言  一、技术栈 二、系统功能介绍 理员功能实现 宠物领养管理 宠物领养审核管理 宠物认领管理 宠物认领审核管理 教学视频管理 用户功能实现 宠物领养 宠物认领 教学视频 感谢信管理 三、核心代码 1、登录模块  2、文件上传模块 3、代码封装 如今社会上各行各业

    2024年01月16日
    浏览(36)
  • 基于Spring Boot的本科生就业质量设计与实现

    信息化爆炸的时代,互联网技术的指数型的增长,信息化程度的不断普及,社会节奏在加快,每天都有大量的信息扑面而来,人们正处于数字信息化世界。数字化的互联网具有便捷性,传递快,效率高,成本低等优点。 本课题拟设计的基于SpringBoot+Vue+ElementUI框架开发的本科生

    2024年02月08日
    浏览(29)
  • 基于Spring Boot的社区垃圾分类管理平台的设计与实现

    近些年来,随着科技的飞速发展,互联网的普及逐渐延伸到各行各业中,给人们生活带来了十分的便利,社区垃圾分类管理平台利用计算机网络实现信息化管理,使整个社区垃圾分类管理的发展和服务水平有显著提升。 本文拟采用Eclipse开发工具,JAVA语言,Spring Boot框架进行

    2024年03月19日
    浏览(47)
  • 基于Spring Boot的大学课程排课系统设计与实现

    大学课程排课是现代教育管理中重要的一环。目前,传统的排课方式已经无法满足日益增长的课程需求和学生个性化的诉求。因此,研究一种基于遗传算法的大学课程排课系统是非常必要的。本研究旨在开发一种基于SpringBoot Vue的大学课程排课系统,并运用遗传算法优化排课

    2024年02月07日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包