热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java基于虹软实现人脸识别、人脸比对、活性检测等

本文主要介绍了Java基于虹软实现人脸识别、人脸比对、活性检测等,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的

虹软

  • 免费,高级版本试用
  • 支持在线、离线
  • 有 Java SDK,C++ SDK

一、注册虹软开发者平台

点击注册

在这里插入图片描述

注册完成后可在“我的应用”中新建应用,获得 APP_IDSDK_Key,请记住这两个信息,后续 SDK 中会用到。

在这里插入图片描述

接下来下载SDK就行了。

二、开始使用SDK

SDK包结构
在下载的sdk包中,包结构大概是这样

|—demo
| |—ArcFaceDemo Demo工程
|—doc
| |—ARCSOFT_ARC_FACE_DEVELOPER’S_GUIDE.PDF 开发说明文档
|—inc
| |—amcomdef.h 平台文件
| |—asvloffscreen.h 平台文件
| |—arcsoft_face_sdk.h 接口文件
| |—merror.h 错误码文件
|—lib
|—|---Win32/x64
| |—|---libarcsoft_face.dll 算法库
| |—|---libarcsoft_face_engine.dll 引擎库
| |—|---libarcsoft_face_engine.lib 引擎库
|—samplecode
| |—samplecode.cpp 示例代码
|—releasenotes.txt 说明文件

在项目中引入 SDK 包


    arcsoft
    arcsoft-sdk-face
    3.0.0.0
    system
    ${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0.jar

简单的集成

package com.study;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.*;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;
import com.arcsoft.face.toolkit.ImageInfoEx;
import com.study.exception.CustomException;
import com.study.vo.FaceDetailInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 集成虹软-人脸识别测试
 *
 * @author ouyangrongtao
 * @since 2022-02-20 19:12
 */
public class FaceEngineMain {

    // 从上述的开发者平台-“我的应用” 获取
    private static final String APP_ID = "";
    private static final String SDK_KEY = "";

    // sdk安装路径
    private static final String ARC_FACE_PATH = "arcsoft";

    private static final Logger LOGGER = LoggerFactory.getLogger(FaceEngineMain.class);

    public static void main(String[] args) {
        FaceEngineMain faceEngineMain = new FaceEngineMain();
        // 激活
        FaceEngine faceEngine = faceEngineMain.active();
        // 识别功能配置
        FunctionConfiguration functiOnConfiguration= faceEngineMain.getFunctionConfiguration();
        // 初始化识别引擎
        faceEngineMain.initEngine(faceEngine, functionConfiguration);

        ImageInfo imageInfo = ImageFactory.getRGBData(new File("d:aaa.jpeg"));
        ImageInfo imageInfo2 = ImageFactory.getRGBData(new File("d:bb.jpeg"));

        // 人脸检测&特征提取1
        List faceDetailInfoList1 = faceEngineMain.detectFaces(faceEngine, imageInfo);

        // 人脸检测&特征提取2
        List faceDetailInfoList2 = faceEngineMain.detectFaces(faceEngine, imageInfo2);

        /*
         * 特征比对
         * 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82
         * 用于生活照之间的特征比对,推荐阈值0.80
         */
        FaceSimilar faceSimilar = faceEngineMain.compareFaceFeature(faceEngine,
                faceDetailInfoList1.get(0).getFaceFeature(), faceDetailInfoList2.get(0).getFaceFeature());
        LOGGER.info("相似度:{}", faceSimilar.getScore());

        // 获取人脸属性
        faceEngineMain.getFaceAttributes(faceEngine, imageInfo);

        ImageInfo imageInfo3 = ImageFactory.getRGBData(new File("d:ccc.jpg"));
        ImageInfo imageInfo4 = ImageFactory.getRGBData(new File("d:ddd.jpg"));

        // 人脸检测&特征提取3
        List faceDetailInfoList3 = faceEngineMain.detectFacesEx(faceEngine, imageInfo3, DetectModel.ASF_DETECT_MODEL_RGB);

        // 人脸检测&特征提取4
        List faceDetailInfoList4 = faceEngineMain.detectFacesEx(faceEngine, imageInfo4, DetectModel.ASF_DETECT_MODEL_RGB);

        // 特征比对
        FaceSimilar faceSimilar2 = faceEngineMain.compareFaceFeature(faceEngine,
                faceDetailInfoList3.get(0).getFaceFeature(), faceDetailInfoList4.get(0).getFaceFeature(), CompareModel.LIFE_PHOTO);
        /*
         * 特征比对
         * 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82
         * 用于生活照之间的特征比对,推荐阈值0.80
         */
        LOGGER.info("相似度:{}", faceSimilar2.getScore());

        // 获取人脸属性
        faceEngineMain.getFaceAttributesEx(faceEngine, imageInfo);

        ImageInfo imageInfoGray = ImageFactory.getGrayData(new File("d:ddd.jpg"));

        // 活体检测 RGB & IR
        faceEngineMain.getLiveness(faceEngine, imageInfo, imageInfoGray);

        // 卸载
        faceEngineMain.unInit(faceEngine);
    }

    /**
     * 活体检测
     * @param faceEngine 引擎
     * @param imageInfoRGB RGB图片信息
     * @param imageInfoGray Gray图片信息
     */
    private void getLiveness(FaceEngine faceEngine, ImageInfo imageInfoRGB, ImageInfo imageInfoGray) {
        // 人脸检测
        List faceInfoList = new ArrayList<>();
        faceEngine.detectFaces(imageInfoRGB.getImageData(),
                imageInfoRGB.getWidth(), imageInfoRGB.getHeight(), imageInfoRGB.getImageFormat(), faceInfoList);
        // 设置活体测试阀值
        faceEngine.setLivenessParam(0.5f, 0.7f);

        // RGB人脸检测
        FunctionConfiguration cOnfiguration= new FunctionConfiguration();
        configuration.setSupportLiveness(true);
        faceEngine.process(imageInfoRGB.getImageData(),
                imageInfoRGB.getWidth(), imageInfoRGB.getHeight(), imageInfoRGB.getImageFormat(), faceInfoList, configuration);

        // RGB活体检测
        List livenessInfoList = new ArrayList<>();
        faceEngine.getLiveness(livenessInfoList);
        LOGGER.info("RGB活体:{}", livenessInfoList.get(0).getLiveness());

        // IR属性处理
        List faceInfoListGray = new ArrayList<>();
        // IR人脸检查
        faceEngine.detectFaces(imageInfoGray.getImageData(),
                imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray);

        cOnfiguration= new FunctionConfiguration();
        configuration.setSupportIRLiveness(true);
        faceEngine.processIr(imageInfoGray.getImageData(),
                imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray, configuration);

        //IR活体检测
        List irLivenessInfo = new ArrayList<>();
        faceEngine.getLivenessIr(irLivenessInfo);
        LOGGER.info("IR活体:{}", irLivenessInfo.get(0).getLiveness());
    }

    /**
     * 人脸属性检测
     * @param faceEngine 引擎
     * @param imageInfo 图片信息
     */
    private void getFaceAttributesEx(FaceEngine faceEngine, ImageInfo imageInfo) {
        // 人脸检测
        List faceInfoList = new ArrayList<>();
        faceEngine.detectFaces(imageInfo.getImageData(),
                imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);

        ImageInfoEx imageInfoEx = new ImageInfoEx();
        imageInfoEx.setHeight(imageInfo.getHeight());
        imageInfoEx.setWidth(imageInfo.getWidth());
        imageInfoEx.setImageFormat(imageInfo.getImageFormat());
        imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});
        imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});

        //人脸属性检测
        FunctionConfiguration cOnfiguration= new FunctionConfiguration();
        configuration.setSupportGender(true);
        configuration.setSupportAge(true);
        configuration.setSupportFace3dAngle(true);
        faceEngine.process(imageInfoEx, faceInfoList, configuration);

        //性别检测
        List genderInfoList = new ArrayList<>();
        faceEngine.getGender(genderInfoList);
        LOGGER.info("性别:{}", genderInfoList.get(0).getGender());

        //年龄检测
        List ageInfoList = new ArrayList<>();
        faceEngine.getAge(ageInfoList);
        LOGGER.info("年龄:{}", ageInfoList.get(0).getAge());

        //3D信息检测
        List face3DAngleList = new ArrayList<>();
        faceEngine.getFace3DAngle(face3DAngleList);
        Face3DAngle face3DAngle = face3DAngleList.get(0);
        LOGGER.info("3D角度:{}", face3DAngle.getPitch() + "," + face3DAngle.getRoll() + "," + face3DAngle.getYaw());
    }

    /**
     * 人脸属性检测
     * @param faceEngine 引擎
     * @param imageInfo 图片信息
     */
    private void getFaceAttributes(FaceEngine faceEngine, ImageInfo imageInfo) {
        //人脸属性检测
        FunctionConfiguration cOnfiguration= new FunctionConfiguration();
        configuration.setSupportGender(true);
        configuration.setSupportAge(true);
        configuration.setSupportFace3dAngle(true);

        // 人脸检测
        List faceInfoList = new ArrayList<>();
        faceEngine.detectFaces(imageInfo.getImageData(),
                imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);

        faceEngine.process(imageInfo.getImageData(),
                imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, configuration);

        //性别检测
        List genderInfoList = new ArrayList<>();
        faceEngine.getGender(genderInfoList);
        LOGGER.info("性别:{}", genderInfoList.get(0).getGender());

        //年龄检测
        List ageInfoList = new ArrayList<>();
        faceEngine.getAge(ageInfoList);
        LOGGER.info("年龄:{}", ageInfoList.get(0).getAge());

        //3D信息检测
        List face3DAngleList = new ArrayList<>();
        faceEngine.getFace3DAngle(face3DAngleList);
        Face3DAngle face3DAngle = face3DAngleList.get(0);
        LOGGER.info("3D角度:{}", face3DAngle.getPitch() + "," + face3DAngle.getRoll() + "," + face3DAngle.getYaw());
    }

    /**
     * 特征比对-可设置比对模型
     * @param faceEngine 引擎
     * @param sourceFaceFeature 原特征值
     * @param targetFaceFeature 比对的特征值
     * @param compareModel 比对模型
     * @return 比对结果
     */
    private FaceSimilar compareFaceFeature(FaceEngine faceEngine, FaceFeature sourceFaceFeature, FaceFeature targetFaceFeature, CompareModel compareModel) {
        // 特征比对
        FaceSimilar faceSimilar = new FaceSimilar();
        int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, compareModel, faceSimilar);
        if (ErrorInfo.MOK.getValue() != errorCode) {
            LOGGER.error("人脸特征比对失败");
        }

        return faceSimilar;
    }

    /**
     * 特征比对
     * @param faceEngine 引擎
     * @param sourceFaceFeature 原特征值
     * @param targetFaceFeature 比对的特征值
     * @return 比对结果
     */
    private FaceSimilar compareFaceFeature(FaceEngine faceEngine, FaceFeature sourceFaceFeature, FaceFeature targetFaceFeature) {
        // 特征比对
        FaceSimilar faceSimilar = new FaceSimilar();
        int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
        if (ErrorInfo.MOK.getValue() != errorCode) {
            LOGGER.error("人脸特征比对失败");
        }

        return faceSimilar;
    }

    /**
     * 人脸检测&特征提取--可设置检测模式
     * @param faceEngine 引擎
     * @param imageInfo 图片信息
     * @param detectModel 检测模式
     * @return 人脸信息
     */
    private List detectFacesEx(FaceEngine faceEngine, ImageInfo imageInfo, DetectModel detectModel) {
        ImageInfoEx imageInfoEx = new ImageInfoEx();
        imageInfoEx.setHeight(imageInfo.getHeight());
        imageInfoEx.setWidth(imageInfo.getWidth());
        imageInfoEx.setImageFormat(imageInfo.getImageFormat());
        imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});
        imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});

        List faceInfoList = new ArrayList<>();
        faceEngine.detectFaces(imageInfoEx, detectModel, faceInfoList);

        List faceDetailInfoList = new ArrayList<>(faceInfoList.size());
        for (FaceInfo faceInfo : faceInfoList) {
            LOGGER.info("imageInfoEx 人脸检测结果: {}", faceInfo);
            FaceFeature faceFeature = new FaceFeature();
            faceEngine.extractFaceFeature(imageInfoEx, faceInfo, faceFeature);

            LOGGER.info("imageInfoEx 特征值大小:{}", faceFeature.getFeatureData().length);

            FaceDetailInfo faceDetailInfo = new FaceDetailInfo(faceInfo, faceFeature);
            faceDetailInfoList.add(faceDetailInfo);
        }

        return faceDetailInfoList;
    }

    /**
     * 人脸检测&特征提取
     * @param faceEngine 引擎
     * @param imageInfo 图片信息
     * @return 人脸信息
     */
    private List detectFaces(FaceEngine faceEngine, ImageInfo imageInfo) {
        // 人脸检测
        List faceInfoList = new ArrayList<>();
        faceEngine.detectFaces(imageInfo.getImageData(),
                imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);

        List faceDetailInfoList = new ArrayList<>(faceInfoList.size());
        // 特征提取
        for (FaceInfo faceInfo : faceInfoList) {
            LOGGER.info("人脸检测结果: {}", faceInfo);

            FaceFeature faceFeature = new FaceFeature();
            faceEngine.extractFaceFeature(imageInfo.getImageData(),
                    imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfo, faceFeature);

            LOGGER.info("特征值大小:{}", faceFeature.getFeatureData().length);

            FaceDetailInfo faceDetailInfo = new FaceDetailInfo(faceInfo, faceFeature);
            faceDetailInfoList.add(faceDetailInfo);
        }

        return faceDetailInfoList;
    }

    /**
     * 初始化识别引擎
     * @param faceEngine 人脸识别引擎
     * @param functionConfiguration 功能配置
     */
    private void initEngine(FaceEngine faceEngine, FunctionConfiguration functionConfiguration) {
        // 引擎配置
        EngineConfiguration engineCOnfiguration= new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(16);

        engineConfiguration.setFunctionConfiguration(functionConfiguration);

        // 初始化引擎
        int errorCode = faceEngine.init(engineConfiguration);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            throw new CustomException("初始化引擎失败");
        }
    }

    /**
     * 识别功能配置
     */
    private FunctionConfiguration getFunctionConfiguration() {
        // 功能配置
        FunctionConfiguration functiOnConfiguration= new FunctionConfiguration();

        functionConfiguration.setSupportAge(true);
        functionConfiguration.setSupportFace3dAngle(true);
        functionConfiguration.setSupportFaceDetect(true);
        functionConfiguration.setSupportFaceRecognition(true);
        functionConfiguration.setSupportGender(true);
        functionConfiguration.setSupportLiveness(true);
        functionConfiguration.setSupportIRLiveness(true);

        return functionConfiguration;
    }

    /**
     * 激活 初次使用SDK时需要对SDK先进行激活,激活后无需重复调用;调用此接口时必须为联网状态,激活成功后即可离线使用;
     * @return FaceEngine 对象
     */
    private FaceEngine active() {
        URL resource = ClassLoader.getSystemResource(ARC_FACE_PATH);
        LOGGER.info("软件安装目录:{}", resource);

        FaceEngine faceEngine = new FaceEngine(resource.getPath());

        ActiveFileInfo activeFileInfo = new ActiveFileInfo();
        int errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
        if (errorCode != ErrorInfo.MOK.getValue()
                && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            LOGGER.info("获取激活文件信息失败");
        }

        // 首次激活
        errorCode = faceEngine.activeOnline(APP_ID, SDK_KEY);
        if (errorCode != ErrorInfo.MOK.getValue()
                && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            throw new CustomException("引擎激活失败");
        }

        LOGGER.info("激活信息:{}", activeFileInfo);

        return faceEngine;
    }

    /**
     * 卸载引擎
     * @param faceEngine 人脸识别引擎
     */
    private void unInit(FaceEngine faceEngine) {
        faceEngine.unInit();
    }
}

性能信息(参考官方文档)

在这里插入图片描述

阀值设置推荐(参考官方文档)

  1. 活体取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为活体。
    - RGB 活体:0.5
    - IR 活体:0.7

  2. 人脸比对取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为同一人。
    - 用于生活照之间的特征比对,推荐阈值0.80
    - 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82

产品文档 https://ai.arcsoft.com.cn/manual/docs#/89

 到此这篇关于Java基于虹软实现人脸识别、人脸比对、活性检测等的文章就介绍到这了,更多相关Java 人脸识别、人脸比对、活性检测内容请搜索编程笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程笔记!


推荐阅读
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
author-avatar
初2新生_349
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有