鸿蒙应用开发之基础视觉服务主体分割基础

13 阅读1分钟


一、工具


DevEco Studio

二、项目介绍


开发步骤
引用相关类添加至工程。
import { subjectSegmentation } from '@kit.CoreVisionKit';
准备预处理的图片资源,将图片转换为PixelMap,并添加初始化和释放方法。
async aboutToAppear(): Promise {
  const initResult = await subjectSegmentation.init();
  hilog.info(0x0000, 'subjectSegmentationSample', `Subject segmentation initialization result:${initResult}`);
}


async aboutToDisappear(): Promise {
  await subjectSegmentation.release();
  hilog.info(0x0000, 'subjectSegmentationSample', 'Subject segmentation released successfully');
}


private async selectImage() {
  let uri = await this.openPhoto()
  if (uri === undefined) {
    hilog.error(0x0000, TAG, "uri is undefined");
  }
  this.loadImage(uri);
}


private openPhoto(): Promise> {
  return new Promise>((resolve, reject) => {
    let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    PhotoSelectOptions.maxSelectNumber = 1;
    let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
    hilog.info(0x0000, TAG, 'PhotoViewPicker.select successfully, PhotoSelectResult uri: ');
    photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
      hilog.info(0x0000, TAG, `PhotoViewPicker.select successfully, PhotoSelectResult uri: ${PhotoSelectResult.photoUris}`);
      resolve(PhotoSelectResult.photoUris)
    }).catch((err: BusinessError) => {
      hilog.error(0x0000, TAG, `PhotoViewPicker.select failed with errCode: ${err.code}, errMessage: ${err.message}`);
      reject();
    });
  })
}


private loadImage(names: string[]) {
  setTimeout(async () => {
    let imageSource: image.ImageSource | undefined = undefined
    let fileSource = await fileIo.open(names[0], fileIo.OpenMode.READ_ONLY)
    imageSource = image.createImageSource(fileSource.fd)
    this.chooseImage = await imageSource.createPixelMap()
    hilog.info(0x0000, TAG, `this.chooseImage===${this.chooseImage}`);
  }, 100
  )
}
实例化待分割的入参项VisionInfo,并传入待检测图片的PixelMap。
let visionInfo: subjectSegmentation.VisionInfo = {
  pixelMap: this.chooseImage,
};
配置通用文本识别的配置项SegmentationConfig,包括最大分割主体个数、是否输出每个主体的分割信息,以及是否输出分割后的前景图。
let config: subjectSegmentation.SegmentationConfig = {
  maxCount: parseInt(this.maxNum),
  enableSubjectDetails: true,
  enableSubjectForegroundImage: true,
};
调用subjectSegmentation的subjectSegmentation.doSegmentation接口,实现主体分割。
let data: subjectSegmentation.SegmentationResult = await subjectSegmentation.doSegmentation(visionInfo, config);
let outputString = `Subject count: ${data.subjectCount}\n`;
outputString += `Max subject count: ${config.maxCount}\n`;
outputString += `Enable subject details: ${config.enableSubjectDetails ? 'Yes' : 'No'}\n\n`;
let segBox : subjectSegmentation.Rectangle = data.fullSubject.subjectRectangle;
let segBoxString = `Full subject box:\nLeft: ${segBox.left}, Top: ${segBox.top}, Width: ${segBox.width}, Height: ${segBox.height}\n\n`;
outputString += segBoxString;


if (config.enableSubjectDetails) {
  outputString += 'Individual subject boxes:\n';
  if (data.subjectDetails) {
    for (let i = 0; i < data.subjectDetails.length; i++) {
      let detailSegBox: subjectSegmentation.Rectangle = data.subjectDetails[i].subjectRectangle;
      outputString += `Subject ${i + 1}:\nLeft: ${detailSegBox.left}, Top: ${detailSegBox.top}, Width: ${detailSegBox.width}, Height: ${detailSegBox.height}\n\n`;
    }
  }
}
开发实例
import { subjectSegmentation } from '@kit.CoreVisionKit';
import { image } from '@kit.ImageKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';


const TAG: string = "ImageSegmentationSample";


@Entry
@Component
struct Index {
  @State chooseImage: PixelMap | undefined = undefined
  @State dataValues: string = ''
  @State segmentedImage: PixelMap | undefined = undefined
  @State maxNum: string = '20'



  build() {
    Column() {
      Image(this.chooseImage)
        .objectFit(ImageFit.Fill)
        .height('30%')
        .accessibilityDescription("Image to be segmented")


      Scroll() {
        Text(this.dataValues)
          .copyOption(CopyOptions.LocalDevice)
          .margin(10)
          .width('100%')
      }
      .height('20%')


      Image(this.segmentedImage)
        .objectFit(ImageFit.Fill)
        .height('30%')
        .accessibilityDescription("Segmented subject image")


      Row() {
        Text('Max subject count:')
          .fontSize(16)
        TextInput({ placeholder: 'Enter max subject count', text: this.maxNum })
          .type(InputType.Number)
          .placeholderColor(Color.Gray)
          .fontSize(16)
          .backgroundColor(Color.White)
          .onChange((value: string) => {
            this.maxNum = value
          })
      }
      .width('80%')
      .margin(10)


      Button('Select Image')
        .type(ButtonType.Capsule)
        .fontColor(Color.White)
        .alignSelf(ItemAlign.Center)
        .width('80%')
        .margin(10)
        .onClick(() => {
          this.selectImage()
        })


      Button('Image Segmentation')
        .type(ButtonType.Capsule)
        .fontColor(Color.White)
        .alignSelf(ItemAlign.Center)
        .width('80%')
        .margin(10)
        .onClick(() => {
          if (!this.chooseImage) {
            hilog.error(0x0000, TAG, "imageSegmentation not have chooseImage");
            return
          }
          let visionInfo: subjectSegmentation.VisionInfo = {
            pixelMap: this.chooseImage,
          };
          let config: subjectSegmentation.SegmentationConfig = {
            maxCount: parseInt(this.maxNum),
            enableSubjectDetails: true,
            enableSubjectForegroundImage: true,
          };
          subjectSegmentation.doSegmentation(visionInfo, config)
            .then((data: subjectSegmentation.SegmentationResult) => {
              let outputString = `Subject count: ${data.subjectCount}\n`;
              outputString += `Max subject count: ${config.maxCount}\n`;
              outputString += `Enable subject details: ${config.enableSubjectDetails ? 'Yes' : 'No'}\n\n`;
              let segBox : subjectSegmentation.Rectangle = data.fullSubject.subjectRectangle;
              let segBoxString = `Full subject box:\nLeft: ${segBox.left}, Top: ${segBox.top}, Width: ${segBox.width}, Height: ${segBox.height}\n\n`;
              outputString += segBoxString;


              if (config.enableSubjectDetails) {
                outputString += 'Individual subject boxes:\n';
                if (data.subjectDetails) {
                  for (let i = 0; i < data.subjectDetails.length; i++) {
                    let detailSegBox: subjectSegmentation.Rectangle = data.subjectDetails[i].subjectRectangle;
                    outputString += `Subject ${i + 1}:\nLeft: ${detailSegBox.left}, Top: ${detailSegBox.top}, Width: ${detailSegBox.width}, Height: ${detailSegBox.height}\n\n`;
                  }
                }
              }


              hilog.info(0x0000, TAG, "Segmentation result: " + outputString);
              this.dataValues = outputString;


              if (data.fullSubject && data.fullSubject.foregroundImage) {
                this.segmentedImage = data.fullSubject.foregroundImage;
              } else {
                hilog.warn(0x0000, TAG, "No foreground image in segmentation result");
              }
            })
            .catch((error: BusinessError) => {
              hilog.error(0x0000, TAG, `Image segmentation failed errCode: ${error.code}, errMessage: ${error.message}`);
              this.dataValues = `Error: ${error.message}`;
              this.segmentedImage = undefined;
            });
        })
    }
    .width('100%')
    .height('80%')
    .justifyContent(FlexAlign.Center)
  }


  private async selectImage() {
    let uri = await this.openPhoto()
    if (uri === undefined) {
      hilog.error(0x0000, TAG, "uri is undefined");
    }
    this.loadImage(uri);
  }


  private openPhoto(): Promise> {
    return new Promise>((resolve, reject) => {
      let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
      PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
      PhotoSelectOptions.maxSelectNumber = 1;
      let photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
      hilog.info(0x0000, TAG, 'PhotoViewPicker.select successfully, PhotoSelectResult uri: ');
      photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
        hilog.info(0x0000, TAG, `PhotoViewPicker.select successfully, PhotoSelectResult uri: ${PhotoSelectResult.photoUris}`);
        resolve(PhotoSelectResult.photoUris)
      }).catch((err: BusinessError) => {
        hilog.error(0x0000, TAG, `PhotoViewPicker.select failed with errCode: ${err.code}, errMessage: ${err.message}`);
        reject();
      });
    })
  }


  private loadImage(names: string[]) {
    setTimeout(async () => {
      let imageSource: image.ImageSource | undefined = undefined
      let fileSource = await fileIo.open(names[0], fileIo.OpenMode.READ_ONLY)
      imageSource = image.createImageSource(fileSource.fd)
      this.chooseImage = await imageSource.createPixelMap()
      hilog.info(0x0000, TAG, `this.chooseImage===${this.chooseImage}`);
    }, 100
    )
  }
}