Springboot整合百度人脸识别功能实现注册和登录
时间:2024-05-03 08:20:48 来源:网络cs 作者:焦糖 栏目:运营工具 阅读:
该类主要是负责把前端传回来的MultipartFile类型的人脸识别图片文件转换为百度AI需要的base64格式
package com.baidu.util;import org.springframework.web.multipart.MultipartFile;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.Base64;/** * Base64 工具类 */public class Base64Util { private static final char last2byte = (char) Integer.parseInt("00000011", 2); private static final char last4byte = (char) Integer.parseInt("00001111", 2); private static final char last6byte = (char) Integer.parseInt("00111111", 2); private static final char lead6byte = (char) Integer.parseInt("11111100", 2); private static final char lead4byte = (char) Integer.parseInt("11110000", 2); private static final char lead2byte = (char) Integer.parseInt("11000000", 2); private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; public Base64Util() { } public static String multipartFileToBase64(MultipartFile file) throws IOException { InputStream inputStream = file.getInputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); int bytesRead; int bufferSize = 10 * 1024 * 1024; byte[] buffer = new byte[bufferSize]; // 可以根据需要调整缓冲区大小 while ((bytesRead = inputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, bytesRead); } byte[] bytes = byteArrayOutputStream.toByteArray(); String base64String = Base64.getEncoder().encodeToString(bytes); // 不需要显式关闭 inputStream,因为 MultipartFile 的实现会负责关闭它 // byteArrayOutputStream.close(); // 如果需要,可以在这里关闭 ByteArrayOutputStream return base64String; } public static String encode(byte[] from) { StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3); int num = 0; char currentByte = 0; int i; for (i = 0; i < from.length; ++i) { for (num %= 8; num < 8; num += 6) { switch (num) { case 0: currentByte = (char) (from[i] & lead6byte); currentByte = (char) (currentByte >>> 2); case 1: case 3: case 5: default: break; case 2: currentByte = (char) (from[i] & last6byte); break; case 4: currentByte = (char) (from[i] & last4byte); currentByte = (char) (currentByte << 2); if (i + 1 < from.length) { currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6); } break; case 6: currentByte = (char) (from[i] & last2byte); currentByte = (char) (currentByte << 4); if (i + 1 < from.length) { currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4); } } to.append(encodeTable[currentByte]); } } if (to.length() % 4 != 0) { for (i = 4 - to.length() % 4; i > 0; --i) { to.append("="); } } return to.toString(); }}
创建CodeCompents
package com.baidu.compents;public class CodeCompents { public final static String baidu_ai_imageType = "BASE64"; public final static String baidu_ai_groupId = "groupId";}
创建UserBaiduAIController
登录接口需要传入用户名(账号)和登录时的图片然后获取数据库中注册的人脸识别照片的URL传到百度AI进行比对,如果数据库中没有该用户的人脸识别照片的URL则为该用户没有注册人脸识别,直接返回请先注册人脸识别
注册接口需要传入用户名(账号)和注册的人脸图片,然后将人脸识别的照片上传到阿里云的OSS服务器并获取保存的URL,然后将URL给到用户类里对应的属性中,再调用修改方法对数据库中的信息修改将注册的人脸识别图片URL保存到数据库中
package com.baidu.controller;import com.baidu.aip.face.AipFace;import com.baidu.aip.face.MatchRequest;import com.baidu.compents.CodeCompents;import com.baidu.config.BaiduAiConfig;import com.baidu.pojo.UserBaiduai;import com.baidu.service.UserBaiduAIService;import com.baidu.util.Base64Util;import com.baidu.util.OssUtil;import org.apache.commons.lang3.ObjectUtils;import org.json.JSONException;import org.json.JSONObject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;@RestController@RequestMapping("/baiduAI")public class UserBaiduAIController { @Autowired private UserBaiduAIService userBaiduAIService; /** * 账号+人脸校验 * @param userName * @param file * @throws Exception */ @PostMapping("/loginBaiduAi") public void loginBaiduAi(String userName, MultipartFile file) throws Exception { // 传入appId、apiKey、secretkey。创建Java代码和百度云交互的Client对象 AipFace client = new AipFace(BaiduAiConfig.AppId, BaiduAiConfig.AK, BaiduAiConfig.SK); // 登录图片 // MultipartFile类型转换Base64字符串格式 String loginImageBase64 = Base64Util.multipartFileToBase64(file); // 根据用户名获取用户信息 UserBaiduai one = userBaiduAIService.findByName(userName); /* 判断该用户是否注册了人脸 如果没有注册则不进行校验 如果注册了则进行校验 */ if (!ObjectUtils.isEmpty(one.getPhoto())){ // 用户注册的人脸的照片存储路径 String comparedImageUrl = one.getPhoto(); /* 传入参数进行校验 返回值为两张照片的相似度 */ Double faceComparison = faceComparison(client, loginImageBase64, comparedImageUrl); if (faceComparison > 85) { System.out.println(one.getUsername()); System.out.println("人脸识别登录成功"); } else { System.out.println("人脸识别登录失败"); } }else { System.out.println("请先录入人脸信息"); } } @PostMapping("registerBaiduAi") public void registerBaiduAi(String userName,MultipartFile file) throws IOException, JSONException { // 传入appId、apiKey、secretkey。创建Java代码和百度云交互的Client对象 AipFace client = new AipFace(BaiduAiConfig.AppId, BaiduAiConfig.AK, BaiduAiConfig.SK); // 根据用户名获取用户信息 UserBaiduai one = userBaiduAIService.findByName(userName); // 判断用户是否注册过人脸识别 if(!ObjectUtils.isEmpty(one.getPhoto())){ // 如果有则先删除原来注册的人脸照片 // 假设图片URL是https://canghai0190.oss-cn-beijing.aliyuncs.com/img/1714270552688.png // 那么我们要截取com/后面的文件路径名称传入方法进行删除 int index = one.getPhoto().indexOf("com/"); String fileName = null; if (index != -1) { fileName = one.getPhoto().substring(index + 4); // 截取 "com/" 后面的内容 } else { fileName = ""; } System.out.println(fileName); OssUtil.deleteFileToOss(fileName); } // MultipartFile类型转换Base64字符串格式 String registerImageBase64 = Base64Util.multipartFileToBase64(file); // 传入可选参数调用接口 HashMap<String, String> options = new HashMap<String, String>(); options.put("user_info", "user's info"); options.put("quality_control", "NORMAL"); options.put("liveness_control", "LOW"); options.put("action_type", "REPLACE"); /* 调用api方法完成人脸注册 image 图片的url或者base64字符串 imageType 图片形式(URL,BASE64) groupId 组Id(固定一个字符串) userId 用户Id options hashMap基本参数配置 */ JSONObject res = client.addUser(registerImageBase64, CodeCompents.baidu_ai_imageType, CodeCompents.baidu_ai_groupId, String.valueOf(userName), options); if (res.getInt("error_code")==0){ //上传人脸识别图片到oss String url = OssUtil.uploadFileToOss(file); //将人脸识别信息和用户信息绑定存入数据库 UserBaiduai userBaiduai = userBaiduAIService.findByName(userName); userBaiduai.setPhoto(url); userBaiduAIService.update(userBaiduai); //更新redis中的用户信息// updateUser(hmsUser); System.out.println("人脸注册成功"); }else { System.out.println("人脸注册失败"); } System.out.println(res.toString(2)); } static Double faceComparison(AipFace client, String loginImageBase64, String comparedImageUrl) throws Exception { // 将图片的URL传递给百度API MatchRequest req2 = new MatchRequest(comparedImageUrl, "URL"); // 将前端传过来的图片传递给百度API MatchRequest req1 = new MatchRequest(loginImageBase64, CodeCompents.baidu_ai_imageType); // 讲MatchRequest信息存入list集合中 ArrayList<MatchRequest> requests = new ArrayList<>(); requests.add(req1); requests.add(req2); // 进行人脸比对 返回值是json串 JSONObject match = client.match(requests); System.out.println(match.toString(2)); // 返回两张照片的相似度 return match.getJSONObject("result").getDouble("score"); }}
测试
由于本人vue会的是在不多所以前端没有写出来,想要页面的请参考我最上面放的CodeDevMaster大佬的链接,教程最后面有vue前端的教程
为了测试我这边就使用Postman进行测试
需要的参数有
params中userName参数
body中名为file的file类型的一个照片文件
注册接口的测试结果
登录接口的测试结果
登录接口人脸正确的结果
登录接口人脸识别的接口
怎么判断两张照片是否为同一个人?
大家应该可以看到我上面两次测试都用红框框起来的score这个值,这个值的意思是传入百度AI的登录的人脸照片和数据库中注册的人脸照片的匹配值,匹配值越高则大概率是同一个人,匹配值越低则说明越不可能是同一个人,然后我们只需要根据这个值进行判断即可,一半是相似度大于等于85即可判断为同一个人,小于85则判断为不是同一个人
返回的JSON中各个属性是什么意思?
score人脸相似度得分face_list 人脸信息列表face_token人脸的唯一标志log_id是请求标识码,随机数,唯一location是人脸在图片中的位置 error_code错误码error_msg误描述信息,帮助理解和解决发生的错误
本文链接:https://www.kjpai.cn/news/2024-05-03/164397.html,文章来源:网络cs,作者:焦糖,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!
上一篇:Android 样式小结
下一篇:返回列表