更新记录

1.0.0(2026-11-12)

  • 首个版本:基于虹软 ArcFace 5.0 瑞芯微(RK3568 / RK3588 等 RK 主板)SDK 的离线人脸识别插件 (注册 / 检索 / 比对均在本机完成,推理走主板 RKNN)
  • 原生侧为虹软 RK 官方 SDK(com.zy.sdk:arc-face-rk:1.0.0),仅 arm64-v8a
  • 激活与引擎:requestPermissions / getDeviceFinger / activeOnline / activeOffline / isActivated / customFaceDataPath / init(options)(path 指定人脸库目录)
  • 图片能力:getImageFace / imageFaceRegister / batchRegister / faceCompare(1:N)
  • 1:1 比对:faceCompare11(两张图片)/ faceCompareWithUser(图片 vs 库内人员)/ compareFeature(特征), 统一返回 similar / pass / threshold
  • 人脸库:增删查清 + 本地持久化(特征与注册头像落盘,init 自动回灌)
  • nvue 相机组件 <zy-ArcFaceRK>:CameraX 预览、人脸框、活体、1:N 识别、相机内注册、前后摄像头切换
  • demo:pages/arcface-rk/arcface-rk.vue(API)、pages/arcface-rk/arcface-rk-camera.nvue(组件)

平台兼容性

uni-app(4.72)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Safari app-vue app-vue插件版本 app-nvue app-nvue插件版本 Android Android插件版本 iOS 鸿蒙
√ 1.0.0 √ 1.0.0 × × √ 1.0.0 √ 1.0.0 5.0 1.0.0 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × - × ×

uni-app x(4.72)

Chrome Safari Android Android插件版本 iOS 鸿蒙 微信小程序
- - 5.0 1.0.0 - - -

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × √ ×

zy-ArcFaceRK

安卓虹软 ArcFace 5.0(瑞芯微 RK 主板 / RKNN 版)离线人脸识别 UTS 插件:本地注册、本地检索、本地比对,全程无需联网推理。

特性

  • 激活:在线激活(activeKey + appId + sdkKey)、离线激活(.dat 授权文件)、设备指纹、激活状态查询
  • 人脸库(本地持久化):图片注册、批量注册、删除、清空、按 id 查询、全部查询、数量统计
  • 图片能力:单图人脸信息(年龄 / 性别 / 口罩 / 活体 / 3D 角度 / 人脸框)、单图注册、1:N 比对
  • 1:1 比对:两张图片比对、图片与库内指定人员比对、两个特征直接比对(均返回相似度 + 是否达标)
  • 相机组件:CameraX 预览 + 实时人脸框 + 活体检测 + 1:N 识别 + 相机内注册 + 自定义提示文案 + 前后摄像头切换
  • 无需联网识别:推理全部在本机完成,特征与人脸头像只保存在应用私有目录

平台支持

平台 支持
Android(uni-app vue2 / vue3) ✅
Android(uni-app x) ✅
iOS / Web / 小程序 ❌
  • minSdkVersion:21
  • 架构:仅 arm64-v8a(虹软 RK 版只提供 64 位 so,不支持 32 位设备)
  • 运行环境:RK3568 / RK3588 等瑞芯微主板,板卡固件需自带 librknnrt.so (RKNN Runtime ≥ 1.4.0,虹软 RK 版 so 直接 link 该库,缺失时引擎初始化失败)

安装

  1. 把 zy-ArcFaceRK 整个目录放入项目的 uni_modules/;
  2. 由于插件带原生 so 与三方 SDK,标准基座无法使用,必须打自定义基座或云打包;
  3. config.json 已声明三方依赖(CameraX 等)与所需权限(相机 / 网络 / 手机状态 / 媒体读取), 无需额外配置。

体积提示:人脸 SDK 约 46MB(libarcsoft_face.so 约 50MB,模型已编译进 so,只有 arm64-v8a), 插件目录本身不含二进制,构建时自动拉取。

权限说明:targetSdkVersion >= 33 时不再申请 READ_EXTERNAL_STORAGE(系统会直接抛 IllegalArgumentException),requestPermissions 会按 targetSdkVersion 自动改用 READ_MEDIA_*。

激活流程

  1. 调用 requestPermissions 拿到所需运行时权限;
  2. 调用 getDeviceFinger 拿到设备指纹;
  3. 到 虹软开放平台 创建应用,用设备指纹 + 包名申请 appId / sdkKey / activeKey;
  4. 调用 activeOnline({ appId, sdkKey, activeKey }) 激活(同一 activeKey 有激活次数限制,成功后可不再调用);
  5. 调用 init({ path }) 初始化引擎(组件内也会自动初始化;path 可选,用于指定人脸库目录)。

Module API

所有方法都是 (options?, callback) 风格,回调 res = { code, message, data },code === 0 表示成功。

方法 参数 返回 data 说明
requestPermissions(callback) - grantedList / deniedList / doNotAskAgain 申请相机、手机状态、存储权限
getDeviceFinger(callback) - info 设备指纹(申请激活码用)
activeOnline(options, callback) activeKey appId sdkKey - 在线激活
activeOffline(options, callback) path - 离线激活(.dat 文件路径)
isActivated(callback) - isActivated 是否已激活
customFaceDataPath(options, callback) path - 自定义人脸库目录(须在 init 之前;也可直接用 init 的 path)
init(options, callback) path? version count 初始化引擎并加载人脸库(幂等);path 可在首次初始化时指定人脸库目录
getImageFace(options, callback) url list: ArcFaceImageFaceInfo[] 图片人脸信息(年龄/性别/口罩/活体/3D 角度/人脸框)
imageFaceRegister(options, callback) url id? name? registerMultiple? user: ArcFaceRegisterFaceInfo 图片注册人脸
batchRegister(options, callback) list[{url,id?,name?}] registerMultiple? status success failed count progress user 批量注册(回调多次触发)
deleteFace(options, callback) id - 删除单个人脸(不存在返回 -106)
getFace(options, callback) id user(含 imageBase64) 查询单个人脸
getAllFace(callback) - list: ArcFaceRegisterFaceInfo[] 全部人脸(不含 base64,用 imagePath 自行读取)
getFaceCount(callback) - count 已注册人脸数量
clearFace(callback) - - 清空人脸库(特征 + 头像文件)
faceCompare(options, callback) url similar? user + similar 图片 1:N 比对(默认阈值 0.85)
faceCompare11(options, callback) url url2 similar? similar pass threshold 两张图片 1:1 比对
faceCompareWithUser(options, callback) url id similar? similar pass threshold + user 图片与库内指定人员 1:1 比对(id 未注册返回 -106)
compareFeature(options, callback) feature1 feature2 similar? similar pass threshold 两个特征 Base64 的 1:1 比对(无需图片)

url 支持:本地绝对路径、file://、content://(相册选择)、http(s)://、base64(可带 data:image/jpeg;base64, 前缀)。

数据结构

type ArcFaceImageFaceInfo = {
  age: number        // -1 未知
  gender: number     // 1 男 / 0 女 / -1 未知(虹软原始值)
  mask: number       // 1 佩戴口罩 / 0 未佩戴 / -1 未知
  liveness: number   // 1 真人 / 0 非真人 / -1 未知
  face3D: { yaw: number, roll: number, pitch: number }
  face: { top: number, bottom: number, left: number, right: number, width: number, height: number }
}

type ArcFaceRegisterFaceInfo = {
  userId: string
  userName: string
  faceId: number      // 特征在引擎内的 id
  imagePath: string   // 注册头像本地路径
  registerTime: number
  featureData: string // 特征 Base64
  imageBase64?: string
}

示例

import {
  requestPermissions, getDeviceFinger, activeOnline, init,
  getImageFace, imageFaceRegister, faceCompare, getAllFace, getFaceCount
} from '@/uni_modules/zy-ArcFaceRK'

requestPermissions((res) => console.log('权限', res.code, res.data.grantedList))

getDeviceFinger((res) => {
  if (res.code === 0) console.log('设备指纹', res.data.info)
})

activeOnline({ appId: 'xxx', sdkKey: 'yyy', activeKey: 'zzz' }, (res) => {
  if (res.code !== 0) return uni.showToast({ title: res.message, icon: 'none' })
  init({}, (r) => console.log('引擎版本', r.data.version, '人脸库', r.data.count))
  // 需要自定义人脸库目录时:init({ path: '/sdcard/xxx/faceDB' }, (r) => {})
})

// 图片注册
imageFaceRegister({ url: '/sdcard/face/zhangsan.jpg', id: '1001', name: '张三' }, (res) => {
  console.log(res.code, res.data.user)
})

// 1:N 比对
faceCompare({ url: '/sdcard/face/test.jpg', similar: 0.85 }, (res) => {
  if (res.code === 0) console.log('命中', res.data.user.userName, res.data.similar)
})

1:1 比对

三种用法共用一套返回语义:比对流程本身成功就返回 code === 0,是否同一人由 data.pass 决定 (等价于 data.similar >= data.threshold)。只有取图失败、未检出人脸、提特征失败才返回错误码 (-102 未发现人脸、-10002 文件不存在、-10003 url 有误、-106 id 未注册)。

import { faceCompare11, faceCompareWithUser, compareFeature } from '@/uni_modules/zy-ArcFaceRK'

// 两张图片各取面积最大的人脸比对
faceCompare11({ url: '/sdcard/a.jpg', url2: '/sdcard/b.jpg', similar: 0.85 }, (res) => {
  if (res.code !== 0) return console.log('比对失败', res.message)
  console.log('相似度', res.data.similar, res.data.pass ? '同一人' : '不是同一人')
})

// 现场照片 vs 工号对应的人(只比这一条记录,不走 1:N 检索,结果与人脸库规模无关)
faceCompareWithUser({ url: '/sdcard/live.jpg', id: '1001', similar: 0.85 }, (res) => {
  if (res.code === 0 && res.data.pass) console.log('核验通过', res.data.user.userName)
})

// 特征对特征(特征来自注册记录 / onFaceResult / 服务端下发)
compareFeature({ feature1: featureA, feature2: featureB, similar: 0.85 }, (res) => {
  console.log(res.data.similar, res.data.pass)
})

相机组件

只在 nvue 页面 中可用(page.nvue),标签即插件 id(SFC 模板中大小写敏感,须与插件 id 完全一致):

<zy-ArcFaceRK
  ref="camera"
  class="camera"
  :config="config"
  :auto-start="true"
  @onInitResult="onInitResult"
  @onFaceResult="onFaceResult"
  @onError="onError"></zy-ArcFaceRK>

属性

属性 类型 默认值 说明
config Object {} 相机 + 视频检测配置,见下表
auto-start Boolean true 原生视图就绪且拿到相机权限后自动开始预览

config.camera:

字段 默认值 说明
rotation 0 在帧旋转基础上额外旋转角度
facing 0 1 前置 / 0 后置
radius 0 预览圆角(px)
size [1280,720] 预览分辨率
screenLocked true 仅记录,不强制旋转屏幕
isHorizontalMirror false 是否水平镜像(前置摄像头始终按镜像显示)

config.video:

字段 默认值 说明
orient 360 检测角度(引擎按全角度 ALL_OUT 处理)
isContraryX / isContraryY false 人脸框与画面方向相反时翻转坐标
similar 0.8 识别阈值
liveness true 是否活体检测
showFaceInfo true 是否解析年龄 / 性别 / 口罩
livenessParams {rgb:0.5, ir:0.5} 活体阈值
showFaceResultNotice true 是否显示人脸上方提示
faceSize 0 人脸框宽度小于该值不识别(0 不限制)
isKeepMaxFace true 单人脸识别
maxDetectFaces 1 最大识别人脸数
drawFaceBorder true 是否绘制人脸框
compareImage true 识别成功是否返回当前人脸 base64
failImage false 识别失败是否返回图片 base64
isOutRecognize true 识别后需人脸移出画面才能再次识别
continueTime 3 isOutRecognize=false 时的识别间隔(秒)
isRegisterImageBase64 true 是否返回库内注册头像 base64

方法

所有方法最后一个参数为 callback(res),res = { code, message, data }。

方法 参数 说明
start(callback) - 开始预览
stop(callback) - 停止预览(触发 onCameraClosed)
switchCamera(callback) - 切换前后摄像头(触发 onCameraConfigurationChanged)
closeFace(callback) - 关闭人脸检测(预览保留)
openFace(callback) - 开启人脸检测
getCameraData(callback) - data.cameraId、data.supportedPreviewSizesJson([{width,height}])
register(options, callback) id? name? registerMultiple? 注册当前画面的人脸
setFaceResult(options, callback) trackId message 自定义某个人脸的识别成功文案
release() - 释放相机资源(组件卸载会自动调用)

事件

事件 detail
onInitResult { status, code, message }
onCameraOpened {}
onCameraClosed {}
onCameraConfigurationChanged { cameraID, displayOrientation }
onFaceResult ArcFaceFaceResultDetail(见下)
onError { code, message, data }

onFaceResult.detail:trackId status code message userId userName faceId imagePath registerTime similar faceSize featureData imageBase64 compareImageBase64 registerImageBase64 failFaceImageBase64 failImageBase64。

组件示例

<template>
  <view style="flex:1;">
    <zy-ArcFaceRK ref="camera" style="width:750rpx;height:800rpx;" :config="config"
      @onInitResult="onInitResult" @onFaceResult="onFaceResult"></zy-ArcFaceRK>
    <button @click="registerFace">注册当前人脸</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      config: {
        camera: { facing: 1, size: [1280, 720] },
        video: { similar: 0.8, liveness: true, isKeepMaxFace: true, drawFaceBorder: true }
      }
    }
  },
  methods: {
    onInitResult(e) { console.log('初始化', e.detail.status) },
    onFaceResult(e) {
      const d = e.detail
      console.log(d.status ? '识别成功 ' + d.userName : '未匹配 code=' + d.code)
    },
    registerFace() {
      this.$refs.camera.register({ id: '1001', name: '张三' }, (res) => {
        console.log('注册', res.code, res.message)
      })
    }
  }
}
</script>

状态码

code 说明
0 成功
-1 通用错误码
-100 注册时带口罩
-101 裁剪图片错误
-102 未发现人脸
-103 注册失败
-104 已注册(registerMultiple=false 且同 id 重复注册)
-105 存在相同人脸(registerMultiple=false 且同一张脸换 id 注册)
-106 人脸未注册
-107 未初始化
-10001 缺少必要的权限
-10002 文件不存在
-10003 url 地址有误
-10004 相机不可用
-10005 SDK 未激活
五位数(如 90126) 虹软 SDK 原始错误码,可查虹软官方错误码表

注意事项

  1. 人脸库持久化:虹软 SDK 的特征库只在内存,插件把特征(Base64)与注册头像持久化到 Android/data/<包名>/files/Pictures/faceDB(faces.json + registerFaces/),每次 init 自动回灌; 需要换目录用 init({ path })(等价于 init 之前调 customFaceDataPath), 引擎初始化之后再传不同目录会返回 -1(特征已回灌内存,换目录须释放引擎或重启应用)。
  2. 激活与 init 的关系:未激活时 init 可能返回虹软错误码,识别也会失败;请先激活。
  3. 引擎单例:整个进程只有一个引擎实例(module API 与组件共用),调用已在内部串行化; 组件未初始化时会自动 init。
  4. 性能:默认以 1280×720 作为分析分辨率,图片解码最大边 1280;偏远/低端机可把 config.camera.size 降到 [640,480]。
  5. 识别频次:默认 isOutRecognize=true(同一张脸只回调一次,移出画面后才再次识别); 需要定频刷新时置为 false 并调整 continueTime。
  6. 性别取值是虹软原始值(1 男 / 0 女),与部分文档描述的 0/1 相反,业务侧按此判断。
  7. RK 版专有约束:
    • 只支持 arm64-v8a(config.json 的 abis 已固定为单个),打包时请只勾选 arm64-v8a, 勾 32 位会因缺少 so 失败;
    • 引擎依赖主板固件提供的 librknnrt.so(RKNN Runtime ≥ 1.4.0),init 返回异常错误码时 先用 adb shell ls /vendor/lib64/librknnrt.so 确认;模拟器与无 NPU 的普通手机无法跑 RK 版;
    • 激活码要在虹软平台按 RK 板卡的设备指纹 + 包名 单独申请,非 RK 主板的授权不能用于本插件。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.CAMERA(相机预览识别)、android.permission.INTERNET(在线激活/远程图片)、android.permission.ACCESS_NETWORK_STATE、android.permission.READ_PHONE_STATE(设备指纹)、android.permission.READ_EXTERNAL_STORAGE、android.permission.WRITE_EXTERNAL_STORAGE(读取相册图片与保存注册图)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

全部推理在本机完成,人脸特征与注册图片仅保存在应用私有目录;仅在线激活与传入 http(s) 图片地址时会联网

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。