Android基于虹软SDK实现离线人脸识别

Posted lilihewo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android基于虹软SDK实现离线人脸识别相关的知识,希望对你有一定的参考价值。

一、需求

        android端实现离线人脸识别功能,即对比两张人脸是否是同一个人。

二、解决方案

        选用虹软人脸识别SDK来实现人脸特征数据比对。

三、步骤

        1. 打开虹软开发者中心 开发者中心

        2. 新建应用

        3. 获取APP_ID,SDK_KEY,ACTIVE_KEY

        4. 编写代码

        4.1 填写SDK激活需要的APP_ID,SDK_KEY,ACTIVE_KEY

    public static final String APP_ID = "官网获取的APP_ID";
    public static final String SDK_KEY = "官网获取的SDK_KEY ";
    public static final String ACTIVE_KEY = "官网获取的ACTIVE_KEY,如果是试用,就填写试用码";

        4.2 布局文件的编写,这里对比两张人脸来判断是否是同一个人。用两个ImageView显示人脸照片吧。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/iv_register_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_weight="1"
            android:maxHeight="200dp"
            android:minHeight="100dp" />

        <ImageView
            android:id="@+id/iv_recognize_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_weight="1"
            android:maxHeight="200dp"
            android:minHeight="100dp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">

        <Button
            android:layout_width="150dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="10dp"
            android:background="@drawable/angle_button"
            android:onClick="addRegisterImage"
            android:text="添加注册照"
            android:textColor="@android:color/white"
            android:textSize="20sp" />

        <Button
            android:layout_width="150dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="30dp"
            android:background="@drawable/angle_button"
            android:onClick="addRecognizeImage"
            android:text="添加识别照"
            android:textColor="@android:color/white"
            android:textSize="20sp" />

    </LinearLayout>

    <TextView
        android:id="@+id/tv_similar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="相似度:--"
        android:textColor="@android:color/black"
        android:textSize="26sp" />


    <Button
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="200dp"
        android:layout_marginLeft="80dp"
        android:layout_marginRight="80dp"
        android:background="@drawable/angle_button"
        android:onClick="faceCompare"
        android:text="人脸比对"
        android:textColor="@android:color/white"
        android:textSize="20sp" />


</LinearLayout>

        4.3 代码编写

        4.3.1 激活人脸识别引擎,第一次使用需要联网激活SDK,激活成功后无需联网。

        if (!isActivated(this)) 
            runOnSubThread(() -> FaceEngine.activeOnline(this,
                    Constants.ACTIVE_KEY,
                    Constants.APP_ID,
                    Constants.SDK_KEY));
        

        4.3.2 初始化人脸识别SDK

    // 初始化人脸识别SDK
    private void initEngine() 
        faceEngine = new FaceEngine();
        faceEngineCode = faceEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_ALL_OUT,
                6, INIT_MASK);
        if (faceEngineCode != ErrorInfo.MOK) 
            showToast(getString(R.string.init_failed, faceEngineCode, ErrorCodeUtil.arcFaceErrorCodeToFieldName(faceEngineCode)));
        
    

        4.3.3 人脸检测

    // 人脸检测
    private List<FaceInfo> detectFace(byte[] bgr24, int width, int height)
    
        // 人脸信息集合(人脸框、人脸角度)
        List<FaceInfo> faceInfoList = new ArrayList<>();
        // 人脸检测
        int detectCode = faceEngine.detectFaces(bgr24, width, height, FaceEngine.CP_PAF_BGR24, faceInfoList);
        if (detectCode != 0 || faceInfoList.isEmpty()) 
            showToast("face detection finished, code is " + detectCode + ", face num is " + faceInfoList.size());
            return null;
        

        return faceInfoList;
    

        4.3.4 人脸特征提取

    // 提取人脸特征数据
    private FaceFeature extractFaceFeatureData(byte[] bgr24, int width, int height, List<FaceInfo> faceInfoList)
    
        // 口罩信息结果
        List<MaskInfo> maskInfoList = new ArrayList<>();

        faceEngine.getMask(maskInfoList);

        int isMask = MaskInfo.UNKNOWN;
        if (!maskInfoList.isEmpty()) 
            isMask = maskInfoList.get(0).getMask();
        

        // 人脸特征
        FaceFeature faceFeature = new FaceFeature();

        faceEngine.extractFaceFeature(bgr24, width, height,
                FaceEngine.CP_PAF_BGR24,
                faceInfoList.get(0),
                ExtractType.RECOGNIZE, isMask, faceFeature);

        return faceFeature;
    

        4.3.5 人脸特征比对

    // 比较两个人脸的相似度
    private float faceCompare(FaceFeature previewFaceFeature, FaceFeature idCardFaceFeature)
    
        FaceSimilar faceSimilar = new FaceSimilar();
        int compareCode = faceEngine.compareFaceFeature(previewFaceFeature, idCardFaceFeature, CompareModel.ID_CARD, faceSimilar);
        if (compareCode == ErrorInfo.MOK)
            // 两个人脸的相似度
            float score = faceSimilar.getScore();
            return score;
         else 
            Log.i(TAG, "compare failed, code is : " + compareCode);
            return 0;
        
    

        4.3.6 实际效果

 四、源码

需要完整源码的伙伴可以到这里下载

Android基于虹软SDK实现离线人脸识别https://www.lilihewo.com/article/235.html

基于免费SDK实现人脸识别应用开发

  随着人脸辨认技能运用范围不断扩展,如安在WindowsC#上依据免费SDK实现人脸辨认运用开发,正成为开发者们关怀的论题之一。
  关于该需求,我引荐虹软视觉敞开平台的ArcFace3.0,免费、离线且可商用,包括人脸辨认、活体检测、年纪检测、性别检测等丰富功用,算法鲁棒性强,接入门槛低,同时支撑Windows、iOS、Android(包括Android10)、Linux,是广大开发者落地AI运用的利器。
  为协助开发者快速上手,虹软工程师团队针对C#开发打磨了一期课程,以技能解析和专项答疑等形式协助开发者解决难题。主张有爱好测验ArcFace3.0的C#开发者能够提早学习,在实践开发中可事半功倍。
  本期课程关键如下,对完好课程视频感爱好的开发者,能够经过百度查找"虹软技能公开课"观看。
  一、关键一【3分钟跑通C#demo】
  课程依据虹软人脸辨认SDK包中提供的示例代码,以实操的形式介绍了如何快速接入运用。接入进程在课程视频中有详细介绍。主张观看视频后自行测验装备,即可对虹软人脸辨认技能有一个开始的了解。
  Demo装备进程如下:
  1.下载Demo
  2.查看本地系统环境是否符合要求:
  a..NETFramework4.5.1及以上
  b.MicrosoftVisualC++2013运转库
  3.在虹软视觉敞开平台下载SDK,获取APPID、SDKKEY
  4.装备运转Demo:
  a.在App.config文件中装备APPID、SDKKEY
  b.将SDKlib文件夹中dll文件拷贝到运转根目录下
  c.如本地.NETFramework的版别高于4.5.1,直接修改项目的方针结构
  二、关键二【ArcFace要点接口及参数介绍】
  1.引擎初始化接口:ASFInitEngine()
  【阐明】
  引擎初始化接口用于初始化引擎,初始化中的参数设置用于界说引擎的特点和算法功用组合,与算法能够呈现出的作用休戚相关。
  初始化失利时,依据错误码查询原因即可。参数设置是开发者最关怀的核心问题,也是保障在实践运用场景中最大化发挥算法作用的关键。视频中首要介绍以下几个参数在实践场景下如何运用。
  【重要参数阐明】
  ·detectMode(检测形式):
  ASF_DETECT_MODE_VIDEOvideo形式:适用于摄像头预览,视频文件辨认
  ASF_DETECT_MODE_IMAGEimage形式:适用于静态图片辨认。
  ·detectFaceScaleVal(最小人脸尺度):代表人脸尺度相关于图片长边的占比,数值越大,能检测更小的人脸,效值范围[2,32],video形式引荐值为16,image形式引荐值32。
  ·combinedMask(算法功用组合):主张依据具体事务合理挑选算法功用组合,假如功用挑选越多,占用的内存越大。
  2.人脸特征提取接口:ASFFaceFeatureExtract()
  【阐明】当人脸检测完结时,能够依据获取的人脸信息经过此接口进行对应人脸的特征提取。
  【重要参数阐明】
  ·faceInfo:特征提取需求单张精确的人脸位置和视点,否则或许会报81925。
  ·featureFeature:算法返回的人脸特征值,包括特征byte数组及特征长度,特征数据库存取操作应存取特征byte数组。
  3.人脸特点检测:ASFProcess()
  【阐明】人脸检测成功后,能够依据人脸信息经过此接口检测人脸特点,如年纪、性别等。
  【重要参数阐明】
  ·combinedMask:只支撑引擎初始化时指定需求检测的功用,如引擎初始化时,mask指定为年纪和性别,则不能检测3D视点等其他特点。
  ·支撑的特点:ASF_AGE(年纪)、ASF_GENDER(性别)、ASF_FACE3DANGLE(3D视点)、ASF_LIVENESS(RGB活体)。
  ·Process()检测后可依据ASFGetXXX()接口获取对应特点检测成果。
  三、关键三【视频流辨认和活体检测】
  下图为常见视频流辨认和活体检测的逻辑流程图:
  【多线程策略】
  ·主线程:包括人脸追寻以及画面预览功用。
  ·FR线程:用于人脸特征提取和特征查找。
  ·活体线程:用于人脸活体检测。
  【优化策略】
  ·FaceID:依据FaceID标识一个人,从进入画面到脱离画面,对这一人脸只做一次辨认即可,大大降低系统资源占用。
  ·测验次数:同一张人脸,特征提取失利能够做有限次数的测验,提高交互作用。
  四、关键四【常见问题答疑】
  1.多线程调用问题
  a.同一个引擎能够运用多线程调用不同算法。
  b.多线程调用同一个算法接口需求启用不同的引擎。
  2.VIDEO和IMAGE形式的区别
  VIDEO形式:
  a.对视频流中的人脸进行追寻,人脸框滑润过渡,不会呈现跳框的现象。
  b.用于预览数据的人脸追寻,处理速度快,可避免呈现卡顿问题。
  c.在视频形式引进faceId帧,该值用于标记一张人脸,当一个人脸从进入画面直到脱离画面,faceId值不变。可用于事务中优化程序功能。
  IMAGE形式:
  a.针对单张图片进行人脸检测精度更高。
  b.在注册人脸库时,我们主张运用精度更高的IMAGE形式。
  3.非托管内存的操作
  C#调用C++SDK接口,有些传参需求以Intptr的形式。
  a.复制前应先为Intptr请求内存;
  b.当IntPtr不运用时,需求及时手动开释。
  4.人脸特征数据库的存储
  人脸特征提取接口返回的featureFeature对应ASF_FaceFeature,数据库存储应将ASF_FaceFeature.feature转化为byte[]再进行数据库存储,featureSize表示byte[]的长度。
  5.SDKdll文件的引用方法(运用DllImport方法)
  a.运用相对路径,将dll直接放到执行目录下(web程序不主张运用);
  b.运用绝对路径;
  c.将dll文件放到系统盘Windows下的System32文件夹下;
  d.为dll文件所在文件夹添加环境变量。

以上是关于Android基于虹软SDK实现离线人脸识别的主要内容,如果未能解决你的问题,请参考以下文章

虹软人脸识别怎么样

android 人脸识别 sdk有没有离线版的?

基于免费SDK实现人脸识别应用开发

虹软人脸识别3.0 - 图像数据结构介绍(Android)

基于虹软(ArcSoft)实现人脸识别——Android版

android 集成人脸识别都有哪些好的sdk