Android 一句话集成ArcFace虹软人脸识别

基于虹软人脸识别增值版Android SDK V3.1,封装人脸识别方法。

增值版Android SDK V3.1文档

引入

仅支持AndroidX

Gradle:

最新版本

//必选,默认仅支持armeabi-v7a
implementation 'com.shencoder:arc-face:1.0.1'
//可选,支持arm64-v8a
implementation 'com.shencoder:arc-face-arm64-v8a:1.0.1'
如果Gradle出现implementation失败的情况,可以在Project的build.gradle里面添加如下:
allprojects {
    repositories {
        //...
        maven { url 'https://dl.bintray.com/shencoder/android-lib' }
    }
}

项目内依赖CameraView用于摄像头预览,默认使用TextureView用于实现预览镜像。

使用事例

布局示例

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.shencoder.arcface.view.FaceCameraView
        android:id="@+id/faceCameraView"
        android:layout_width="match_parent"
        android:layout_height="450dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

代码示例

基本使用

    val faceCameraView: FaceCameraView = findViewById(R.id.faceCameraView)
    val configuration = FaceConfiguration.Builder(this, object : OnRecognizeCallback {
        /**
         * 检测到的人脸数量
         * <p>运行在子线程</p>
         *
         * @param num 人脸数量
         * @param faceIds faceId
         */
        override fun detectFaceNum(num: Int, faceIds: List<Int>) {

        }

        /**
         * 有人,仅在有变化时调用一次
         * <p>运行在子线程</p>
         */
        override fun someone() {

        }

        /**
         * 无人,仅在有变化时调用一次
         * <p>运行在子线程</p>
         */
        override fun nobody() {

        }

        /**
         * 如果不想自动比对的话,可以通过此接口返回识别到的人脸特征码,仅在[FaceConfiguration.enableCompareFace] 为false时才会回调
         * <p>运行在子线程</p>
         *
         * @param faceId 人脸Id
         * @param feature 人脸特征码
         * @param recognizeInfo 识别到的其他信息,包含活体值、年龄、性别、人脸角度等信息
         */
         override fun onGetFaceFeature(
             faceId: Int,
             feature: ByteArray,
             recognizeInfo: RecognizeInfo
         ) {
             Log.i("MainActivity", "onGetFaceFeature-faceId:${faceId},feature:${feature.size},recognizeInfo:$recognizeInfo")
         }

        /**
         * 识别成功后结果回调,仅回调一次,直到人脸离开画面
         * <p>运行在子线程</p>
         *
         * @param bean 识别的数据 [faceFeatureList] 的子项
         * @param similar 识别通过的相似度
         * @param recognizeInfo 识别到的其他信息,包含活体值、年龄、性别、人脸角度等信息
         * @return 人脸绘制框上成功时绘制的文字
         */
        override fun onRecognized(
            bean: FaceFeatureDataBean,
            similar: Float,
            recognizeInfo: RecognizeInfo
        ): String? {
            println("人脸比对成功-相似度:" + similar + ",recognizeInfo:" + recognizeInfo.toString())
            return "识别成功"
        }

        /**
         * 识别相似度阈值,有效值范围(0.0f,1.0f)
         */
        override fun similarThreshold(): Float {
            return 0.8f
        }

        /**
         * 待比较人脸数据集合,需要自己封装传入
         */
        override fun faceFeatureList(): List<FaceFeatureDataBean> {
            return listOf()
        }

    })
        .setDetectFaceOrient(DetectFaceOrient.ASF_OP_0_ONLY)//人脸检测角度
        .enableRecognize(true)//是否需要识别
        .setDetectFaceScaleVal(16)//用于数值化表示的最小人脸尺寸,该尺寸代表人脸尺寸相对于图片长边的占比。
        .setLivenessType(LivenessType.RGB)//活体检测类型,[LivenessType.IR] 目前不支持
        .setRgbLivenessThreshold(0.6f)//设置RGB可见光活体阈值
        .setIrLivenessThreshold(0.7f)//设置IR红外活体阈值
        .enableImageQuality(true)//是否启用图像质量阈值
        .setImageQualityThreshold(0.35f)//图像质量阈值
        .setDetectFaceMaxNum(1)//最大需要检测的人脸个数
        .recognizeKeepMaxFace(true)//是否仅识别最大人脸
        .enableRecognizeAreaLimited(false)//是否限制识别区域
        .setRecognizeAreaLimitedRatio(0.7f)//识别区域屏占比,正方形,位置在预览画面正中间
        .setDetectInfo(
            DetectInfo(
                age = false,
                gender = false,
                angle = false
            )
        )//相关属性检测,年龄、性别、3d角度这个功能依附于 [livenessType],需要为[LivenessType.RGB],选择需要启用的,会占用额外的内存,可能影响识别速度
        .setRgbCameraFcing(CameraFacing.BACK)//彩色RGB摄像头类型
        .setIrCameraFcing(CameraFacing.FRONT)//红外IR摄像头类型,目前不支持
        .setPreviewSize(PreviewSize(1280, 720))//摄像头预览分辨率,彩色摄像头和红外都支持的预览分辨率
        .setDrawFaceRect(
            DrawFaceRect(
                isDraw = true,
                unknownColor = Color.YELLOW,
                failedColor = Color.RED,
                successColor = Color.GREEN
            )
        )//人脸识别框绘制相关
        .isMirror(true)//预览画面是否镜像
        .setExtractFeatureErrorRetryCount(3)//人脸特征提取出错重试次数,超过置为失败状态
        .setRecognizeFailedRetryInterval(1000)//人脸识别失败后,重试间隔,单位:毫秒
        .setLivenessErrorRetryCount(3)//体检测出错重试次数
        .setLivenessFailedRetryInterval(1000)//活体检测失败后,重试间隔,单位:毫秒
        .enableCompareFace(false)//是否启用人脸比对
        .setOnErrorCallback(object : OnErrorCallback {
            override fun onError(type: FaceErrorType, errorCode: Int, errorMessage: String) {
                Log.e(
                    "MainActivity",
                    "onError: FaceErrorType:${type},errorCode:${errorCode},errorMessage:${errorMessage}"
                )
            }
        })//识别中错误回调
        .build()
    //设置人脸相关参数,如果确认人脸已经激活且直接进行人脸识别则设备true
    faceCameraView.setConfiguration(configuration, false)
    faceCameraView.setLifecycleOwner(this)
    //在合适的地方调用此方法,设置为true且人脸已激活才会提交预览数据
    faceCameraView.enableFace(true)

虹软人脸激活相关 FaceActive

  • 在线激活
FaceActive.activeOnline(context: Context, activeKey: String, appId: String, sdkKey: String, callback: OnActiveCallback?)
  • 离线激活
FaceActive.activeOffline(context: Context, filePath: String,callback: OnActiveCallback?)
  • 是否已经激活人脸
FaceActive.isActivated(context: Context): Boolean
  • 生成设备指纹信息,用于离线激活(请自行获取内存卡读写权限)
FaceActive.generateActiveDeviceInfo(context: Context, saveFilePath: String, callback: OnActiveDeviceInfoCallback?)

人脸比对和生成特征码相关 FaceServer (可以自行封装成单例模式)

  • 初始化
/**
  * 初始化人脸引擎
  * @param context 上下文
  * @param faceOrient 人脸检测角度,单一角度检测,不支持[DetectFaceOrient.ASF_OP_ALL_OUT]
  * [DetectFaceOrient.ASF_OP_0_ONLY]
  * [DetectFaceOrient.ASF_OP_90_ONLY]
  * [DetectFaceOrient.ASF_OP_180_ONLY]
  * [DetectFaceOrient.ASF_OP_270_ONLY]
  * @param detectFaceScaleVal 识别的最小人脸比例,取值范围[2,32]
  */
fun init(context: Context, faceOrient: DetectFaceOrient = DetectFaceOrient.ASF_OP_0_ONLY, @IntRange(from = 2, to = 32) detectFaceScaleVal: Int = 16) 
  • 比对人脸 1:N
/**
  * 比对人脸 1:N
  * @param faceFeature 要比对的人脸特征码
  * @param features 待比对的人脸列表
  * 
  * @return null:说明比对列表为空或者人脸引擎出错;返回相似度最大的[features]中的数据
  */
fun compareFaceFeature(faceFeature: FaceFeature, features: List<FaceFeatureDataBean>): CompareResult?
  • 比对人脸 1:1
/**
  * 比对两组特征码 1:1
  * 
  * @return 返回相似度
  */
fun compareFaceFeature(feature1: ByteArray, feature2: ByteArray): Float
  • 通过Bitmap提取特征码
/**
  * 通过Bitmap提取特征码
  * 最好在子线程运行
  * 
  * @return 特征码
  */
fun extractFaceFeature(bitmap: Bitmap?): ByteArray?
  • 销毁资源
/**
  * 销毁资源
  */
fun destroy()

人脸特征码转换工具 FeatureCovertUtil

  • ByteArray特征码数据转为16进制字符串
FeatureCovertUtil.byteArrayToHexString(feature: ByteArray): String
  • 16进制字符串转为ByteArray特征码数据
FeatureCovertUtil.hexStringToByteArray(hexStr: String): ByteArray

Github传送门

原文地址:https://www.cnblogs.com/qq714081644/p/14501408.html