首页 > 其他分享 >HarmonyOS NEXT-CoreVision Kit-FaceDetector-实现人脸识别,获取人脸数据

HarmonyOS NEXT-CoreVision Kit-FaceDetector-实现人脸识别,获取人脸数据

时间:2024-09-27 15:20:26浏览次数:11  
标签:CoreVision FaceDetector 面部 Kit width PixelMap error import message

效果演示图,右边的是人脸数据,可用来比对人脸

注意这里只有真机才能测试是否成功, 测试机型pce-w30

实现这个效果很简洁:打开相册、选取图片、打开文件、创建imageSource、创建PixelMap、喂给faceDetector拿到结果

在这里我简单封装了两个工具类方便后续使用,分别是:照片选择类、人脸识别类

大部分解读都写在注释里面了,供参考

// 引入必要的模块
import { faceDetector } from '@kit.CoreVisionKit'; // 引入人脸检测模块
import { promptAction } from '@kit.ArkUI'; // 引入UI提示模块

/**
 * FaceDetectClass 类用于处理面部检测的逻辑
 */
export class FaceDetectClass {

  // 静态属性,用于存储当前面部数据的JSON字符串
  static faceDataStr: string = "";

  /**
   * 异步检测面部信息
   * @param pixMap - 包含图像数据的PixelMap对象
   * @returns 返回Promise,解析为面部数据的JSON字符串,或在失败时拒绝
   */
  static async detectFace(pixMap: PixelMap): Promise<string> {
    return new Promise<string>(async (resolve, reject) => {
      try {
        // 构造VisionInfo对象,包含待检测的图像数据
        const visionInfo: faceDetector.VisionInfo = {
          pixelMap: pixMap
        };

        // 调用人脸检测接口
        const faceData = await faceDetector.detect(visionInfo);

        // 检查是否检测到面部
        if (faceData.length === 0) {
          // 如果没有检测到面部,显示提示并拒绝Promise
          promptAction.showToast({
            message: "获取面部数据失败"
          });
          reject("未检测到面部");
        } else {
          // 将面部数据转换为JSON字符串
          const faceJsonStr = JSON.stringify(faceData);

          // 更新静态属性以存储当前面部数据
          FaceDetectClass.faceDataStr = faceJsonStr;

          // 解析Promise,返回面部数据的JSON字符串
          resolve(faceJsonStr);
        }
      } catch (err) {
        // 捕获并处理异常
        promptAction.showToast({
          message: `识别面部失败: ${err.message}`
        });
        reject(err); // 拒绝Promise,并传递错误对象
      }
    });
  }
}
// 引入必要的模块
import { photoAccessHelper } from '@kit.MediaLibraryKit'; // 引入媒体库访问助手,用于选择照片
import { fileIo } from '@kit.CoreFileKit'; // 引入文件IO模块,用于文件操作
import { image } from '@kit.ImageKit'; // 引入图像处理模块,用于处理图像数据

/**
 * PhotoPickerClass 类提供了选择照片和根据URI创建PixelMap的功能
 */
export class PhotoPickerClass {
  // 静态属性,用于存储照片选择器实例
  static photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();

  /**
   * 异步选择一张照片并返回其URI
   * @returns 返回所选照片的URI
   */
  static async selectImageUri() {
    try {
      // 调用照片选择器选择照片,限制为图像类型且最大选择数为1
      const selectionResult = await PhotoPickerClass.photoPicker.select({
        MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, // 指定MIME类型为图像
        maxSelectNumber: 1 // 设置最大选择数量为1
      });

      // 返回第一张照片的URI(因为maxSelectNumber为1,所以这里总是安全的)
      return selectionResult.photoUris[0];
    } catch (error) {
      // 处理可能的错误,例如用户取消选择或发生其他错误
      console.error('Failed to select image:', error);
      // 重新抛出错误,以便调用者可以处理
      return error.message
    }
  }

  /**
   * 根据提供的图片URI创建PixelMap对象
   * @param imgUri 图片的URI
   * @returns 返回创建的PixelMap对象
   */
  static creatPixMapByUri(imgUri: string): Promise<PixelMap | undefined> {
    return new Promise<PixelMap | undefined>((resolve, reject) => {
      try {
        // 以只读模式打开文件
        const file = fileIo.openSync(imgUri, fileIo.OpenMode.READ_ONLY);

        // 使用文件描述符创建图像源
        const imgSource = image.createImageSource(file.fd);

        // 从图像源同步创建PixelMap对象
        const imgPixMap = imgSource.createPixelMapSync();

        // 关闭文件(注意:在某些环境中,这可能不是必需的,因为createImageSource可能已接管文件)
        if (imgSource) {
          imgSource.release()
        }
        // 返回创建的PixelMap对象
        resolve(imgPixMap);
      } catch (error) {
        // 处理可能的错误,例如文件不存在或无法读取
        console.error('Failed to create PixelMap from URI:', imgUri, error);
        reject("创建pixelMap错误" + error.message)
      }
    })
  }
}
import { promptAction } from '@kit.ArkUI'
import { FaceDetectClass } from '../utils/FaceDetector'
import { PhotoPickerClass } from '../utils/PhotoPicker'

@Entry
@Component
struct Index {
  @State currentUri: string = ""
  @State dataValue: string = ""
  @State testPixMap: PixelMap | undefined = undefined
  @State cltData: string[] = []

  aboutToDisappear(): void {
    if (this.testPixMap) {
      // 释放资源
      this.testPixMap.release()
    }
  }

  build() {
    Row({ space: 15 }) {
      // 选择图片部分
      Column() {
        Column() {
          Image(this.currentUri)
            .width(400)
            .aspectRatio(1)
            .objectFit(ImageFit.Contain)
        }
        .justifyContent(FlexAlign.Center)
        .layoutWeight(1)
        .width("100%")

        Column({ space: 15 }) {
          Button("删除数据")
            .margin({ bottom: 30 })
            .fontSize(30)
            .width(300)
            .height(60)
            .onClick(() => {
              this.cltData.pop()
            })
          Button("选择照片")
            .margin({ bottom: 30 })
            .fontSize(30)
            .width(300)
            .height(60)
            .onClick(async () => {
              try {
                this.currentUri = await PhotoPickerClass.selectImageUri()
                this.testPixMap = await PhotoPickerClass.creatPixMapByUri(this.currentUri)
              } catch (err) {
                promptAction.showToast({
                  message: `Error + ${err.message}`
                })
              }
            })
        }
      }
      .height('100%')
      .layoutWeight(1)
      .border({ width: 2, color: Color.Blue })
      .borderRadius(10)

      // 识别人脸部分
      Column() {
        Column({ space: 10 }) {
          ForEach(this.cltData, (dataItem: string) => {
            Text(dataItem ? dataItem : "")
          })
        }
        .padding(15)
        .layoutWeight(1)
        .width("100%")

        Button("识别人脸")
          .margin({ bottom: 30 })
          .fontSize(30)
          .width(300)
          .height(60)
          .onClick(async () => {
            try {
              if (this.testPixMap) {
                this.dataValue = await FaceDetectClass.detectFace(this.testPixMap)
                this.cltData.push(this.dataValue)
                promptAction.showToast({
                  message: "识别成功"
                })
              }
            } catch (err) {
              promptAction.showToast({
                message: `识别错误____ ${err.message}`
              })
            }
          })
      }
      .height('100%')
      .layoutWeight(1)
      .border({ width: 2, color: Color.Blue })
      .borderRadius(10)
    }
    .padding(10)
    .height('100%')
    .width('100%')
  }
}

标签:CoreVision,FaceDetector,面部,Kit,width,PixelMap,error,import,message
From: https://blog.csdn.net/2303_78789385/article/details/142593565

相关文章

  • Install Cuda Toolkit
     (base)zzh@ZZHPC:~$sudoubuntu-driversdevices==/sys/devices/pci0000:00/0000:00:1b.4/0000:02:00.0==modalias:pci:v000010DEd00001F07sv000010DEsd000012ADbc03sc00i00vendor:NVIDIACorporationmodel:TU106[GeForceRTX2070Rev.A]driver:......
  • Unity UI Tookite:实现命令控制台 [自定义元素]
    目录前言功能需求基础逻辑实现——输入输出分离逻辑实现——命令解析/历史指令切换历史指令解析指令基于反射的命令组自动装载逻辑实现——命令提示逻辑实现——定位报错逻辑实现——内容滚动/元素铺满逻辑实现——可变文本块最后前言最近在将Godot项目重写至Unit......
  • Nuxt Kit 实用工具的使用示例
    title:NuxtKit实用工具的使用示例date:2024/9/25updated:2024/9/25author:cmdragonexcerpt:摘要:本文介绍了NuxtKit工具在开发集成工具或插件时,如何访问和修改Nuxt应用中使用的Vite或webpack配置,以实现定制化构建需求。内容包括功能概述、项目示例、详细步骤说明了......
  • 华为HarmonyOS灵活高效的消息推送服务(Push Kit) - 5 发送通知消息
    场景介绍通知消息通过PushKit通道直接下发,可在终端设备的通知中心、锁屏、横幅等展示,用户点击后拉起应用。您可以通过设置通知消息样式来吸引用户。开通权益PushKit根据消息内容,将通知消息分类为服务与通讯、资讯营销两大类别,开放通知消息自分类权益。两种类型的通知消息......
  • kl散度,K近邻估计法(K-Nearest Neighbors, KNN)是一种基本的分类与回归方法,通常用于分类
     K近邻估计法(K-NearestNeighbors,KNN)是一种基本的分类与回归方法,通常用于分类任务。在Python中,你可以使用scikit-learn库来实现KNN算法。下面是一个简单的示例,展示如何使用scikit-learn来实现KNN分类器。首先,确保你已经安装了scikit-learn库。如果没有安装,可以通过运行pipinsta......
  • Nuxt Kit 使用日志记录工具
    title:NuxtKit使用日志记录工具date:2024/9/23updated:2024/9/23author:cmdragonexcerpt:摘要:本文介绍在Nuxt3框架的NuxtKit中使用日志记录工具的方法,重点讲解useLogger函数的应用,通过创建示例项目一步步展示如何配置和使用日志记录功能来监控应用状态、记录信息......
  • Nuxt Kit 使用日志记录工具
    title:NuxtKit使用日志记录工具date:2024/9/23updated:2024/9/23author:cmdragonexcerpt:摘要:本文介绍在Nuxt3框架的NuxtKit中使用日志记录工具的方法,重点讲解useLogger函数的应用,通过创建示例项目一步步展示如何配置和使用日志记录功能来监控应用状态、记......
  • Nuxt Kit 使用日志记录工具
    title:NuxtKit使用日志记录工具date:2024/9/23updated:2024/9/23author:cmdragonexcerpt:摘要:本文介绍在Nuxt3框架的NuxtKit中使用日志记录工具的方法,重点讲解useLogger函数的应用,通过创建示例项目一步步展示如何配置和使用日志记录功能来监控应用状态、记......
  • Mockito提升单元测试覆盖率
    简单实战  1、准备工作从gitee下载一个例子工程,下面会在这个工程下补充测试用例      选择的是Ruoyi的后台代码,gitclone之后,添加几个依赖,因为习惯用@RunWith(MockitoJUnitRunner.class)的方式,就添加了下面的两个依赖  第一个Mockito是这篇文章......
  • 使用 GitHub Actions & Pages 托管 Honkit 发布的网站
    使用GitHubActions&Pages托管Honkit发布的网站Created:2024-09-22T13:48+08:00Published:2024-09-22T14:28+08:00Category:DevOps作为张雨生的骨灰级粉丝,我一直想把雨生的资料尽可能地收集起来,用网站或者电子书的形式发布。一番查找后,我选择了honkit制作电子书和......