Java - 使用虹软人脸识别sdk记录

项目中需要使用人脸识别功能(图片vs图片),用于校验是否是用户本人操作。
思路:前端传入截取的照片(特征值),与数据库保存的用户照片(特征值)进行比对。

此处选用的是:虹软人脸识别Arcface
独立离线版SDK,拥有人脸检测、人脸跟踪、人脸比对/搜索、年龄检测、性别识别、IR/RGB活体检测等功能;
首次调用需联网激活,后续离线使用;
一年有效期,到期更新引擎继续免费使用。更新引擎只需要在开放平台重新下载引擎,将原应用工程中的引擎相关包文件、代码中所使用的APP_ID、SDK_KEY均替换成最新的即可

一、代码示例

1.提取照片特征值

将照片以base64码的形式上传,使用虹软sdk将其特征值提取并保存。

/**
     * 提取人脸特征
     * @param imageInfo
     * @return
     */
    public byte[] extractFaceFeature(ImageInfo imageInfo) throws InterruptedException {

        FaceEngine faceEngine = null;

        try {

            // 获取引擎对象
            faceEngine = faceEngineObjectPool.borrowObject();

            // 人脸检测获得人脸列表 faceInfoList
            List<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接口文档

😺该文章为博主几年前写的,代码情况已经记不太清了,可能有遗漏,发布仅在此做个记录。
751c080b-1dc8-42c9-a2fd-288185d53cb6

posted @ 2025-11-04 14:17  御坂10027  阅读(15)  评论(0)    收藏  举报  来源