700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 百度AI实现Web端人脸识别登陆-Springboot-Vue/element-ui

百度AI实现Web端人脸识别登陆-Springboot-Vue/element-ui

时间:2019-06-13 05:30:11

相关推荐

百度AI实现Web端人脸识别登陆-Springboot-Vue/element-ui

3.8 人脸识别登陆Controller

1、效果图

后台获取的数据

{"face_token":"efb5996c1707850f81e884ef190c984b","user_list":[{"score":91.080505371094,"group_id":"group1","user_id":"1","user_info":""}]}

2、注册百度ai

百度ai地址https://login./?redirect=https%3A%2F%2Fconsole.%2F%3Ffromai%3D1#/aip/overviewhttps://login./?redirect=https%3A%2F%2Fconsole.%2F%3Ffromai%3D1#/aip/overview

2.1 、使用免费百度ai步骤

1、点击人脸识别:跳转到服务

2、其间会有一些验证,创建应用

3、查看人脸库

4、新建组、用户

5、添加人脸照片

3、代码实现逻辑

基于Springboot框架搭建的,前端使用Vue,通过摄像机拍下照片后,请求后端人脸识别登陆服务,后台调用百度API人脸识别接口,进入百度大脑搜索人脸识别即可获取官网的Secret Key,将前端获取的人脸信息的base64信息和你本地数据库里的人脸信息传到百度人脸识别的接口进行人脸比对,返回一个json数据,result参数 带别人脸相似度, result可自己定义,从而实现人脸识别登录。

核心代码块

3.1、导入Maven依赖

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

3.2、创建FaceUtil,获取ApiFace【单例】

package mon.utils.face.utils;import com.baidu.aip.face.AipFace;import com.baidu.aip.util.Base64Util;/*** 人脸识别工具*/public class FaceUtil {private static final String APP_ID = "25236971";private static final String APP_KEY = "zLIZGY15wiEQh2utjwAGGW9C";private static final String SECRET_KEY = "Pzi4Ew6eWfZPINBkshlCO22OqADa777I";private static volatile AipFace client = new AipFace(APP_ID, APP_KEY, SECRET_KEY);// 创建单例避免多次获取sdkpublic static AipFace getClient(){client.setConnectionTimeoutInMillis(2000);client.setSocketTimeoutInMillis(60000);return client;}/*** 编码* @param form* @return*/public static String encodeBase64(byte[] form){return Base64Util.encode(form);}/*** 解码* @param data* @return*/public static byte[] decodeBase64(String data){return Base64Util.decode(data);}}

3.3 创建FaceResultUtil,统一处理请求

package mon.utils.face.utils;import mon.utils.face.BizException;import mon.utils.face.constant.ErrorEnum;import mon.utils.face.constant.FaceConstant;import mon.utils.face.dto.FaceResult;import org.json.JSONObject;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/*** 结果工具封装*/public class FaceResultUtil {private static final Logger logger = LoggerFactory.getLogger("百度API接口请求结果解析");public static FaceResult isSuccess(JSONObject res){FaceResult result = parseJsonObject(res);if (!result.isSuccess()){// 对错误进行分类ErrorEnum errorEnum = ErrorEnum.getInstance(result.getErrorCode());if (errorEnum == null){throw new BizException("百度接口请求失败" + result.getErrorMsg());}else {throw new BizException(errorEnum.getCnDesc());}}return result;}/*** 解析JsonObject* @return*/private static FaceResult parseJsonObject(JSONObject res){FaceResult faceResult = FaceResult.builder().build();try {String logId = res.has(FaceConstant.LOG_ID) ? res.get(FaceConstant.LOG_ID).toString() : "0";int errorCode = res.has(FaceConstant.ERROR_CODE) ? res.getInt(FaceConstant.ERROR_CODE) : -1;String errorMsg = res.has(FaceConstant.ERROR_MSG) ? res.getString(FaceConstant.ERROR_MSG) : "";int cached = res.has(FaceConstant.CACHED) ? res.getInt(FaceConstant.CACHED) : 0;long timestamp = res.has(FaceConstant.TIMESTAMP) ? res.getLong(FaceConstant.TIMESTAMP) : 0;Object dataString = res.has(FaceConstant.RESULT) ? res.get(FaceConstant.RESULT) : "";com.alibaba.fastjson.JSONObject data = null;if (dataString != null) {data = com.alibaba.fastjson.JSONObject.parseObject(dataString.toString());}faceResult.setLogId(logId);faceResult.setErrorCode(errorCode);faceResult.setErrorMsg(errorMsg);faceResult.setCached(cached);faceResult.setTimestamp(timestamp);faceResult.setData(data);}catch (Exception e){logger.error("JSONObject解析失败", e);}return faceResult;}}

3.4 创建FaceResult

package mon.utils.face.dto;import com.alibaba.fastjson.JSONObject;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;/***请求百度API接口结果*/@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic class FaceResult implements Serializable {private String logId;private String errorMsg;private int cached;private int errorCode;private long timestamp;private JSONObject data;public boolean isSuccess(){return 0 == this.errorCode ? true : false;}}

3.5 创建ImageU

package mon.utils.face.dto;import mon.utils.face.constant.ImageTypeEnum;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;/*** 图像对象*/@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic class ImageU implements Serializable {private ImageTypeEnum imageTypeEnum;private String data;}

3.6 创建FaceUserDTO

package mon.utils.face.dto;import mon.utils.face.constant.FaceConstant;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic class FaceUserDTO<T> implements Serializable {private String userId;private String groupId = FaceConstant.DEFAULT_GROUP_ID;private String faceToken;private T user;}

3.7 创建FaceManage[关键类](重点)

package mon.utils.face;import com.alibaba.fastjson.JSON;import com.baidu.aip.face.FaceVerifyRequest;import com.baidu.aip.face.MatchRequest;import mon.utils.face.constant.ActionTypeEnum;import mon.utils.face.constant.FaceConstant;import mon.utils.face.constant.LivenessControlEnum;import mon.utils.face.constant.QualityControlEnum;import mon.utils.face.dto.FaceResult;import mon.utils.face.dto.FaceUserDTO;import mon.utils.face.dto.ImageU;import mon.utils.face.utils.FaceResultUtil;import mon.utils.face.utils.FaceUtil;import org.json.JSONObject;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.ArrayList;import java.util.HashMap;import java.util.Objects;/*** 人脸识别相关服务*/public class FaceManage {private static final Logger logger = LoggerFactory.getLogger(FaceManage.class);/*** 人脸注册*/public static void faceRegister(FaceUserDTO userDTO, ImageU imageU){// 传入可选参数调用接口HashMap<String, String> options = new HashMap<String, String>();// 用户资料options.put("user_info", JSON.toJSONString(userDTO));// 图片质量options.put("quality_control", QualityControlEnum.LOW.name());// 活体检测控制options.put("liveness_control", LivenessControlEnum.NONE.name());// 操作方式options.put("action_type", ActionTypeEnum.REPLACE.name());String image = imageU.getData();String imageType = imageU.getImageTypeEnum().name();String groupId = userDTO.getGroupId();String userId = userDTO.getUserId();// 人脸注册JSONObject res = FaceUtil.getClient().addUser(image, imageType, groupId, userId, options);FaceResultUtil.isSuccess(res);logger.info("人脸注册成功");}/*** 人脸更新*/public static void faceUpdate(FaceUserDTO userDTO, ImageU imageU) {HashMap<String, String> options = new HashMap<String, String>();// 用户资料options.put("user_info", JSON.toJSONString(userDTO));// 图片质量options.put("quality_control", QualityControlEnum.LOW.name());// 活体检测控制options.put("liveness_control", LivenessControlEnum.NONE.name());// 操作方式options.put("action_type", ActionTypeEnum.REPLACE.name());String image = imageU.getData();String imageType = imageU.getImageTypeEnum().name();String groupId = userDTO.getGroupId();String userId = userDTO.getUserId();// 人脸更新JSONObject res = FaceUtil.getClient().updateUser(image, imageType, groupId, userId, options);FaceResultUtil.isSuccess(res);logger.info("人脸更新成功 {}", res.toString(2));}/*** 人脸删除*/public static void faceDelete(String userId, String groupId, String faceToken) {// 传入可选参数调用接口HashMap<String, String> options = new HashMap<String, String>();// 人脸删除JSONObject res = FaceUtil.getClient().faceDelete(userId, groupId, faceToken, options);FaceResultUtil.isSuccess(res);logger.info("人脸删除成功 {}", res.toString(2));}/*** 用户信息查询*/public static FaceUserDTO<String> findUser(String userId, String groupId) {HashMap<String, String> options = new HashMap<>();// 用户信息查询JSONObject res = FaceUtil.getClient().getUser(userId, groupId, options);FaceResult result = FaceResultUtil.isSuccess(res);return JSON.parseObject(result.getData().toJSONString(), FaceUserDTO.class);}/*** 获取用户人脸列表* @throws Exception*/public static FaceResult faceGetList(String userId, String groupId){HashMap<String, String> options = new HashMap<String, String>();// 获取用户人脸列表JSONObject res = FaceUtil.getClient().faceGetlist(userId, groupId, options);return FaceResultUtil.isSuccess(res);}/*** 获取用户列表*/public static FaceResult listUserByGroupId(String groupId) {HashMap<String, String> options = new HashMap<String, String>();options.put("start", "0");options.put("length", "50");// 获取用户列表JSONObject res = FaceUtil.getClient().getGroupUsers(groupId, options);return FaceResultUtil.isSuccess(res);}/*** 删除用户*/public static void deleteUser(String userId, String groupId) {HashMap<String, String> options = new HashMap<String, String>();// 删除用户JSONObject res = FaceUtil.getClient().deleteUser(groupId, userId, options);FaceResultUtil.isSuccess(res);logger.info("用户删除成功 {}", res.toString(2));}/*** 创建用户组*/public static void addGroup(String groupId) {HashMap<String, String> options = new HashMap<String, String>();// 创建用户组JSONObject res = FaceUtil.getClient().groupAdd(groupId, options);FaceResultUtil.isSuccess(res);logger.info("创建用户组 {}", res.toString(2));}/*** 删除用户组*/public static void deleteGroup(String groupId){HashMap<String, String> options = new HashMap<String, String>();// 删除用户组JSONObject res = FaceUtil.getClient().groupDelete(groupId, options);FaceResultUtil.isSuccess(res);logger.info("删除用户组 {}", res.toString(2));}/*** 组列表查询*/public static FaceResult listGroup() {HashMap<String, String> options = new HashMap<String, String>();options.put("start", "0");options.put("length", "50");// 组列表查询JSONObject res = FaceUtil.getClient().getGroupList(options);return FaceResultUtil.isSuccess(res);}/*** 身份验证(没权限使用)*/public static FaceResult personVerify(String idCardNumber, String realName, ImageU imageU){HashMap<String, String> options = new HashMap<String, String>();options.put("quality_control", QualityControlEnum.LOW.name());options.put("liveness_control", LivenessControlEnum.NONE.name());// 身份验证JSONObject res = FaceUtil.getClient().personVerify(imageU.getData(), imageU.getImageTypeEnum().name(), idCardNumber, realName, options);return FaceResultUtil.isSuccess(res);}/*** 人脸对比*/public static int faceMatchScore(ImageU imageU1, ImageU imageU2){MatchRequest req1 = new MatchRequest(imageU1.getData(), imageU1.getImageTypeEnum().name());MatchRequest req2 = new MatchRequest(imageU2.getData(), imageU2.getImageTypeEnum().name());ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();requests.add(req1);requests.add(req2);JSONObject res = FaceUtil.getClient().match(requests);FaceResult result = FaceResultUtil.isSuccess(res);// 对结果进行特殊处理Integer score = result.getData().getInteger(FaceConstant.SCORE);return score == null ? 0 : score;}/*** 人脸是否对比成功* @param imageU1* @param imageU2* @param score 匹配分数* @return*/public static boolean isfaceMatch(ImageU imageU1, ImageU imageU2, Integer score){int defaultScore = FaceConstant.MATCH_SCORE;if (Objects.nonNull(score)){defaultScore = score;}return faceMatchScore(imageU1, imageU2) > defaultScore ? true : false;}/*** 人脸检测*/public static FaceResult faceDetect(ImageU imageU) {HashMap<String, String> options = new HashMap<String, String>();options.put("face_field", "age");options.put("max_face_num", "2");options.put("face_type", "LIVE");// 人脸检测JSONObject res = FaceUtil.getClient().detect(imageU.getData(), imageU.getImageTypeEnum().name(), options);return FaceResultUtil.isSuccess(res);}/*** 人脸搜索*/public static FaceResult faceSearch(String groupIds, ImageU imageU) {HashMap<String, String> options = new HashMap<String, String>();options.put("max_face_num", "1");options.put("max_user_num", "1");options.put("quality_control", QualityControlEnum.LOW.name());options.put("liveness_control", LivenessControlEnum.NONE.name());// 人脸搜索JSONObject res = FaceUtil.getClient().search(imageU.getData(), imageU.getImageTypeEnum().name(), groupIds, options);return FaceResultUtil.isSuccess(res);}/*** 活体检测*/public static FaceResult faceverify(ImageU imageU) {FaceVerifyRequest req = new FaceVerifyRequest(imageU.getData(), imageU.getImageTypeEnum().name());ArrayList<FaceVerifyRequest> list = new ArrayList<FaceVerifyRequest>();list.add(req);JSONObject res = FaceUtil.getClient().faceverify(list);return FaceResultUtil.isSuccess(res);}}

3.8、测试

package mon.utils.face;import com.alibaba.fastjson.JSON;import mon.face.FaceManage;import mon.face.constant.FaceConstant;import mon.face.constant.ImageTypeEnum;import mon.face.dto.FaceResult;import mon.face.dto.FaceUserDTO;import mon.face.dto.ImageU;import mon.face.utils.FaceUtil;import mon.utils.FilesUtil;import mons.io.IOUtils;import org.junit.Test;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.util.HashMap;/*** User: lanxinghua* Date: /8/29 20:17* Desc: 人脸识别测试*/public class FaceIdentificationTest {/*** 人脸注册,导入数据100张人脸图片*/@Testpublic void test00() throws Exception{FaceUserDTO<String> userDTO = new FaceUserDTO<>();userDTO.setGroupId("group2");String filePath = "/Users/cxx/Downloads/entryPhoto/";File[] files = FilesUtil.listFile(filePath);int j = 0;for (File file : files) {int id = 7000 + j;j++;userDTO.setUserId(String.valueOf(id));InputStream is = new FileInputStream(new File(filePath + file.getName()));byte[] bytes = IOUtils.toByteArray(is);String data = FaceUtil.encodeBase64(bytes);ImageU imageU = ImageU.builder().data(data).imageTypeEnum(ImageTypeEnum.BASE64).build();userDTO.setUser("用户信息 group1 - " + id);try {FaceManage.faceRegister(userDTO, imageU);}catch (Exception e){System.out.println("注册失败 msg:" + e.getMessage());continue;}}}/*** 人脸注册*/@Testpublic void test01() {FaceUserDTO<String> userDTO = new FaceUserDTO<>();userDTO.setGroupId("group1");userDTO.setUserId("6031");String image = "/mis/permanent/img2.jpg";ImageU imageU = ImageU.builder().data(image).imageTypeEnum(ImageTypeEnum.URL).build();userDTO.setUser("用户信息1");FaceManage.faceRegister(userDTO, imageU);}/*** 人脸更新*/@Testpublic void test02() {FaceUserDTO<String> userDTO = new FaceUserDTO();userDTO.setGroupId("group1");userDTO.setUserId("6031");String image = "/mis/permanent/img2.jpg";ImageU imageU = ImageU.builder().data(image).imageTypeEnum(ImageTypeEnum.URL).build();userDTO.setUser("用户信息1");// 人脸更新FaceManage.faceUpdate(userDTO, imageU);}/*** 人脸删除接口*/@Testpublic void test03() {String userId = "6030";String groupId = "group1";String faceToken = "5a1a8c17c40ea41264e8830017134972";FaceManage.faceDelete(userId, groupId, faceToken);}/*** 用户信息查询*/@Testpublic void test04() {HashMap<String, String> options = new HashMap<>();String userId = "6030";String groupId = "group1";// 用户信息查询FaceUserDTO<String> userDTO = FaceManage.findUser(userId, groupId);System.out.println("用户信息:" + JSON.toJSONString(userDTO));}/*** 获取用户人脸列表*/@Testpublic void test05() {String userId = "6030";String groupId = "group1";// 获取用户人脸列表FaceResult result = FaceManage.faceGetList(userId, groupId);String data = result.getData().getString(FaceConstant.FACE_LIST);System.out.println("人脸列表"+data);}/*** 获取用户列表*/@Testpublic void test06() {String groupId = "group1";FaceResult result = FaceManage.listUserByGroupId(groupId);// 获取用户列表String userIds = result.getData().getString(FaceConstant.USER_ID_LIST);System.out.println("userIds" + userIds);}/*** 删除用户*/@Testpublic void test07() {HashMap<String, String> options = new HashMap<String, String>();String groupId = "group1";String userId = "6031";// 删除用户FaceManage.deleteUser(userId, groupId);}/*** 创建用户组*/@Testpublic void test08() {String groupId = "group2";FaceManage.addGroup(groupId);}/*** 删除用户组*/@Testpublic void test09() {String groupId = "group2";FaceManage.deleteGroup(groupId);}/*** 组列表查询*/@Testpublic void test10() {FaceResult result = FaceManage.listGroup();String groupIds = result.getData().getString(FaceConstant.GROUP_ID_LIST);System.out.println(groupIds);}/*** 身份验证(没权限使用)*/@Testpublic void test11() {String image = "/mis/permanent/img1.jpg";ImageU imageU = ImageU.builder().data(image).imageTypeEnum(ImageTypeEnum.URL).build();String idCardNumber = "235151251";String name = "陈星星";FaceManage.personVerify(idCardNumber, name, imageU);}/*** 人脸对比*/@Testpublic void test12() {String image1 = "/mis/permanent/img1.jpg";String image2 = "/mis/permanent/img2.jpg";ImageU imageU1 = ImageU.builder().data(image1).imageTypeEnum(ImageTypeEnum.URL).build();ImageU imageU2 = ImageU.builder().data(image2).imageTypeEnum(ImageTypeEnum.URL).build();boolean match = FaceManage.isfaceMatch(imageU2, imageU1, 80);int matchScore = FaceManage.faceMatchScore(imageU2, imageU1);System.out.println("是否匹配:" + match);System.out.println("匹配等分:" + matchScore);}/*** 人脸检测*/@Testpublic void test13() {String image = "/mis/permanent/img1.jpg";ImageU imageU = ImageU.builder().data(image).imageTypeEnum(ImageTypeEnum.URL).build();FaceResult result = FaceManage.faceDetect(imageU);String data = result.getData().getString(FaceConstant.FACE_LIST);System.out.println(data);}/*** 人脸搜索*/@Testpublic void test14() {String image = "/mis/permanent/img1.jpg";ImageU imageU = ImageU.builder().data(image).imageTypeEnum(ImageTypeEnum.URL).build();String groupIds = "group1,group2";FaceResult result = FaceManage.faceSearch(groupIds, imageU);String users = result.getData().getString(FaceConstant.USER_LIST);System.out.println(users);}/*** 活体检测*/@Testpublic void test15() {String image = "/mis/permanent/img1.jpg";ImageU imageU = ImageU.builder().data(image).imageTypeEnum(ImageTypeEnum.URL).build();FaceResult result = FaceManage.faceverify(imageU);String users = result.getData().toJSONString();System.out.println(users);}}

3.9人脸识别登陆Controller

/*** 人脸登录*/@PostMapping( "/facelogin")@ResponseBodypublic AjaxResult facelogin(@RequestParam("file") String file,@RequestParam("groupId") String groupId) throws Exception {/*** base64转为multipartFile*/MultipartFile multipartFile = Base64DecodeMultipartFile.base64Convert(file);//很长if (multipartFile.isEmpty()) {throw new BizException("上传文件不能为空");}String groupIds = "group1";String data = FaceUtil.encodeBase64(multipartFile.getBytes());ImageU imageU = ImageU.builder().data(data).imageTypeEnum(ImageTypeEnum.BASE64).build();FaceResult result = FaceManage.faceSearch(groupIds, imageU);String users = result.getData().getString(FaceConstant.USER_LIST);if (StringUtils.isEmpty(users)){return AjaxResult.error("用户不存在");}JSONArray array = JSONObject.parseArray(users);JSONObject object = JSONObject.parseObject(array.get(0).toString());Integer score = object.getInteger(FaceConstant.SCORE);if (score == null){return AjaxResult.error("登录失败");}if (score >= FaceConstant.MATCH_SCORE){System.out.println(result.getData().toString());Long user_id = object.getLong("user_id");SysUser sysUser = sysUserService.selectUserById(user_id);/* 认证用户方法,可以自己写 */AjaxResult ajax = loginService.login(0,sysUser.getUserName());return ajax;}return AjaxResult.error("用户不存在");}

3.10 枚举,用到的一些辅助类

package mon.utils.face;import org.springframework.web.multipart.MultipartFile;import sun.misc.BASE64Decoder;import java.io.*;import java.util.UUID;/*** base64转为multipartFile工具类* base64Convert*/public class Base64DecodeMultipartFile implements MultipartFile {private final byte[] imgContent;private final String header;public Base64DecodeMultipartFile(byte[] imgContent, String header) {this.imgContent = imgContent;this.header = header.split(";")[0];}@Overridepublic String getName() {return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];}@Overridepublic String getOriginalFilename() {return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];}@Overridepublic String getContentType() {return header.split(":")[1];}@Overridepublic boolean isEmpty() {return imgContent == null || imgContent.length == 0;}@Overridepublic long getSize() {return imgContent.length;}@Overridepublic byte[] getBytes() throws IOException {return imgContent;}@Overridepublic InputStream getInputStream() throws IOException {return new ByteArrayInputStream(imgContent);}@Overridepublic void transferTo(File dest) throws IOException, IllegalStateException {new FileOutputStream(dest).write(imgContent);}/*** base64转multipartFile** @param base64* @return*/public static MultipartFile base64Convert(String base64) {String[] baseStrs = base64.split(",");BASE64Decoder decoder = new BASE64Decoder();byte[] b = new byte[0];try {b = decoder.decodeBuffer(baseStrs[1]);} catch (IOException e) {e.printStackTrace();}for (int i = 0; i < b.length; ++i) {if (b[i] < 0) {b[i] += 256;}}return new Base64DecodeMultipartFile(b, baseStrs[0]);}}

package mon.utils.face;/*** 自定义异常**/public class BizException extends RuntimeException {private static final long serialVersionUID = 1L;private String msg;private int code = 500;public BizException(String msg) {super(msg);this.msg = msg;}public BizException(String msg, Throwable e) {super(msg, e);this.msg = msg;}public BizException(String msg, int code) {super(msg);this.msg = msg;this.code = code;}public BizException(String msg, int code, Throwable e) {super(msg, e);this.msg = msg;this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}}

package mon.utils.face.constant;/*** 操作方式*/public enum ActionTypeEnum {APPEND("重复注册"),REPLACE("会用新图替换");ActionTypeEnum(String desc){this.desc = desc;}private String desc;public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}}

package mon.utils.face.constant;/*** 百度接口错误码,还需要加CODE看官方文档*/public enum ErrorEnum {ERROR_ENUM_1(1, "Unknown error", "服务器内部错误,请再次请求"),ERROR_ENUM_13(13, "Get service token failed", "获取token失败"),ERROR_ENUM_222202(222202, "pic not has face", "图片中没有人脸"),ERROR_ENUM_222203(222203, "image check fail", "无法解析人脸"),ERROR_ENUM_222207(222207, "match user is not found", "未找到匹配的用户"),ERROR_ENUM_222209(222209, "face token not exist", "face token不存在"),ERROR_ENUM_222301(222301, "get face fail", "获取人脸图片失败"),ERROR_ENUM_223102(223102, "user is already exist", "该用户已存在"),ERROR_ENUM_223106(223106, "face is not exist", "该人脸不存在"),ERROR_ENUM_223113(223113, "face is covered", "人脸模糊"),ERROR_ENUM_223114(223114, "face is fuzzy", "人脸模糊"),ERROR_ENUM_223115(223115, "face light is not good", "人脸光照不好"),ERROR_ENUM_223116(223116, "incomplete face", "人脸不完整");ErrorEnum(int errorCode, String desc, String cnDesc){this.errorCode = errorCode;this.desc = desc;Desc = cnDesc;}private int errorCode;private String desc;private String cnDesc;public static ErrorEnum getInstance(int errorCode){for (ErrorEnum value : ErrorEnum.values()) {if (value.errorCode == errorCode){return value;}}return null;}public int getErrorCode() {return errorCode;}public void setErrorCode(int errorCode) {this.errorCode = errorCode;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public String getCnDesc() {return cnDesc;}public void setCnDesc(String cnDesc) {Desc = cnDesc;}}

package mon.utils.face.constant;public class FaceConstant {/*** 默认组别*/public static final String DEFAULT_GROUP_ID = "60030";/*** 匹配分数*/public static final int MATCH_SCORE = 80;public static final String RESULT = "result";public static final String LOG_ID = "log_id";public static final String ERROR_MSG = "error_msg";public static final String CACHED = "cached";public static final String ERROR_CODE = "error_code";public static final String TIMESTAMP = "timestamp";public static final String SCORE = "score";public static final String FACE_LIST = "face_list";public static final String FACE_TOKEN = "face_token";public static final String USER_ID_LIST = "user_id_list";public static final String GROUP_ID_LIST = "group_id_list";public static final String USER_LIST = "user_list";}

package mon.utils.face.constant;/*** 图片类型*/public enum ImageTypeEnum {BASE64("BASE64", 2),URL("URL", 0),FACE_TOKEN("FACE_TOKEN", 0);ImageTypeEnum(String key, int size){this.key = key;this.size = size;}/*** key*/private String key;/*** 大小 单位:M*/private int size;public String getKey() {return key;}public void setKey(String key) {this.key = key;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}}

package mon.utils.face.constant;/*** 活体检测控制*/public enum LivenessControlEnum {NONE("不进行控制"),LOW("较低的活体要求(高通过率 低攻击拒绝率)"),NORMAL("一般的活体要求(平衡的攻击拒绝率, 通过率)"),HIGH("较高的活体要求");LivenessControlEnum(String desc){this.desc = desc;}private String desc;public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}}

package mon.utils.face.constant;/*** 图片质量控制*/public enum QualityControlEnum {NONE("不进行控制"),LOW("较低的质量要求"),NORMAL("一般的质量要求"),HIGH("较高的质量要求");QualityControlEnum(String desc){this.desc = desc;}private String desc;public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}}

4、前端实现

<template><div class="login"><el-formref="loginForm":model="loginForm":rules="loginRules"class="login-form"><h3 class="title">管理系统</h3><el-tabs v-model="activeName" type="card" @tab-click="handleClick"><el-tab-pane label="账户登录" name="first"><el-form-item prop="username"><el-inputv-model="loginForm.username"type="text"auto-complete="off"placeholder="账号"><svg-iconslot="prefix"icon-class="user"class="el-input__icon input-icon"/></el-input></el-form-item><el-form-item prop="password"><el-inputv-model="loginForm.password"type="password"auto-complete="off"placeholder="密码"@keyup.enter.native="handleLogin"><svg-iconslot="prefix"icon-class="password"class="el-input__icon input-icon"/></el-input></el-form-item><el-form-item prop="code" v-if="captchaOnOff"><el-inputv-model="loginForm.code"auto-complete="off"placeholder="验证码"style="width: 63%"@keyup.enter.native="handleLogin"><svg-iconslot="prefix"icon-class="validCode"class="el-input__icon input-icon"/></el-input><div class="login-code"><img :src="codeUrl" @click="getCode" class="login-code-img" /></div></el-form-item><el-checkboxv-model="loginForm.rememberMe"style="margin: 0px 0px 25px 0px">记住密码</el-checkbox><el-form-item style="width: 100%"><el-button:loading="loading"size="medium"type="primary"style="width: 100%"@click.native.prevent="handleLogin"><span v-if="!loading">登 录</span><span v-else>登 录 中...</span></el-button><div style="float: right" v-if="register"><router-link class="link-type" :to="'/register'">立即注册</router-link></div></el-form-item></el-tab-pane><el-tab-pane label="人脸识别" name="second"><div class="testTrackingWrapper"><videoid="video"width="340"height="300"preloadautoplayloopmuted></video><canvas id="canvas" width="550" height="400"></canvas><div class="buttonWrapper"><button type="button" @click="submitPhoto">上传</button><button type="button" name="button" @click="openCamera">拍照</button></div></div></el-tab-pane></el-tabs></el-form><!-- 底部 --><div class="el-login-footer"><span>Copyright © - nexauto All Rights Reserved.</span></div><img :src="image" /></div></template><script>import { getCodeImg } from "@/api/login";import Cookies from "js-cookie";import { encrypt, decrypt } from "@/utils/jsencrypt";require("../assets/js/tracking-min");require("../assets/js/face-min.js");require("../assets/js/dat.gui.min.js");require("../assets/js/stats.min");export default {name: "Login",data() {return {// open: false, //控制摄像头开关// video: null,image: "",activeName: "first",codeUrl: "",cookiePassword: "",loginForm: {username: "admin",password: "admin123",rememberMe: false,code: "",uuid: "",},loginRules: {username: [{ required: true, trigger: "blur", message: "请输入您的账号" },],password: [{ required: true, trigger: "blur", message: "请输入您的密码" },],code: [{ required: true, trigger: "change", message: "请输入验证码" }],},loading: false,// 验证码开关captchaOnOff: true,// 注册开关register: false,redirect: undefined,};},watch: {$route: {handler: function (route) {this.redirect = route.query && route.query.redirect;},immediate: true,},},created() {this.getCode();this.getCookie();},methods: {//选项卡点击事件handleClick(tab, event) {console.log(tab, event);if (tab.name == "first") {this.stopNavigator();} else {this.openCamera();}},getCode() {getCodeImg().then((res) => {this.captchaOnOff =res.captchaOnOff === undefined ? true : res.captchaOnOff;if (this.captchaOnOff) {this.codeUrl = "data:image/gif;base64," + res.img;this.loginForm.uuid = res.uuid;}});},getCookie() {const username = Cookies.get("username");const password = Cookies.get("password");const rememberMe = Cookies.get("rememberMe");this.loginForm = {username: username === undefined ? this.loginForm.username : username,password:password === undefined ? this.loginForm.password : decrypt(password),rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),};},handleLogin() {this.$refs.loginForm.validate((valid) => {if (valid) {this.loading = true;if (this.loginForm.rememberMe) {Cookies.set("username", this.loginForm.username, { expires: 30 });Cookies.set("password", encrypt(this.loginForm.password), {expires: 30,});Cookies.set("rememberMe", this.loginForm.rememberMe, {expires: 30,});} else {Cookies.remove("username");Cookies.remove("password");Cookies.remove("rememberMe");}this.$store.dispatch("Login", this.loginForm).then(() => {this.$router.push({ path: this.redirect || "/" }).catch(() => {});}).catch(() => {this.loading = false;if (this.captchaOnOff) {this.getCode();}});}});},//打开摄像头openCamera() {var _this = this;var video = document.getElementById("video");var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var tracker = new tracking.ObjectTracker("face");tracker.setInitialScale(4);tracker.setStepSize(2);tracker.setEdgesDensity(0.1);this.trackerTask = tracking.track("#video", tracker, { camera: true });tracker.on("track", function (event) {context.clearRect(0, 0, canvas.width, canvas.height);event.data.forEach(function (rect) {context.font = "11px Helvetica";context.fillText("已识别到人脸,请点击拍照", 100, 40);context.strokeStyle = "#a64ceb";context.strokeRect(rect.x, rect.y, rect.width, rect.height);});});},//提交submitPhoto() {let _this = this;let canvas = document.getElementById("canvas");let context = canvas.getContext("2d");let video = document.getElementById("video");context.drawImage(video, 0, 0, 500, 400);let formData=new FormData();let base64File=canvas.toDataURL(); formData.append("file",base64File);formData.append("groupId","group1");this.$store.dispatch("Facelogin", formData).then(() => {this.stopNavigator();this.$router.push({ path: this.redirect || "/" }).catch(() => {});}).catch(() => {this.loading = false;this.getCode();});},//关闭摄像头stopNavigator() {if (video && video !== null) {video.srcObject.getTracks()[0].stop();// this.open = true; //切换成打开摄像头}},},beforeDestroy() {this.stopNavigator();},};</script><style rel="stylesheet/scss" lang="scss">.login {display: flex;justify-content: center;align-items: center;height: 100%;background-image: url("../assets/images/login-background.jpg");background-size: cover;}.title {margin: 0px auto 30px auto;text-align: center;color: #707070;}.login-form {border-radius: 6px;background: #ffffff;width: 400px;padding: 25px 25px 5px 25px;.el-input {height: 38px;input {height: 38px;}}.input-icon {height: 39px;width: 14px;margin-left: 2px;}}.login-tip {font-size: 13px;text-align: center;color: #bfbfbf;}.login-code {width: 33%;height: 38px;float: right;img {cursor: pointer;vertical-align: middle;}}.el-login-footer {height: 40px;line-height: 40px;position: fixed;bottom: 0;width: 100%;text-align: center;color: #fff;font-family: Arial;font-size: 12px;letter-spacing: 1px;}.login-code-img {height: 38px;}.testTrackingWrapper {height: 300px;width: 200px;position: relative;}video,canvas {position: absolute;left: 0;right: 0;top: 0;}.buttonWrapper {position: absolute;left: 0;right: 0;bottom: 7%;}</style>

写的不好的地方,可以纠正,如出问题,鄙人可以交流学习:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。