文档管理中心
我的
您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录
指南与API参考指南AICore Vision Kit(基础视觉服务)骨骼点检测

骨骼点检测

适用场景

人体骨骼关键点检测,主要检测人体的一些关键点,通过关键点描述人体骨骼信息。具体应用主要集中在智能视频监控,病人监护系统,人机交互,虚拟现实,人体动画,智能家居,智能安防,运动员辅助训练等等。

支持17个关键点的识别,具体为鼻子,左右眼,左右耳,左右肩,左右肘、左右手腕、左右髋、左右膝、左右脚踝。

效果如下图所示:

开发步骤

  1. 在使用骨骼点检测时,将实现骨骼点检测相关的类添加至工程。

    收起
    自动换行
    深色代码主题
    复制
    1. import { image } from '@kit.ImageKit';
    2. import { hilog } from '@kit.PerformanceAnalysisKit';
    3. import { BusinessError } from '@kit.BasicServicesKit';
    4. import { fileIo } from '@kit.CoreFileKit';
    5. import { skeletonDetection, visionBase } from '@kit.CoreVisionKit';
    6. import { photoAccessHelper } from '@kit.MediaLibraryKit';
  2. 通过photoAccessHelper.PhotoViewPicker拉起图库选择图片,使用fileIo与image模块将URI转换为PixelMap,为后续检测接口准备输入数据。

    收起
    自动换行
    深色代码主题
    复制
    1. Button('选择图片')
    2. .type(ButtonType.Capsule)
    3. .fontColor(Color.White)
    4. .alignSelf(ItemAlign.Center)
    5. .width('80%')
    6. .margin(10)
    7. .onClick(() => {
    8. // 拉起图库,获取图片资源
    9. void this.selectImage();
    10. })

    选择图片与解码图片的方法实现如下:

    收起
    自动换行
    深色代码主题
    复制
    1. private async selectImage() {
    2. let uri = await this.openPhoto();
    3. if (!uri) {
    4. hilog.error(0x0000, 'skeletonDetectSample', 'Failed to define uri.');
    5. return;
    6. }
    7. this.loadImage(uri);
    8. }
    9. private async openPhoto(): Promise<string> {
    10. return new Promise<string>((resolve, reject) => {
    11. let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
    12. photoPicker.select({
    13. MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
    14. maxSelectNumber: 1
    15. }).then(res => {
    16. resolve(res.photoUris[0]);
    17. }).catch((err: BusinessError) => {
    18. hilog.error(0x0000, 'skeletonDetectSample', `Failed to get photo image uri. code: ${err.code}, message: ${err.message}`);
    19. reject(err);
    20. });
    21. });
    22. }
    23. private loadImage(name: string) {
    24. setTimeout(async () => {
    25. let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY);
    26. this.imageSource = image.createImageSource(fileSource.fd);
    27. this.chooseImage = await this.imageSource.createPixelMap();
    28. await fileIo.close(fileSource);
    29. }, 100);
    30. }
  3. 实例化visionBase.Request对象,将PixelMap封装为输入参数;调用SkeletonDetector.create()创建检测器实例,再调用其process方法,获取图片中人体的17个关键点信息,并将结果展示在界面上。

    收起
    自动换行
    深色代码主题
    复制
    1. Button('开始骨骼点识别')
    2. .type(ButtonType.Capsule)
    3. .fontColor(Color.White)
    4. .alignSelf(ItemAlign.Center)
    5. .width('80%')
    6. .margin(10)
    7. .onClick(() => {
    8. // 调用封装的异步处理函数
    9. void this.handleSkeletonDetection();
    10. })

    骨骼点识别的方法实现如下:

    收起
    自动换行
    深色代码主题
    复制
    1. private async handleSkeletonDetection() {
    2. try {
    3. if (!this.chooseImage) {
    4. hilog.error(0x0000, 'skeletonDetectSample', 'Failed to choose image.');
    5. return;
    6. }
    7. // 调用骨骼点识别接口
    8. let request: visionBase.Request = {
    9. inputData: { pixelMap: this.chooseImage }
    10. };
    11. let detector = await skeletonDetection.SkeletonDetector.create();
    12. let data: skeletonDetection.SkeletonDetectionResponse = await detector.process(request);
    13. await detector.destroy();
    14. let poseJson = JSON.stringify(data);
    15. hilog.info(0x0000, 'skeletonDetectSample', `Succeeded in skeleton detection: ${poseJson}`);
    16. this.dataValues = poseJson;
    17. } catch (err) {
    18. const error = err as BusinessError;
    19. hilog.error(0x0000, 'skeletonDetectSample', `Skeleton detection error. Code: ${error.code}, message: ${error.message}`);
    20. }
    21. }

开发实例

Index.ets

收起
自动换行
深色代码主题
复制
  1. import { image } from '@kit.ImageKit';
  2. import { hilog } from '@kit.PerformanceAnalysisKit';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. import { fileIo } from '@kit.CoreFileKit';
  5. import { skeletonDetection, visionBase } from '@kit.CoreVisionKit';
  6. import { photoAccessHelper } from '@kit.MediaLibraryKit';
  7. @Entry
  8. @Component
  9. struct Index {
  10. private imageSource: image.ImageSource | undefined = undefined;
  11. @State chooseImage: PixelMap | undefined = undefined;
  12. @State dataValues: string = '';
  13. build() {
  14. Column() {
  15. Image(this.chooseImage)
  16. .objectFit(ImageFit.Fill)
  17. .height('60%')
  18. Text(this.dataValues)
  19. .copyOption(CopyOptions.LocalDevice)
  20. .height('15%')
  21. .margin(10)
  22. .width('60%')
  23. Button('选择图片')
  24. .type(ButtonType.Capsule)
  25. .fontColor(Color.White)
  26. .alignSelf(ItemAlign.Center)
  27. .width('80%')
  28. .margin(10)
  29. .onClick(() => {
  30. // 拉起图库
  31. void this.selectImage();
  32. })
  33. Button('开始骨骼点识别')
  34. .type(ButtonType.Capsule)
  35. .fontColor(Color.White)
  36. .alignSelf(ItemAlign.Center)
  37. .width('80%')
  38. .margin(10)
  39. .onClick(() => {
  40. // 调用封装的异步处理函数
  41. void this.handleSkeletonDetection();
  42. })
  43. }
  44. .width('100%')
  45. .height('100%')
  46. .justifyContent(FlexAlign.Center)
  47. }
  48. // 封装骨骼点识别的异步逻辑
  49. private async handleSkeletonDetection() {
  50. try {
  51. if (!this.chooseImage) {
  52. hilog.error(0x0000, 'skeletonDetectSample', 'Failed to choose image.');
  53. return;
  54. }
  55. // 调用骨骼点识别接口
  56. let request: visionBase.Request = {
  57. inputData: { pixelMap: this.chooseImage }
  58. };
  59. let detector = await skeletonDetection.SkeletonDetector.create();
  60. let data: skeletonDetection.SkeletonDetectionResponse = await detector.process(request);
  61. await detector.destroy();
  62. if (!data) {
  63. hilog.error(0x0000, 'skeletonDetectSample', 'Invalid skeleton detection result');
  64. return;
  65. }
  66. let poseJson = JSON.stringify(data);
  67. hilog.info(0x0000, 'skeletonDetectSample', `Succeeded in skeleton detection: ${poseJson}`);
  68. this.dataValues = poseJson;
  69. } catch (err) {
  70. const error = err as BusinessError;
  71. hilog.error(0x0000, 'skeletonDetectSample', `Skeleton detection error. Code: ${error.code}, message: ${error.message}`);
  72. }
  73. }
  74. private async selectImage() {
  75. let uri = await this.openPhoto();
  76. if (!uri) {
  77. hilog.error(0x0000, 'skeletonDetectSample', 'Failed to define uri.');
  78. return;
  79. }
  80. this.loadImage(uri);
  81. }
  82. private async openPhoto(): Promise<string> {
  83. return new Promise<string>((resolve, reject) => {
  84. let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
  85. photoPicker.select({
  86. MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
  87. maxSelectNumber: 1
  88. }).then(res => {
  89. resolve(res.photoUris[0]);
  90. }).catch((err: BusinessError) => {
  91. hilog.error(0x0000, 'skeletonDetectSample', `Failed to get photo image uri. code: ${err.code}, message: ${err.message}`);
  92. reject(err);
  93. });
  94. });
  95. }
  96. private loadImage(name: string) {
  97. setTimeout(async () => {
  98. let fileSource = await fileIo.open(name, fileIo.OpenMode.READ_ONLY);
  99. this.imageSource = image.createImageSource(fileSource.fd);
  100. this.chooseImage = await this.imageSource.createPixelMap();
  101. await fileIo.close(fileSource);
  102. }, 100);
  103. }
  104. }