# ArcFace **Repository Path**: qq714081644/ArcFace ## Basic Information - **Project Name**: ArcFace - **Description**: 基于虹软人脸识别SDK V3.1,封装人脸识别方法 - **Primary Language**: Kotlin - **License**: MIT - **Default Branch**: master - **Homepage**: https://github.com/shenbengit/ArcFace - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-06-08 - **Last Updated**: 2023-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ArcFace 基于[虹软人脸识别](https://ai.arcsoft.com.cn/)增值版Android SDK V3.1,封装人脸识别方法。 > [增值版Android SDK V3.1文档](https://github.com/shenbengit/ArcFace/blob/master/ARCSOFT_ARC_FACE_DEVELOPER'S_GUIDE_V3.1.pdf) > [虹软人脸识别4.0封装](https://github.com/shenbengit/ArcFace4.0) ## 效果展示 限制识别区域 ![ArcFace](https://github.com/shenbengit/ArcFace/blob/master/screenshots/ArcFace01.gif) 不限制识别区域 ![ArcFace](https://github.com/shenbengit/ArcFace/blob/master/screenshots/ArcFace02.gif) ### 将JitPack存储库添加到您的项目中(项目根目录下build.gradle文件) ```gradle allprojects { repositories { ... maven { url 'https://jitpack.io' } } } ``` ### 添加依赖 [![](https://jitpack.io/v/shenbengit/ArcFace.svg)](https://jitpack.io/#shenbengit/ArcFace) ```gradle android { ... defaultConfig { ... ndk { // 设置支持的SO库架构,仅支持armeabi-v7a、arm64-v8a,若想减小APK体积,可只引用对应的SO库架构 abiFilters 'armeabi-v7a', 'arm64-v8a' } } } dependencies { implementation 'com.github.shenbengit:ArcFace:Tag' } ``` 项目内依赖[Fotoapparat](https://github.com/RedApparat/Fotoapparat)用于摄像头预览。 ## 使用事例 布局示例 ```Xml ``` 代码示例 > 基本使用 ```kotlin val faceCameraView: FaceCameraView = findViewById(R.id.faceCameraView) val configuration = FaceConfiguration.builder(this, object : OnRecognizeCallback { /** * 检测到的人脸数量 *

运行在子线程

* * @param num 人脸数量 * @param faceIds faceId */ override fun detectFaceNum(num: Int, faceIds: List) { } /** * 有人,仅在有变化时调用一次 *

运行在子线程

*/ override fun someone() { } /** * 无人,仅在有变化时调用一次 *

运行在子线程

*/ override fun nobody() { } /** * 如果不想自动比对的话,可以通过此接口返回识别到的人脸特征码,仅在[FaceConfiguration.enableCompareFace] 为false时才会回调 *

运行在子线程

* * @param faceId 人脸Id * @param feature 人脸特征码 * @param recognizeInfo 识别到的其他信息,包含活体值、年龄、性别、人脸角度等信息 * @param camera 预览数据 * @param width 预览数据宽度 * @param height 预览数据高度 */ override fun onGetFaceFeature( faceId: Int, feature: ByteArray, recognizeInfo: RecognizeInfo, nv21: ByteArray, width: Int, height: Int ) { } /** * 识别成功后结果回调,仅回调一次,直到人脸离开画面 *

运行在子线程

* * @param bean 识别的数据 [faceFeatureList] 的子项 * @param similar 识别通过的相似度 * @param recognizeInfo 识别到的其他信息,包含活体值、年龄、性别、人脸角度等信息 * @param camera 预览数据 * @param width 预览数据宽度 * @param height 预览数据高度 * * @return 人脸绘制框上成功时绘制的文字 */ override fun onRecognized( bean: FaceFeatureDataBean, similar: Float, recognizeInfo: RecognizeInfo, nv21: ByteArray, width: Int, height: Int ): String? { println("人脸比对成功-相似度:" + similar + ",recognizeInfo:" + recognizeInfo.toString()) return "识别成功" } /** * 识别相似度阈值,有效值范围(0.0f,1.0f) */ override fun similarThreshold(): Float { return 0.8f } /** * 待比较人脸数据集合,需要自己封装传入 */ override fun faceFeatureList(): List { return listOf() } }) .setDetectFaceOrient(DetectFaceOrient.ASF_OP_0_ONLY)//人脸检测角度 .enableRecognize(true)//是否需要识别 .setDetectFaceScaleVal(30)//用于数值化表示的最小人脸尺寸,该尺寸代表人脸尺寸相对于图片长边的占比。 .setLivenessType(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 = true, gender = true, angle = true ) )//相关属性检测,年龄、性别、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, rgbOffsetX = 0, rgbOffsetY = 0, irOffsetX = -15, irOffsetY = 0, ) )//人脸识别框绘制相关 .isRgbMirror(true)//RGB预览画面是否镜像 .isIrMirror(false)//IR预览画面是否镜像 .setExtractFeatureErrorRetryCount(3)//人脸特征提取出错重试次数,超过置为失败状态 .setRecognizeFailedRetryInterval(1000)//人脸识别失败后,重试间隔,单位:毫秒 .setLivenessErrorRetryCount(3)//体检测出错重试次数 .setLivenessFailedRetryInterval(1000)//活体检测失败后,重试间隔,单位:毫秒 .enableCompareFace(true)//是否启用人脸比对 .setViewfinderText("请将人脸置于识别框内") .setViewfinderGravity(ViewfinderView.TextLocation.BOTTOM) .setOnErrorCallback(object : OnErrorCallback { override fun onError(type: FaceErrorType, errorCode: Int, errorMessage: String) { } })//识别中错误回调 .build() //设置人脸相关参数,如果确认人脸已经激活且直接进行人脸识别则设备true faceCameraView.setConfiguration(configuration, false) faceCameraView.setLifecycleOwner(this) //摄像头开启异常监听 faceCameraView.setOnCameraListener(object : OnCameraListener { override fun onRgbCameraError(exception: Exception) { } override fun onIrCameraError(exception: Exception) { } }) //在合适的地方调用此方法,设置为true且人脸已激活才会提交预览数据 faceCameraView.enableFace(true) ``` > 虹软人脸激活相关 FaceActive * 在线激活 ```kotlin FaceActive.activeOnline(context: Context, activeKey: String, appId: String, sdkKey: String, callback: OnActiveCallback?) ``` * 离线激活 ```kotlin FaceActive.activeOffline(context: Context, filePath: String,callback: OnActiveCallback?) ``` * 是否已经激活人脸 ```kotlin FaceActive.isActivated(context: Context): Boolean ``` * 生成设备指纹信息,用于离线激活(请自行获取内存卡读写权限) ```kotlin FaceActive.generateActiveDeviceInfo(context: Context, saveFilePath: String, callback: OnActiveDeviceInfoCallback?) ``` > 人脸比对和生成特征码相关 FaceServer (可以自行封装成单例模式) * 初始化 ```kotlin /** * 初始化人脸引擎 * @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 ```kotlin /** * 比对人脸 1:N * @param faceFeature 要比对的人脸特征码 * @param features 待比对的人脸列表 * * @return null:说明比对列表为空或者人脸引擎出错;返回相似度最大的[features]中的数据 */ fun compareFaceFeature(faceFeature: FaceFeature, features: List): CompareResult? ``` * 比对人脸 1:1 ```kotlin /** * 比对两组特征码 1:1 * * @return 返回相似度 */ fun compareFaceFeature(feature1: ByteArray, feature2: ByteArray): Float ``` * 通过Bitmap提取特征码 ```kotlin /** * 通过Bitmap提取特征码 * 最好在子线程运行 * * @return 特征码 */ fun extractFaceFeature(bitmap: Bitmap?): ByteArray? ``` * 通过nv21数据提取特征码 ```kotlin /** * 摄像机预览数据提取人脸特征码 * 最好在子线程运行 * @param nv21 摄像机数据 * @param width 预览宽度 * @param height 预览高度 * * @return 特征码 */ fun extractFaceFeature(nv21: ByteArray, width: Int, height: Int): ByteArray? ``` * 销毁资源 ```kotlin /** * 销毁资源 */ fun destroy() ``` > 人脸检测 FaceDetect (可以自行封装成单例模式) * 初始化 ```kotlin /** * 初始化人脸引擎 * @param context 上下文 * @param enableImageQuality 启用图片质量检测 * @param detectFaceMaxNum 检测人脸数量 * @param detectFaceScaleVal 识别的最小人脸比例,取值范围[2,32] * @param detectFaceOrient 人脸检测角度 * [DetectFaceOrient.ASF_OP_0_ONLY] * [DetectFaceOrient.ASF_OP_90_ONLY] * [DetectFaceOrient.ASF_OP_180_ONLY] * [DetectFaceOrient.ASF_OP_270_ONLY] * [DetectFaceOrient.ASF_OP_ALL_OUT] */ fun init( context: Context, enableImageQuality: Boolean = false, detectFaceMaxNum: Int, detectFaceScaleVal: Int = 16, detectFaceOrient: DetectFaceOrient = DetectFaceOrient.ASF_OP_0_ONLY ) ``` * 人脸检测回调 ```kotlin /** * 人脸检测回调 */ fun setFaceDetectCallback(callback: FaceDetectCallback?) ``` * 销毁资源 ```kotlin * 传入预览数据 /** * 传入预览数据 */ fun onPreviewFrame(rgbNV21: ByteArray,previewWidth: Int,previewHeight: Int) ``` * 销毁资源 ```kotlin /** * 销毁资源 */ fun destroy() ``` > 人脸特征码转换工具 FeatureCovertUtil * ByteArray特征码数据转为16进制字符串 ```kotlin FeatureCovertUtil.byteArrayToHexString(feature: ByteArray): String ``` * 16进制字符串转为ByteArray特征码数据 ```kotlin FeatureCovertUtil.hexStringToByteArray(hexStr: String): ByteArray ```