springboot+springSecurity+vue+百度云AI实现人脸登录(服务端)

一、实现思路

        根据前端落地页拍摄的面部头像进行登录,拿到图片第一步去后端请求校验,看抓取的照片是否有人脸,如果有,再进行第二步人脸比对,如果比对有结果,且相似度大于设置的分值,则认为比对成功,跳转到自己的系统。

二、服务端接口:

        1.人脸注册 既然要人脸登录,肯定系统中要存在登录人的人脸数据信息,如果没有,直接就无法登录。

   所以首先要人脸注册。

        2.人脸检测 如果上传的人脸照片没有头像信息,则无不对必要,直接登陆失败。

        3.人脸搜索 前端抓取的人脸和人脸库数据对比,获取比对结果

三、百度云配置获取相关参数

  1.注册并登录到百度云

        

2.选择人工智能-人脸识别功能

3.创建应用

4.拿到要连接的参数

 四、导入百度云AI的依赖

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

五、服务端接口开发

1. 工具类  这里只写了人脸注册,人脸检测,人脸搜索的工具类 业务直接调用即可

package com.dong.boot.utils;

import com.baidu.aip.face.AipFace;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.HashMap;

public class FaceRecognitionUtil {

    private  final static String APPID="24838072";
    private  final static String APIKEY ="l3tBYskoFx4sK3hK1yRqGijs";
    private  final static String SECRETKEY ="Q6f6UZVM5zb0TvHc1RSTaN3gOehpoUaH";
    private  final static String QUALITYCONTROL ="NORMAL";
    private  final static String LIVENESSCONTROL ="LOW";
    private  final static String IMAGETYPE="BASE64";
    private  final static String GROUPID="faceFirst";


    private  AipFace initAipFace(){
        //1创建和百度云AI的连接
        return new AipFace(APPID,APIKEY,SECRETKEY);
    }

    /**
     * @description 人脸注册
     * @params
     * @returns
     * @author Yadong Xu
     * @date 2021/9/12
     *
     */
    public  boolean faceRegister(String userId,String encode){
        AipFace aipFace = initAipFace();
        //人脸识别相关的配置
        HashMap<String,String> params = new HashMap<>();
        params.put("quality_control",QUALITYCONTROL);//图片质量控制NONE: 不进行控制LOW:较低的质量要求NORMAL: 一般的质量要求HIGH: 较高的质量要求默认 NONE 若图片质量不满足要求,则返回结果中会提示质量检测失败
        params.put("liveness_control",LIVENESSCONTROL);//活体检测控制NONE: 不进行控制LOW:较低的活体要求(高通过率 低攻击拒绝率)NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率)HIGH: 较高的活体要求(高攻击拒绝率 低通过率)默认NONE若活体检测结果不满足要求,则返回结果中会提示活体检测失败
        //准备注册到人脸库的图片 百度云接收两种格式的图片 一个是url地址 一个是base64的字符串
        // encode 人脸数据字符串 BASE64类型  照片组 faceFirst userId 20210912001 自定义的 params设置注册时的参数
        JSONObject jsonObject = aipFace.addUser(encode, IMAGETYPE, GROUPID, userId, params);
        //人脸注册的返回信息:{"result":{"face_token":"c175093d999f61bd6053853764eaa167",
        // "location":{"top":353.46,"left":130.81,"rotation":-24,"width":507,"height":499}},
        // "log_id":12555552010,"error_msg":"SUCCESS","cached":0,"error_code":0,"timestamp":1631450788}
        if ((Integer) jsonObject.get("error_code") == 0){
            return true;
        }
        return false;
    }

    /**
     * @description 人脸校验
     * @params 
     * @returns 
     * @author Yadong Xu
     * @date 2021/9/12 
     * 
     */
    public  boolean  faceCheck(String encode) {
        AipFace aipFace = initAipFace();
        JSONObject res = aipFace.detect(encode, IMAGETYPE, null);
        //人脸校验的返回信息{"result":{"face_num":1,"face_list":[{"angle":{"roll":-26.42,"pitch":1.82,"yaw":8.25},
        // "face_token":"c175093d999f61bd6053853764eaa167","location":{"top":353.46,"left":130.81,"rotation":-24,"width":507,"height":499},
        // "face_probability":1}]},"log_id":1012535998455,"error_msg":"SUCCESS","cached":0,"error_code":0,"timestamp":1631451053}
        if ((Integer) res.get("error_code") == 0){
            return true;
        }
        return false;
    }

    /**
     * @description 人脸搜索
     * @params
     * @returns
     * @author Yadong Xu
     * @date 2021/9/12
     *
     */
   public  String faceSearch(String encode){
        AipFace aipFace = initAipFace();
        JSONObject search = aipFace.search(encode, IMAGETYPE, GROUPID, null);
        //人脸搜索返回的信息{"result":{"face_token":"c175093d999f61bd6053853764eaa167",
        // "user_list":[{"score":100,"group_id":"faceFirst","user_id":"20210912003","user_info":""}]},
        // "log_id":4575751012575,"error_msg":"SUCCESS","cached":0,"error_code":0,"timestamp":1631451384}
        JSONArray array = (JSONArray) search.get("user_list");
        JSONObject user = (JSONObject) array.get(0);
        Double score = (Double) user.get("score");
        if (score>80){
            return user.getString("user_id");
        }
        return null;
    }
}

 2.controller层调用

package com.dong.boot.controller.face;

import com.baidu.aip.util.Base64Util;
import com.dong.boot.model.RespBean;
import com.dong.boot.utils.FaceRecognitionUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
public class FaceRecognitionController {

    @PostMapping("/face/register")
    public RespBean  register(@RequestParam("file") MultipartFile file,@RequestParam("userId")String userId){
        //把图片保存到本地
        try {
            file.transferTo(new File("D:\\img\\"+file.getOriginalFilename()));
            String encode = Base64Util.encode(file.getBytes());
            if (FaceRecognitionUtil.faceRegister(userId,encode)){
                return RespBean.ok("文件注册成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return RespBean.ok("文件注册失败");
        }
        return RespBean.ok("文件注册失败");
    }


    @PostMapping("/face/search")
    public RespBean search(@RequestParam("file") MultipartFile file){
        try {
            String encode = Base64Util.encode(file.getBytes());
            String userId = FaceRecognitionUtil.faceSearch(encode);
            if (StringUtils.isNotBlack(userId)){
//模拟自动登录
                 Hr hr = hrService.selectCurrentHr(Integer.parseInt(search));
                Hr hr1 = hrService.loadUserByUsername(hr.getUsername());
                SecurityContext context = SecurityContextHolder.getContext();
                List<SimpleGrantedAuthority> authorities = new ArrayList<> 
                 (hr1.getRoles().size());
                for (Role role : hr1.getRoles()) {
                    authorities.add(new SimpleGrantedAuthority(role.getName()));
                }
                context.setAuthentication(new 
                  
                UsernamePasswordAuthenticationToken(hr1,hr1.getPassword(),authorities));
                req.getSession().setAttribute("SPRING_SECURITY_CONTEXT",context);
                return RespBean.error("人脸对比成功",userService.selectUserById(userId));
            }
            return RespBean.error("人脸对比失败");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return RespBean.error("人脸对比失败");
    }

    @PostMapping("/face/check")
    public RespBean check(@RequestParam("file") MultipartFile file){
        try {
            String encode = Base64Util.encode(file.getBytes());
            boolean check = FaceRecognitionUtil.faceCheck(encode);
            if (!check){
                return RespBean.error("人脸检测失败");
            }
            return RespBean.ok("人脸检测成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return RespBean.ok("人脸检测失败");
    }
}

3.SpringSecurity会对所有请求路径拦截,所有要设置白名单放行

@Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/login","/verify","/face/**");
    }

  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值