当前位置: 首页 > news >正文

鸿蒙 NEXT开发中轻松实现人脸识别功能

大家好,我是 V 哥。
今天给大家介绍在 HarmonyOS 原生鸿蒙开发中,实现人脸识别功能,这个功能在常用的 APP 开发中上镜率还是很高的,在传统的 Android 或 iOS 开发中,通常我们要借助第三方库来实现,而在鸿蒙原生开发中,天然的集成了这个功能,使用起来也超级方便,接下来听 V 哥细细说来。

在鸿蒙 NEXT 中实现人脸识别功能,可通过 CoreVision KitFaceDetector 模块实现。以下是基于 API 12+ 的实现流程及核心代码示例:


一、开发准备

  1. 配置权限
    module.json5 中添加以下权限:
   "requestPermissions": [{ "name": "ohos.permission.READ_MEDIA" },       // 读取图片权限{ "name": "ohos.permission.CAMERA" },          // 相机权限{ "name": "ohos.permission.ACCESS_BIOMETRIC" } // 生物认证权限]
  1. 导入依赖
    使用鸿蒙 NEXT 的视觉服务接口:
   import { faceDetector } from '@kit.CoreVisionKit';import image from '@kit.ImageKit'; // 图像处理模块

二、核心实现步骤

1. 初始化人脸检测器

// 初始化参数配置
let faceDetectConfig: faceDetector.FaceDetectOptions = {maxFaceNum: 5,         // 最大检测人脸数featureLevel: faceDetector.FeatureLevel.TYPE_FULL, // 检测全部特征algorithmMode: faceDetector.AlgorithmMode.TYPE_MODE_ACCURATE // 高精度模式
};// 创建检测器实例
let detector = faceDetector.createFaceDetector(faceDetectConfig);

2. 获取图像数据
通过相机或相册获取图像,转换为 PixelMap 格式:

// 示例:从相册选择图片并转换为 PixelMap
async function getImagePixelMap() {let imageSource = image.createImageSource(selectedImageUri);let decodeOptions = {desiredSize: { width: 1024, height: 1024 } // 调整尺寸优化性能};let pixelMap = await imageSource.createPixelMap(decodeOptions);return pixelMap;
}

3. 执行人脸检测

async function detectFaces(pixelMap: image.PixelMap) {try {// 执行检测let faces: faceDetector.Face[] = await detector.detect(pixelMap);// 处理检测结果faces.forEach((face: faceDetector.Face) => {console.log("人脸置信度: " + face.confidence);console.log("人脸坐标框: " + JSON.stringify(face.rect));console.log("五官坐标点: " + JSON.stringify(face.landmarks));});} catch (error) {console.error("人脸检测失败: " + error.code + ", 信息: " + error.message);}
}

4. 身份验证集成

结合生物认证接口验证机主身份:

import userAuth from '@kit.BiometricAuthenticationKit';// 检查是否支持人脸识别
let status = userAuth.getAvailableStatus(userAuth.UserAuthType.FACE, userAuth.AuthTrustLevel.ATL3
);
if (status.isAvailable) {// 执行人脸认证userAuth.executeAuth(userAuth.UserAuthType.FACE,userAuth.AuthTrustLevel.ATL3,(err, result) => {if (result?.result === userAuth.AuthResult.SUCCESS) {console.log("身份验证通过");}});
}

三、以下是一个完整示例代码

  1. Index.ets 主页面(示例代码是使用元服务项目实现)
import { authentication } from '@kit.AccountKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';const DOMAIN = 0x0000;export const pathStack: NavPathStack = new NavPathStack();@Entry
@ComponentV2
struct Index {build() {Navigation(pathStack) {Column({ space: 20 }) {Button("人脸活体检测-示例").width("80%").borderRadius(10).onClick(() => {pathStack.pushPath({ name: "live" })})}.height('100%').width('100%')}.title("元服务")}aboutToAppear() {hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');this.loginWithHuaweiID();}/*** Sample code for using HUAWEI ID to log in to atomic service.* According to the Atomic Service Review Guide, when a atomic service has an account system,* the option to log in with a HUAWEI ID must be provided.* The following presets the atomic service to use the HUAWEI ID silent login function.* To enable the atomic service to log in successfully using the HUAWEI ID, please refer* to the HarmonyOS HUAWEI ID Access Guide to configure the client ID and fingerprint certificate.*/private loginWithHuaweiID() {// Create a login request and set parametersconst loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();// Whether to forcibly launch the HUAWEI ID login page when the user is not logged in with the HUAWEI IDloginRequest.forceLogin = false;// Execute login requestconst controller = new authentication.AuthenticationController();controller.executeRequest(loginRequest).then((data) => {const loginWithHuaweiIDResponse = data as authentication.LoginWithHuaweiIDResponse;const authCode = loginWithHuaweiIDResponse.data?.authorizationCode;// Send authCode to the backend in exchange for unionID, session}).catch((error: BusinessError) => {hilog.error(DOMAIN, 'testTag', 'error: %{public}s', JSON.stringify(error));if (error.code === authentication.AuthenticationErrorCode.ACCOUNT_NOT_LOGGED_IN) {// HUAWEI ID is not logged in, it is recommended to jump to the login guide page}});}
}
  1. LiveDetectPage.ets 页面
import { common, abilityAccessCtrl, Permissions } from '@kit.AbilityKit';
import { interactiveLiveness } from '@kit.VisionKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
@Builder export function buildPage(){LiveDetectPage()
}
@Component
export struct LiveDetectPage {private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;// 权限private array: Array<Permissions> = ["ohos.permission.CAMERA"];// 动作个数@State actionsNum: number = 0;/*** 是否是静默模式* 静默模式(SILENT_MODE):表示静默活体检测模式,暂未支持。* 交互模式(INTERACTIVE_MODE):表示动作活体检测模式。*/@State isSilentMode: string = "INTERACTIVE_MODE";// 验证完的跳转模式@State routeMode: string = "replace";// 验证结果@State resultInfo: interactiveLiveness.InteractiveLivenessResult = {livenessType: 0};// 验证失败结果@State failResult: Record<string, number | string> = {"code": 1008302000,"message": ""};build() {NavDestination() {// 层叠布局Stack({// 内容对齐方式:顶部对齐alignContent: Alignment.Top}) {// 列容器组件Column() {// 行容器组件Row() {// 弹性布局:主轴方向为横向,内容对齐方式为起始对齐,垂直方向对齐方式为居中对齐Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {// 文本显示组件Text("验证完的跳转模式:").fontSize(18).width("25%")// 弹性布局:主轴方向为横向,内容对齐方式为起始对齐,垂直方向居中对齐Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {// 行容器组件Row() {// 单选框组件Radio({ value: "replace", group: "routeMode" }).checked(true).height(24).width(24).onChange((isChecked: boolean) => {this.routeMode = "replace"})Text("replace").fontSize(16)}.margin({ right: 15 })Row() {// 单选框组件Radio({ value: "back", group: "routeMode" }).checked(false).height(24).width(24).onChange((isChecked: boolean) => {this.routeMode = "back";})Text("back").fontSize(16)}}.width("75%")}}.margin({ bottom: 30 })// 行容器组件Row() {// 弹性布局:主轴方向为横向,内容对齐方式为起始对齐,垂直方向对齐方式为居中对齐Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {Text("动作数量:").fontSize(18).width("25%")TextInput({placeholder: this.actionsNum != 0 ? this.actionsNum.toString() : "动作数量为3或4个"}).type(InputType.Number).placeholderFont({size: 18,weight: FontWeight.Normal,family: "HarmonyHeiTi",style: FontStyle.Normal}).fontSize(18).fontWeight(FontWeight.Bold).fontFamily("HarmonyHeiTi").fontStyle(FontStyle.Normal).width("65%").onChange((value: string) => {this.actionsNum = Number(value) as interactiveLiveness.ActionsNumber;})}}}.margin({ left: 24, top: 80 }).zIndex(1)// 层叠布局组件:内容对齐方式为底部对齐Stack({ alignContent: Alignment.Bottom }) {if (this.resultInfo?.mPixelMap) {// 如果存在mPixelMap,则显示检测的图片Image(this.resultInfo?.mPixelMap).width(260).height(260).align(Alignment.Center).margin({ bottom: 260 })// 圆形遮罩Circle().width(300).height(300).fillOpacity(0).strokeWidth(60).stroke(Color.White).margin({ bottom: 250, left: 0 })}// 判断检测成功还是失败Text(this.resultInfo.mPixelMap ? "检测成功" : this.failResult.code != 1008302000 ? "检测失败" : "").width("100%").height(26).fontSize(20).fontColor("#000000").fontFamily("HarmonyHeiTi").margin({ top: 50 }).textAlign(TextAlign.Center).fontWeight("Medium").margin({ bottom: 240 })// 如果检测失败,则显示检测失败的原因if(this.failResult.code != 1008302000) {Text(this.failResult.message as string).width("100%").height(26).textAlign(TextAlign.Center).fontFamily("HarmonyHeiTi").fontWeight("Medium").margin({ bottom: 200 })}// 开始检测的按钮Button("开始检测").type(ButtonType.Normal).borderRadius(10).width('60%').height(40).fontSize(16).margin({ bottom: 56 }).onClick(() => {this.privateStartDetection();})}.height("100%")}}.title('活体检测').onWillShow(() => {// 释放结果this.resultRelease();// 获取检测的结果this.getDetectionResultInfo();})}// 跳转到人脸活体检测控件private privateRouterLibrary() {// 交互式活体检测配置实例let routerOptions: interactiveLiveness.InteractiveLivenessConfig = {// 是否是静默模式isSilentMode: this.isSilentMode as interactiveLiveness.DetectionMode,// 路由模式:返回还是替换routeMode: this.routeMode as interactiveLiveness.RouteRedirectionMode,// 动作个数actionsNum: this.actionsNum}// 如果可以使用该能力(活体检测能力)// syscap配置if (canIUse("SystemCapability.AI.Component.LivenessDetect")) {// 开始活体检测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}`);})} else {// 如果不可以使用该能力(活体检测能力),则显示不支持该能力的提示hilog.error(0x0001, "LivenessCollectionIndex", '当前设备不支持活体检测API');}}/*** 返回从用户获取到的权限列表,遍历该列表,如果包含了ohos.permission.CAMERA权限,则调用privateRouterLibrary方法*/private privateStartDetection() {abilityAccessCtrl.createAtManager().requestPermissionsFromUser(this.context, this.array).then((res) => {for (let i = 0; i < res.permissions.length; i++) {if (res.permissions[i] === "ohos.permission.CAMERA" && res.authResults[i] === 0) {this.privateRouterLibrary();}}}).catch((err: BusinessError) => {hilog.error(0x0001, "LivenessCollectionIndex", `Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);})}/*** 获取检测的结果*/private getDetectionResultInfo() {// getInteractiveLivenessResult接口调用完会释放资源// 如果可以使用活体检测能力(syscap配置)if (canIUse("SystemCapability.AI.Component.LivenessDetect")) {// 获取活体检测结果let resultInfo = interactiveLiveness.getInteractiveLivenessResult();resultInfo.then(data => {// 获取到结果,则赋值this.resultInfo = data;}).catch((err: BusinessError) => {// 如果发生了异常,则设置失败结果的字段值this.failResult = { "code": err.code, "message": err.message }})} else {// 当前设备不支持活体检测能力hilog.error(0x0001, "LivenessCollectionIndex", '该设备不支持活体检测API。');}}/*** 结果重置*/private resultRelease() {this.resultInfo = {livenessType: 0}this.failResult = {"code": 1008302000,"message": ""}}
}

注意,需要在module.json5中配置权限。

四、注意事项

  1. 真机调试
    需使用支持人脸识别的真机(如 P50 系列)测试,模拟器不支持)。
  2. 性能优化
    • 降低图像分辨率以提升检测速度。
    • 使用 AlgorithmMode.TYPE_MODE_FAST 快速模式平衡性能与精度。
  3. 特征比对
    进阶场景可通过 FaceComparator 比对两张人脸相似度。

五、扩展场景

  • 活体检测:通过 VisionKit 监测眨眼、转头动作。
  • 暗光增强:结合 ImageKit 调整图像亮度/对比度强化识别效果。

通过上述步骤,可快速实现基础人脸识别功能,并根据需求扩展至复杂场景。


六、小结一下

以上就是在鸿蒙 NEXT 开发中实现人脸识别功能,也称为活体检测,通过鸿蒙 NEXT 提供的能力,可以轻松实现,兄弟们,可以抓紧试试(请自备真机测试)。学习鸿蒙可以关注威哥写的《鸿蒙 HarmonyOS NEXT 开发之路》卷1,卷2已上市,卷3正在加紧印刷中。如果你还没有拿下鸿蒙认证,快到碗里来(https://developer.huawei.com/consumer/cn/training/classDetail/042cb1cc4d7d44ecbdbd902fd1275dcc)。

http://www.dtcms.com/a/343029.html

相关文章:

  • hadoop-3.3.6和hbase-2.4.13
  • 日志收集(ELK)
  • k8s--NetworkPolicy资源对象
  • 打工人项目日报计划
  • 搭建FTP文件共享服务器
  • linux 之 virtio 子系统核心的数据结构
  • DeepSeek R2难产:近期DeepSeek-V3.1 发布更新并开源,成功实现迈向 Agent 时代的第一步
  • 信息收集4----(收集网站指纹信息)
  • CSS 3D动画,围绕旋转动画Demo
  • 常见 Linux 网络命令梳理
  • AGV 技术落地场景解析:从制造业到仓储物流,看自动导引车的行业应用
  • 【Ruoyi解密-02.登录流程:】登录-找密码不抓瞎
  • 封装FTPSClient连接ftps服务器
  • 一个成熟的运维及售后岗位应掌握的知识体系详解
  • Linux动态库制作和使用
  • Manus AI 与多语言手写识别:技术、应用与未来
  • Nginx + Vue/React 前端 + API:防止路径混淆漏洞与跨域问题实战分享
  • [Mysql数据库] Mysql安全知识
  • Oracle ADG 切换方式详解:Switchover 与 Failover 操作指南
  • 〖领码方案〗前端 PageData 完整解决方案 第四版
  • 深度解析Structured Outputs:让AI输出严格遵循JSON Schema的结构化响应
  • 【日常学习】2025-8-21 了解些测试名词
  • 【GPT入门】第52课 openwebui安装与使用
  • Zynq中级开发七项必修课-第三课:S_AXI_GP0 主动访问 PS 地址空间
  • 通信算法之317:基于Xilinx FPGA平台的符号同步算法(接收序列与本地序列互相关-不共轭乘)
  • ODDR实现多bit单边沿采样数据转为多bit双沿采样数据
  • 前端-Vue笔记(核心语法)
  • linux内核 - 内存分配机制介绍
  • MySQL 8.4.6 LTS 安装教程 windows
  • 如何在mac玩windows游戏?3个工具推荐,不用换电脑!