【HarmonyOS 5】VisionKit人脸活体检测详解

GeorgeGcs
• 阅读 8

##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、VisionKit人脸活体检测是什么? VisionKit是HamronyOS提供的场景化视觉服务工具包。 华为将常见的解决方案,通常需要三方应用使用SDK进行集成。华为以Kit的形式集成在HarmoyOS系统中,方便三方应用快速开发和赋能。 而VisionKit中包含人脸活体检测的功能接口interactiveLiveness 。人脸活体检测见名知意,主要是为了检测当前人是否为活人本人,而不是照片,硅胶面具,AI视频仿真的可能。 虽然该算法接口已通过中金金融(CECA)认证。但是官方还是建议添加额外的安全措施后,在使用该人脸检测接口,尽量不要直接使用在高风险性的支付和金融场景中。推荐在低危险场景,例如登录,考勤,实名认证等业务场景进行使用。 需要注意的是,人脸活体检测,不支持模拟器和预览器。 详情参见官方接口: https://developer.huawei.com/consumer/cn/doc/harmonyos-references/vision-interactive-liveness https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/vision-interactiveliveness

二、人脸活体检测如何使用? 人脸活体检测功能interactiveLiveness ,起始版本为 5.0.0 (API12),可通过@kit.VisionKit模块导入,支持动作活体检测模式(INTERACTIVE_MODE),动作数量可配置为 3 或 4 个,包含点头、张嘴、眨眼等 6 种动作。 通过InteractiveLivenessConfig配置检测模式、跳转路径、语音播报等参数,提供startLivenessDetection和getInteractiveLivenessResult接口,能抵御照片、视频等攻击,适用于身份验证场景,需申请ohos.permission.CAMERA相机权限,错误码可参考 Vision Kit 错误码文档。 Vision Kit 错误码文档 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/vision-error-code

  1. 核心接口为人脸页面唤起接口: interactiveLiveness.startLivenessDetection,该接口需要配置config进行设置人脸的模式,动作等操作。 (1) Promise 方式:仅返回跳转结果(boolean)。

interactiveLiveness.startLivenessDetection(routerOptions).then((DetectState: boolean) => { hilog.info(0x0001, "LivenessCollectionIndex", Succeeded in jumping.); }).catch((err: BusinessError) => { hilog.error(0x0001, "LivenessCollectionIndex", Failed to jump. Code:${err.code},message:${err.message}); })

(2) Promise + 回调方式:同时返回跳转结果和检测结果(仅适用于 BACK_MODE)。

interactiveLiveness.startLivenessDetection(routerOptions, (err: BusinessError, result: interactiveLiveness.InteractiveLivenessResult | undefined) => { if(err.code !== 0 && !result) { hilog.error(0x0001, "LivenessCollectionIndex", Failed to detect. Code:${err.code},message:${err.message}); return; } hilog.info(0x0001, 'LivenessCollectionIndex', Succeeded in detecting result:${result}); }) 2. InteractiveLivenessConfig配置接口: 调用人脸活体检测,需要填入该配置对象,进行相关设置,参数见以下表格:

  1. 检测模式(DetectionMode) 名称 值 说明 SILENT_MODE "SILENT_MODE" 静默活体检测(暂未支持) INTERACTIVE_MODE "INTERACTIVE_MODE" 动作活体检测(默认模式)
  2. 动作数量(ActionsNumber) 名称 值 说明 ONE_ACTION 1 随机1个动作(暂未支持) TWO_ACTION 2 随机2个动作(暂未支持) THREE_ACTION 3 随机3个动作([眨眼,注视]不同时存在且不相邻,相邻动作不重复) FOUR_ACTION 4 随机4个动作(眨眼仅1次,注视最多1次,[眨眼,注视]不相邻,相邻动作不重复)
  3. 跳转模式(RouteRedirectionMode) 名称 值 说明 BACK_MODE "back" 检测完成后调用router.back返回上一页 REPLACE_MODE "replace" 检测完成后调用router.replaceUrl跳转(默认模式)
  4. 配置项(InteractiveLivenessConfig) 名称 类型 必填/可选 说明 isSilentMode DetectionMode 必填 检测模式(默认INTERACTIVE_MODE) actionsNum ActionsNumber 可选 动作数量(3或4,默认3) successfulRouteUrl string 可选 检测成功跳转路径(未填则用系统默认页面) failedRouteUrl string 可选 检测失败跳转路径(未填则用系统默认页面) routeMode RouteRedirectionMode 可选 跳转模式(默认REPLACE_MODE) challenge string 可选 安全摄像头场景挑战值(16-128位,空值表示不使用) speechSwitch boolean 可选 语音播报开关(默认开启) isPrivacyMode boolean 可选 隐私模式(需申请ohos.permission.PRIVACY_WINDOW权限,默认关闭) 人脸活体检测的配置项对象除了isSilentMode是必填,其他属性均为可选: import { interactiveLiveness } from '@kit.VisionKit';

let isSilentMode = "INTERACTIVE_MODE" as interactiveLiveness.DetectionMode; let routeMode = "replace" as interactiveLiveness.RouteRedirectionMode; let actionsNum = 3 as interactiveLiveness.ActionsNumber; let routerOptions: interactiveLiveness.InteractiveLivenessConfig= { isSilentMode: isSilentMode, routeMode: routeMode, actionsNum: actionsNum, failedRouteUrl: "pages/FailPage", successfulRouteUrl: "pages/SuccessPage" } 3. getInteractiveLivenessResult获取人脸活体检测结果: 在调用人脸活体检测成功后,可通过该接口获取检测结果。结果内容如下表格所示: 名称 类型 只读 可选 说明 livenessType LivenessType 是 否 活体检测模式,值包括:

  • 0(INTERACTIVE_LIVENESS,动作活体检测)
  • 1(SILENT_LIVENESS,静默活体检测,暂未支持)
  • 2(NOT_LIVENESS,非活体) mPixelMap image.PixelMap 是 是 检测成功后返回的最具有活体特征的图片(如包含人脸关键点的特征图),检测失败时无此数据。 securedImageBuffer ArrayBuffer 是 是 安全摄像头场景下返回的安全流数据(加密后的图像特征数据),非安全场景无此数据。 certificate Array 是 是 安全摄像头场景下返回的证书链(用于验证安全流的合法性),非安全场景无此数据。 let successResult = interactiveLiveness.getInteractiveLivenessResult(); successResult.then(data => { hilog.info(0x0001, "LivenessCollectionIndex", Succeeded in detecting.); }).catch((err: BusinessError) => { hilog.error(0x0001, "LivenessCollectionIndex", Failed to detect. Code:${err.code},message:${err.message}); })

三、DEMO源码示例 import { interactiveLiveness } from '@kit.VisionKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { abilityAccessCtrl, common } from '@kit.AbilityKit';

@Entry @Component struct FaceLivenessDemo { @State userGrant: boolean = false // 权限状态 @State detectionResult: string = "" // 检测结果展示 @State actionCount: interactiveLiveness.ActionsNumber = interactiveLiveness.ActionsNumber.THREE_ACTION; // 动作数量(3或4) @State speechEnabled: boolean = true // 语音播报开关 // 表示人脸活体检测完成后使用router.back返回到上一页。 @State routeMode: interactiveLiveness.RouteRedirectionMode = interactiveLiveness.RouteRedirectionMode.BACK_MODE; // 跳转模式

// 权限申请逻辑 private async requestPermissions() { const context = getContext() as common.UIAbilityContext; const atManager = abilityAccessCtrl.createAtManager(); const results = await atManager.requestPermissionsFromUser(context, ["ohos.permission.CAMERA"]); this.userGrant = results.authResults.every(status => status === 0); }

// 检测配置生成 private generateDetectionConfig(): interactiveLiveness.InteractiveLivenessConfig { return { // 表示的是人脸活体检测模式,默认动作活体检测模式。 // INTERACTIVE_MODE表示动作活体检测模式。 isSilentMode: interactiveLiveness.DetectionMode.INTERACTIVE_MODE,

  // 表示动作活体检测的动作数量,数量范围3或4个,默认3个动作。随机生成,规则如下:
  //
  // 当actionsNum=3时,[眨眼,注视]组合中的动作元素不会同时存在并且相邻的动作元素不会相同。
  //
  // 当actionsNum=4时,眨眼动作元素有且仅有1次,注视动作元素最多出现1次,[眨眼,注视]组合中的动作元素不会相邻,相邻的动作元素不会相同。
  //
  // 该参数只有当isSilentMode是INTERACTIVE_MODE的时候有效。
  actionsNum: this.actionCount,
  // 表示人脸活体检测成功后跳转的页面路径。如果不填,系统有默认的检测成功页面。
  // successfulRouteUrl: "pages/result/success", // 自定义成功跳转路径(需提前创建页面)

  // 表示人脸活体检测失败后跳转的页面路径。如果不填,系统有默认的检测失败页面。
  // failedRouteUrl: "pages/result/fail", // 自定义失败跳转路径(需提前创建页面)

  routeMode: this.routeMode, // 跳转模式

  // 语音播报的开关。
  //
  // true表示开启语音播报。
  // false表示关闭语音播报。
  // 默认开启语音播报。
  speechSwitch: this.speechEnabled, // 语音播报控制

  // 挑战值。仅用于安全摄像头场景(对应initializeAttestContext方法中的“userData”字段)的活体检测。
  //
  // 使用安全摄像头场景的前提需要开通Device Security服务。
  //
  // 长度范围是16-128之间(challenge传空或者undefined表示不使用安全摄像头)。
  // challenge: "自定义挑战值1234567890abcdef", // 安全摄像头场景可选

  // 是否设置隐私模式。
  //
  // true:设置隐私模式。
  // false:不设置隐私模式。
  // 默认值为false。
  // isPrivacyMode: true // 隐私模式需额外权限 当设置隐私模式时,需要申请ohos.permission.PRIVACY_WINDOW权限。
};

}

// 启动检测 private async startDetection() { if (!this.userGrant) { this.detectionResult = "请先申请相机权限"; return; }

const config = this.generateDetectionConfig();

try {
  const jumpSuccess = await interactiveLiveness.startLivenessDetection(config);
  if (jumpSuccess) {
    hilog.info(0x0001, "Detection", "跳转检测页面成功");
    // 检测完成后获取结果(需在返回页面时调用)
    const result = await interactiveLiveness.getInteractiveLivenessResult();
    this.processResult(result);
  }
} catch (err) {
  const error = err as BusinessError;
  hilog.error(0x0001, "Detection", `检测失败: 错误码${error.code}, 信息${error.message}`);
  this.detectionResult = `检测异常:错误码${error.code}`;
}

}

// 结果处理 private processResult(result: interactiveLiveness.InteractiveLivenessResult) { let status = ""; let livenessType = result.livenessType; switch (livenessType) { case 0: // 动作活体检测成功 status = "活体检测通过"; // 可在此处处理特征图片或安全数据 break; case 2: // 非活体 status = "检测到非活体(照片/视频攻击)"; break; default: status = "检测结果异常"; } this.detectionResult = status; }

build() { Column({ space: 40 }) { // 权限申请按钮 Button(this.userGrant ? "权限已授权" : "申请相机权限") .fontSize(18) .margin(10) .padding(12) .backgroundColor(this.userGrant ? Color.Green : Color.Blue) .onClick(() => this.requestPermissions())

  // 动作数量选择
  Row({ space: 20 }) {
    Text("动作数量:")
      .fontSize(16)

    Button("3个动作")
      .backgroundColor(this.actionCount === 3 ? Color.Blue : Color.White)
      .border({ width: 1, color: Color.Gray })
      .onClick(() => this.actionCount = 3)

    Button("4个动作")
      .backgroundColor(this.actionCount === 4 ? Color.Blue : Color.White)
      .border({ width: 1, color: Color.Gray })
      .onClick(() => this.actionCount = 4)
  }

  // 语音播报开关
  Toggle({ type: ToggleType.Checkbox, isOn: this.speechEnabled })
    .onChange((isOn: boolean)=>{
      this.speechEnabled = isOn;
    })

  // 跳转模式选择
  Row({ space: 20 }) {
    Text("跳转模式:")
      .fontSize(16)

    Button("替换页面")
      .backgroundColor(this.routeMode === "replace" ? Color.Blue : Color.White)
      .border({ width: 1, color: Color.Gray })
      .onClick(() => {
        this.routeMode = interactiveLiveness.RouteRedirectionMode.REPLACE_MODE;
      })

    Button("返回上页")
      .backgroundColor(this.routeMode === "back" ? Color.Blue : Color.White)
      .border({ width: 1, color: Color.Gray })
      .onClick(() => {
        this.routeMode = interactiveLiveness.RouteRedirectionMode.BACK_MODE;
      })
  }

  // 启动检测按钮
  Button("开始人脸活体检测")
    .fontSize(20)
    .padding(16)
    .backgroundColor(Color.Orange)
    .onClick(() => this.startDetection())

  // 结果显示
  Text(this.detectionResult)
    .fontSize(16)
    .margin({
      top: 30
    })
    .foregroundColor(this.detectionResult.includes("通过") ? Color.Green : Color.Red)
}
.width("100%")
.height("100%")
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)

} } 注意:

  1. 人脸活体检测支持两种模式 INTERACTIVE_MODE(动作活体检测):默认模式,需用户完成 3 或 4 个随机动作(如眨眼、点头等),通过动作组合验证活体,规则限制避免相邻动作重复或特定组合(如眨眼和注视不相邻)。 SILENT_MODE(静默活体检测):暂未支持,无需用户做动作,通过其他技术(如微表情、光线反射)检测活体。
  2. 配置人脸活体检测的动作数量和跳转逻辑 通过InteractiveLivenessConfig中的actionsNum配置,可选值为 3(默认)或 4,3 个动作时(眨眼,注视) 不同时存在且不相邻,4 个动作时眨眼仅 1 次,注视最多 1 次。 通过routeMode配置跳转模式(BACK_MODE 返回上一页或 REPLACE_MODE 替换跳转,默认 REPLACE_MODE)。 successfulRouteUrl和failedRouteUrl设置成功 / 失败后的自定义跳转路径(未填则用系统默认页面)。
  3. 常见错误及处理: 201(Permission denied):未申请ohos.permission.CAMERA权限 1008301002(Route switching failed):路由配置错误,检查successfulRouteUrl/failedRouteUrl路径是否正确,或routeMode是否与页面路由匹配。 1008302000-1008302004(检测相关错误):检测过程中算法初始化失败、超时或动作不符合规则,可通过回调或 Promise 的 catch 捕获错误码,提示用户重新检测并检查动作合规性。
点赞
收藏
评论区
推荐文章
GeorgeGcs GeorgeGcs
16小时前
【HarmonyOS 5】AttributeModifier和AttributeUpdater区别详解
【HarmonyOS5】AttributeModifier和AttributeUpdater区别详解\鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、AttributeModifier和AttributeUpdater的定义和作用1
GeorgeGcs GeorgeGcs
9小时前
从“备胎”到领航者,鸿蒙操作系统的传奇进化
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财【HarmonyOS5】2019年,在全球科技产业的风云变幻中,华为正式推出了鸿蒙操作系统(HarmonyOS),这一消息如同一颗重磅炸弹,瞬间吸引了全世界的目光。彼时,外界对鸿蒙的诞生背
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙应用实现发票扫描、文档扫描输出PDF图片或者表格的功能
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言图(11)HarmonyOS系统提供的核心场景化视觉服务,旨在帮助开发者快速实现移动端文档数字化功能。其核心能力包括:扫描合同、票据、会议记录并保存为PDF分享。拍摄课堂PPT、书
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言在HarmonyOS5的应用开发模型中,featureAbility是旧版FA模型(FeatureAbility)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS NEXT】一键扫码功能
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财前言鸿蒙在api10之后,对系统api的基础上,封装了较为复杂功能的开发工具包,统一称之为Kit。这些Kit根据功能定义的不同,划分为不同的种类Kit。如下图所示:其实可以理解为集成在系统
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言在HarmonyOS5的应用开发模型中,featureAbility是旧版FA模型(FeatureAbility)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文
GeorgeGcs GeorgeGcs
7小时前
鸿蒙 6.0 引爆 AI 智能体革命:从交互重构到全场景智能觉醒,未来已至
【HarmonyOS5】鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言今天的华为开发者大会(2025HDC),全程看完,我只想说,震撼对于用户来说,一个未来场景的手机操作系统,正在诞生,从文本交互的操作转向自然语言,未来手机用
GeorgeGcs GeorgeGcs
5小时前
【HarmonyOS 5】鸿蒙发展历程
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、鸿蒙HarmonyOS版本年代记鸿蒙1.0:2019年8月9日,华为在开发者大会上正式发布鸿蒙1.0系统,这一版本首次应用于华为荣耀智慧屏产品中,标志着华为正式进军操作系统领域。该版本
GeorgeGcs GeorgeGcs
5小时前
【HarmonyOS 5】鸿蒙中进度条的使用详解
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、HarmonyOS中Progress进度条的类型HarmonyOS的ArkUI框架为开发者提供了多种类型的进度条,每种类型都有其独特的样式,以满足不同的设计需求。以下是几种常见的进度条
GeorgeGcs GeorgeGcs
5小时前
【HarmonyOS】鸿蒙应用实现调用系统地图导航或路径规划
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财前言在涉及地图业务中,调用地图导航和路径规划是三方应用中较为常见的功能。若只是子业务需要地图导航效果,整个APP内部集成地图去实现导航或者路径规划,会造成SDK集成冗余。毕竟很重。所以该效
GeorgeGcs
GeorgeGcs
Lv1
男 · 金融头部企业 · 鸿蒙应用架构师
HarmonyOS认证创作先锋,华为HDE专家,鸿蒙讲师,作者。目前任职鸿蒙应用架构师。 历经腾讯,宝马,研究所,金融。 待过私企,外企,央企。 深耕大应用开发领域十年。 AAE,Harmony(OpenHarmony\HarmonyOS),MAE(Android\IOS),FE(H5\Vue\RN)。
文章
56
粉丝
1
获赞
2