鸿蒙5.0&next开辟【使用MindSpore Lite实现图像分类】AI昪思推理框架服务

[复制链接]
发表于 2025-10-17 18:39:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
场景阐明

开辟者可以使用[@ohos.ai.mindSporeLite],在UI代码中集成MindSpore Lite本领,快速摆设AI算法,举行AI模子推理,实现图像分类的应用。
图像分类可实现对图像中物体的辨认,在医学影像分析、自动驾驶、电子商务、人脸辨认等有广泛的应用。
根本概念

在举行开辟前,请先相识以下概念。
张量:它与数组和矩阵非常相似,是MindSpore Lite网络运算中的根本数据结构。
Float16推理模式: Float16又称半精度,它使用16比特表现一个数。Float16推理模式表现推理的时间用半精度举行推理。
接口阐明

这里给出MindSpore Lite推理的通用开辟流程中涉及的一些接口,具体请见下列表格。
接口名形貌loadModelFromFile(model: string, context?: Context): Promise从路径加载模子。getInputs(): MSTensor[]获取模子的输入。predict(inputs: MSTensor[]): Promise<MSTensor[]>推理模子。getData(): ArrayBuffer获取张量的数据。setData(inputArray: ArrayBuffer): void设置张量的数据。开辟流程


  • 选择图像分类模子。
  • 在端侧使用MindSpore Lite推理模子,实现对选择的图片举行分类。
环境准备

安装DevEco Studio,要求版本 >= 4.1,并更新SDK到API 11或以上。
开辟步调

本文以对相册的一张图片举行推理为例,提供使用MindSpore Lite实现图像分类的开辟引导。
选择模子

本示例步调中使用的图像分类模子文件为[mobilenetv2.ms],放置在entry/src/main/resources/rawfile工程目次下。
假如开辟者有其他图像分类的预练习模子,请参考[MindSpore Lite 模子转换]先容,将原始模子转换成.ms格式。
编写代码

图像输入和预处置惩罚


  • 此处以获取相册图片为例,调用[@ohos.file.picker] 实现相册图片文件的选择。
    1. import { photoAccessHelper } from '@kit.MediaLibraryKit';
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. let uris: Array<string> = [];
    4. // 创建图片文件选择实例
    5. let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    6. // 设置选择媒体文件类型为IMAGE,设置选择媒体文件的最大数目
    7. photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    8. photoSelectOptions.maxSelectNumber = 1;
    9. // 创建图库选择器实例,调用select()接口拉起图库界面进行文件选择。文件选择成功后,返回photoSelectResult结果集。
    10. let photoPicker = new photoAccessHelper.PhotoViewPicker();
    11. photoPicker.select(photoSelectOptions, async (
    12.   err: BusinessError, photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
    13.   if (err) {
    14.     console.error('MS_LITE_ERR: PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
    15.     return;
    16.   }
    17.   console.info('MS_LITE_LOG: PhotoViewPicker.select successfully, ' +
    18.     'photoSelectResult uri: ' + JSON.stringify(photoSelectResult));
    19.   uris = photoSelectResult.photoUris;
    20.   console.info('MS_LITE_LOG: uri: ' + uris);
    21. })
    22. ts
    复制代码
  • 根据模子的输入尺寸,调用[@ohos.multimedia.image] (实现图片处置惩罚)、[@ohos.file.fs] (实现底子文件使用) API对选择图片举行裁剪、获取图片buffer数据,并举行标准化处置惩罚。
    1. import { image } from '@kit.ImageKit';
    2. import { fileIo } from '@kit.CoreFileKit';
    3. let modelInputHeight: number = 224;
    4. let modelInputWidth: number = 224;
    5. // 使用fileIo.openSync接口,通过uri打开这个文件得到fd
    6. let file = fileIo.openSync(this.uris[0], fileIo.OpenMode.READ_ONLY);
    7. console.info('MS_LITE_LOG: file fd: ' + file.fd);
    8. // 通过fd使用fileIo.readSync接口读取这个文件内的数据
    9. let inputBuffer = new ArrayBuffer(4096000);
    10. let readLen = fileIo.readSync(file.fd, inputBuffer);
    11. console.info('MS_LITE_LOG: readSync data to file succeed and inputBuffer size is:' + readLen);
    12. // 通过PixelMap预处理
    13. let imageSource = image.createImageSource(file.fd);
    14. imageSource.createPixelMap().then((pixelMap) => {
    15.   pixelMap.getImageInfo().then((info) => {
    16.     console.info('MS_LITE_LOG: info.width = ' + info.size.width);
    17.     console.info('MS_LITE_LOG: info.height = ' + info.size.height);
    18.     // 根据模型输入的尺寸,将图片裁剪为对应的size,获取图片buffer数据readBuffer
    19.     pixelMap.scale(256.0 / info.size.width, 256.0 / info.size.height).then(() => {
    20.       pixelMap.crop(
    21.         { x: 16, y: 16, size: { height: modelInputHeight, width: modelInputWidth } }
    22.       ).then(async () => {
    23.         let info = await pixelMap.getImageInfo();
    24.         console.info('MS_LITE_LOG: crop info.width = ' + info.size.width);
    25.         console.info('MS_LITE_LOG: crop info.height = ' + info.size.height);
    26.         // 需要创建的像素buffer大小
    27.         let readBuffer = new ArrayBuffer(modelInputHeight * modelInputWidth * 4);
    28.         await pixelMap.readPixelsToBuffer(readBuffer);
    29.         console.info('MS_LITE_LOG: Succeeded in reading image pixel data, buffer: ' +
    30.         readBuffer.byteLength);
    31.         // 处理readBuffer,转换成float32格式,并进行标准化处理
    32.         const imageArr = new Uint8Array(
    33.           readBuffer.slice(0, modelInputHeight * modelInputWidth * 4));
    34.         console.info('MS_LITE_LOG: imageArr length: ' + imageArr.length);
    35.         let means = [0.485, 0.456, 0.406];
    36.         let stds = [0.229, 0.224, 0.225];
    37.         let float32View = new Float32Array(modelInputHeight * modelInputWidth * 3);
    38.         let index = 0;
    39.         for (let i = 0; i < imageArr.length; i++) {
    40.           if ((i + 1) % 4 == 0) {
    41.             float32View[index] = (imageArr[i - 3] / 255.0 - means[0]) / stds[0]; // B
    42.             float32View[index+1] = (imageArr[i - 2] / 255.0 - means[1]) / stds[1]; // G
    43.             float32View[index+2] = (imageArr[i - 1] / 255.0 - means[2]) / stds[2]; // R
    44.             index += 3;
    45.           }
    46.         }
    47.         console.info('MS_LITE_LOG: float32View length: ' + float32View.length);
    48.         let printStr = 'float32View data:';
    49.         for (let i = 0; i < 20; i++) {
    50.           printStr += ' ' + float32View[i];
    51.         }
    52.         console.info('MS_LITE_LOG: float32View data: ' + printStr);
    53.       })
    54.     })
    55.   });
    56. });
    57. ts
    复制代码
编写推理代码


  • 工程默认装备界说的本领集大概不包罗MindSporeLite。需在DevEco Studio工程的entry/src/main目次下,手动创建syscap.json文件,内容如下:
    1. {
    2.   "devices": {
    3.     "general": [
    4.       // 需跟module.json5中deviceTypes保持一致。
    5.       "default"
    6.     ]
    7.   },
    8.   "development": {
    9.     "addedSysCaps": [
    10.       "SystemCapability.AI.MindSporeLite"
    11.     ]
    12.   }
    13. }
    14. json
    复制代码
  • 调用[@ohos.ai.mindSporeLite]实现端侧推理。具体开辟过程及细节如下:

    • 创建上下文,设置线程数、装备范例等参数。
    • 加载模子。本文从内存加载模子。
    • 加载数据。模子实行之前必要先获取输入,再向输入的张量中添补数据。
    • 实行推理。使用predict接口举行模子推理。
    1. // model.ets
    2. import { mindSporeLite } from '@kit.MindSporeLiteKit'
    3. export default async function modelPredict(
    4.   modelBuffer: ArrayBuffer, inputsBuffer: ArrayBuffer[]): Promise<mindSporeLite.MSTensor[]> {
    5.   // 1.创建上下文,设置线程数、设备类型等参数。
    6.   let context: mindSporeLite.Context = {};
    7.   context.target = ['cpu'];
    8.   context.cpu = {}
    9.   context.cpu.threadNum = 2;
    10.   context.cpu.threadAffinityMode = 1;
    11.   context.cpu.precisionMode = 'enforce_fp32';
    12.   // 2.从内存加载模型。
    13.   let msLiteModel: mindSporeLite.Model = await mindSporeLite.loadModelFromBuffer(modelBuffer, context);
    14.   // 3.设置输入数据。
    15.   let modelInputs: mindSporeLite.MSTensor[] = msLiteModel.getInputs();
    16.   for (let i = 0; i < inputsBuffer.length; i++) {
    17.     let inputBuffer = inputsBuffer[i];
    18.     if (inputBuffer != null) {
    19.       modelInputs[i].setData(inputBuffer as ArrayBuffer);
    20.     }
    21.   }
    22.   // 4.执行推理。
    23.   console.info('=========MS_LITE_LOG: MS_LITE predict start=====');
    24.   let modelOutputs: mindSporeLite.MSTensor[] = await msLiteModel.predict(modelInputs);
    25.   return modelOutputs;
    26. }
    27. ts
    复制代码
举行推理并输出效果

加载模子文件,调用推理函数,对相册选择的图片举行推理,并对推理效果举行处置惩罚。
  1. import modelPredict from './model';
  2. import { resourceManager } from '@kit.LocalizationKit'
  3. let modelName: string = 'mobilenetv2.ms';
  4. let max: number = 0;
  5. let maxIndex: number = 0;
  6. let maxArray: Array<number> = [];
  7. let maxIndexArray: Array<number> = [];
  8. // 完成图像输入和预处理后的buffer数据保存在float32View,具体可见上文图像输入和预处理中float32View的定义和处理。
  9. let inputs: ArrayBuffer[] = [float32View.buffer];
  10. let resMgr: resourceManager.ResourceManager = getContext().getApplicationContext().resourceManager;
  11. resMgr.getRawFileContent(modelName).then(modelBuffer => {
  12.   // predict
  13.   modelPredict(modelBuffer.buffer.slice(0), inputs).then(outputs => {
  14.     console.info('=========MS_LITE_LOG: MS_LITE predict success=====');
  15.     // 结果打印
  16.     for (let i = 0; i < outputs.length; i++) {
  17.       let out = new Float32Array(outputs[i].getData());
  18.       let printStr = outputs[i].name + ':';
  19.       for (let j = 0; j < out.length; j++) {
  20.         printStr += out[j].toString() + ',';
  21.       }
  22.       console.info('MS_LITE_LOG: ' + printStr);
  23.       // 取分类占比的最大值
  24.       this.max = 0;
  25.       this.maxIndex = 0;
  26.       this.maxArray = [];
  27.       this.maxIndexArray = [];
  28.       let newArray = out.filter(value => value !== max)
  29.       for (let n = 0; n < 5; n++) {
  30.         max = out[0];
  31.         maxIndex = 0;
  32.         for (let m = 0; m < newArray.length; m++) {
  33.           if (newArray[m] > max) {
  34.             max = newArray[m];
  35.             maxIndex = m;
  36.           }
  37.         }
  38.         maxArray.push(Math.round(max * 10000))
  39.         maxIndexArray.push(maxIndex)
  40.         // filter函数,数组过滤函数
  41.         newArray = newArray.filter(value => value !== max)
  42.       }
  43.       console.info('MS_LITE_LOG: max:' + maxArray);
  44.       console.info('MS_LITE_LOG: maxIndex:' + maxIndexArray);
  45.     }
  46.     console.info('=========MS_LITE_LOG END=========');
  47.   })
  48. })
  49. ts
复制代码
调考试证


  • 在DevEco Studio中毗连装备,点击Run entry,编译Hap,有如下表现:
    1. Launching com.samples.mindsporelitearktsdemo
    2. $ hdc shell aa force-stop com.samples.mindsporelitearktsdemo
    3. $ hdc shell mkdir data/local/tmp/xxx
    4. $ hdc file send C:\Users\xxx\MindSporeLiteArkTSDemo\entry\build\default\outputs\default\entry-default-signed.hap "data/local/tmp/xxx"
    5. $ hdc shell bm install -p data/local/tmp/xxx
    6. $ hdc shell rm -rf data/local/tmp/xxx
    7. $ hdc shell aa start -a EntryAbility -b com.samples.mindsporelitearktsdemo
    8. shell
    复制代码
  • 在装备屏幕点击photo按钮,选择图片,点击确定。装备屏幕表现所选图片的分类效果,在日志日志打印效果中,过滤关键字”MS_LITE“,可得到如下效果:
    1. 08-06 03:24:33.743   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: PhotoViewPicker.select successfully, photoSelectResult uri: {"photoUris":["file://media/Photo/13/IMG_1501955351_012/plant.jpg"]}
    2. 08-06 03:24:33.795   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: readSync data to file succeed and inputBuffer size is:32824
    3. 08-06 03:24:34.147   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: crop info.width = 224
    4. 08-06 03:24:34.147   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: crop info.height = 224
    5. 08-06 03:24:34.160   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: Succeeded in reading image pixel data, buffer: 200704
    6. 08-06 03:24:34.970   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     =========MS_LITE_LOG: MS_LITE predict start=====
    7. 08-06 03:24:35.432   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     =========MS_LITE_LOG: MS_LITE predict success=====
    8. 08-06 03:24:35.447   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: Default/head-MobileNetV2Head/Sigmoid-op466:0.0000034338463592575863,0.000014028532859811094,9.119685273617506e-7,0.000049100715841632336,9.502661555416125e-7,3.945370394831116e-7,0.04346757382154465,0.00003971960904891603...
    9. 08-06 03:24:35.499   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: max:9497,7756,1970,435,46
    10. 08-06 03:24:35.499   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     MS_LITE_LOG: maxIndex:323,46,13,6,349
    11. 08-06 03:24:35.499   22547-22547  A03d00/JSAPP                   com.sampl...liteark+  I     =========MS_LITE_LOG END=========
    复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表