Java - 使用虹软人脸识别sdk记录
项目中需要使用人脸识别功能(图片vs图片),用于校验是否是用户本人操作。
思路:前端传入截取的照片(特征值),与数据库保存的用户照片(特征值)进行比对。
此处选用的是:虹软人脸识别Arcface
独立离线版SDK,拥有人脸检测、人脸跟踪、人脸比对/搜索、年龄检测、性别识别、IR/RGB活体检测等功能;
首次调用需联网激活,后续离线使用;
一年有效期,到期更新引擎继续免费使用。更新引擎只需要在开放平台重新下载引擎,将原应用工程中的引擎相关包文件、代码中所使用的APP_ID、SDK_KEY均替换成最新的即可
目录
- 一、代码示例
- 1.提取照片特征值
- 2.比较特征值
- 3.工具类
- 二、参考文档
一、代码示例
1.提取照片特征值
将照片以base64码的形式上传,使用虹软sdk将其特征值提取并保存。
/*** 提取人脸特征* @param imageInfo* @return*/public byte[] extractFaceFeature(ImageInfo imageInfo) throws InterruptedException {FaceEngine faceEngine = null;try {// 获取引擎对象faceEngine = faceEngineObjectPool.borrowObject();// 人脸检测获得人脸列表 faceInfoListList<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);if (!CollectionUtils.isEmpty(faceInfoList)) {logger.info("faceId = {}", faceInfoList.get(0).getFaceId());/*** 提取人脸特征* faceInfoList.get(0) 人脸信息(人脸框、人脸角度)*/FaceFeature faceFeature = new FaceFeature();faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);return faceFeature.getFeatureData();}} catch (Exception e) {logger.error("", e);} finally {if (faceEngine != null) {//释放引擎对象faceEngineObjectPool.returnObject(faceEngine);}}return new byte[0];}
// 校验照片是否能获取特征值byte[] decode = cn.hutool.core.codec.Base64.decode(Base64Utils.base64Process(picture.getPictureCode()));ImageInfo imageInfo = ImageFactory.getRGBData(decode);//人脸特征获取byte[] targetbytes = faceRecognitionService.extractFaceFeature(imageInfo);if (targetbytes == null || targetbytes.length < 1) {log.error("照片人脸读取失败");}
2.比较特征值
// 获得对比相似值byte[] targetbytes; // 目标特征值byte[] sourcebytes; // 源特征值
if (targetbytes.length > 0 && sourcebytes.length > 0) {Integer similarValue = faceRecognitionService.compareFaceFeature2(targetbytes, sourcebytes);log.info("相似值 >>>>>>> {}%", staffId, similarValue);
}
3.工具类
/*** base64处理工具类*/
@Slf4j
public class Base64Utils {// 处理图片base64码public static String base64Process(String base64Str) {if (!StringUtils.isEmpty(base64Str)) {String photoBase64 = base64Str.substring(0, 30).toLowerCase();int indexOf = photoBase64.indexOf("base64,");if (indexOf > 0) {base64Str = base64Str.substring(indexOf + 7);}return base64Str;} else {return "";}}/*** 计算图片的大小,返回单位为KB* @param imageBase64Str 图片base64数据* @return 图片大小*/public static Integer imageSize(String imageBase64Str){//1.找到等号,把等号也去掉(=用来填充base64字符串长度用)Integer equalIndex= imageBase64Str.indexOf("=");if(imageBase64Str.indexOf("=")>0) {imageBase64Str=imageBase64Str.substring(0, equalIndex);}//2.原来的字符流大小,单位为字节Integer strLength=imageBase64Str.length();
// log.info("imageBase64Str-Length = "+strLength);//3.计算后得到的文件流大小,单位为字节Integer size=strLength-(strLength/8)*2;return bytesToKB(size);}/*** byte(字节)根据长度转成kb(千字节)* @param bytes* @return*/public static Integer bytesToKB(long bytes) {BigDecimal filesize = new BigDecimal(bytes);BigDecimal megabyte = new BigDecimal(1024 * 1024);BigDecimal kilobyte = new BigDecimal(1024);float returnValue = filesize.divide(kilobyte, 1, BigDecimal.ROUND_DOWN).floatValue();return (int)returnValue ;}/*** 根据图片的base64数据缩放图片* @param base64ImagStr 原图的base64字符换* @param imageType 图片类型* @return*/public static String scaleImage(String base64ImagStr,String imageType){BufferedImage bufferedImage = ImgUtil.toImage(base64ImagStr);// 这块也可以直接通过传入一个image对象,Image scaleImage = ImgUtil.scale(bufferedImage, 0.3f);String resultBase64Str = ImgUtil.toBase64(scaleImage, imageType);Integer imageSizeBase64 = imageSize(resultBase64Str);if(imageSizeBase64 > 40){log.info("当前base64图片大小为:{}kb,进行压缩 >>>>>>>>>>", imageSizeBase64);resultBase64Str = scaleImage(resultBase64Str, imageType);}return resultBase64Str;}public static void main(String[] args){}
}
二、参考文档
虹软AI开放平台-Java接口文档
😺该文章为博主几年前写的,代码情况已经记不太清了,可能有遗漏,发布仅在此做个记录。
