HarmonyOS鸿蒙NEXT中病虫害AI诊断预测功能实现
HarmonyOS鸿蒙NEXT中病虫害AI诊断预测功能实现
在华为云的AI ModelArts平台已部署图像分类模型的在线服务,且平台提供了在线服务的公网API。
打开PestInfoPage.ets文件,在PestDiagnosisView组件内,
- 定义复制文件的方法,将拍照或相册选取的图片复制到APP当前运行的缓存区
/**
* 复制文件
* @param from
* @param to
*/
copyFile(from:string,to:string):void{
let fFile=fileIo.openSync(from);
let tFile=fileIo.openSync(to,fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); // 替换或创建
fileIo.copyFileSync(fFile.fd,tFile.fd);
fileIo.closeSync(fFile);
fileIo.closeSync(tFile);
}
- 从缓存区读取文件,并压缩
/**
* 读取文件内容(压缩后)
* @param cacheImgUri
* @returns
*/
async readFileContent(cacheImgUri :string):Promise<ArrayBuffer>{
let fFile=fileIo.openSync(cacheImgUri,fileIo.OpenMode.READ_ONLY);
let fStat=fileIo.lstatSync(cacheImgUri);
let arrayBufFile:new ArrayBuffer(fStat.size); // 压缩前文件大小
let imgPacker=image.createImagePacker();
let imgSource=image.createImageSource(fFile.fd);
await imgPacker.packing(imgSource,{format:'image/jpeg',quality:40})
.then((data:ArrayBuffer) => {
arrayBufFile=data;
})
.catch((err:BusinessError) => {
})
return arrayBufFile;
}
- 构建请求体body,含需要上传的图片文件内容
/**
* 构建请求体
* @param boundary
* @param fileName
* @param fileContent
* @returns
*/
buildBodyContent(boundary:string,fileName:string,fileContent:Uint8Array):ArrayBuffer{
// 构建请求体前面内容
let bodyPre=`--${boundary}\r\n`;
bodyPre =bodyPre + `Content-Disposition: form-data; name="images"; filename="${fileName}"\r\n`;
bodyPre =bodyPre + 'Content-Type: application/octet-stream\r\n';
bodyPre =bodyPre + `\r\n`;
let txtEncoder=new util.TextEncoder();
let arrayPre=txtEncoder.encodeInto(bodyPre);
// 构建请求体后面内容
let bodyAft='\r\n';
bodyAft =bodyAft + `--${boundary}`;
bodyAft=bodyAft + '--\r\n';
let arrayAft=txtEncoder.encode(bodyAft);
let body=buffer.concat([arrayPre,fileContent,arrayAft]) // 构建完整请求体
return body.buffer;
}
- 解析AI在线服务接口返回的JSON数据
{
"predicted_label": "c_3",
"scores": [["c_3", "1.000"], ["c_24", "0.000"], ["c_25", "0.000"], ["c_26", "0.000"], ["c_27", "0.000"]]
}
并通过key值找到其对应的置信度value值
/**
* 根据key查找value
* @param key
* @param dataArray
* @returns
*/
findValueByKey(key:string,dataArray:string[][]){
const value=dataArray.find(item => item[0] === key)?.[1];
return value;
}
- AI诊断预测按钮click完整代码如下
/**
* 调用AI模型接口
* @param imgUri
* @returns
*/
async aiAnalyseImg(imgUri:string):Promise<void>{
// 文件名
let fileName=imgUri.split('/').pop() as string;
let cacheFilePath=`${getContext().cacheDir}/${fileName}`;
// 复制图片
this.copyFile(imgUri,cacheFilePath);
// 从缓存文件读取图片数据
let fileContent:new Uint8Array(await this.readFileContent(cacheFilePath));
// 构建请求体body
let boundary:'-------'+(await systemDateTime.getCurrentTime(true)).toString();
let bodyContent=this.buildBodyContent(boundary,fileName,fileContent);
console.debug('请求体是:'+bodyContent);
// 记得替换你自己的接口地址
let url:'https://b07b6d6054d241dc8776d5e44203f97e.apig.cn-north-4.huaweicloudapis.com/v1/infers/c9149048-c678-4e73-9dd4-37c01808683b';
let request=http.createHttp();
let reqOpts:http.HttpRequestOptions={
// 请求头
method:http.RequestMethod.POST,
header:{
'X-Apig-AppCode':'7990c0e44c5d422ab7cb5c42a0b23831f62eccb25cc34ee7b450d17445f1c630', // 记得替换你自己的APP Code
'Content-Type`: `multipart/form-data; boundary=${boundary}`,
'Content-Length':bodyContent.byteLength.toString()
},
extraData:bodyContent,
};
let model:PestModel | undefined;
// 发起请求
request.request(url,reqOpts)
.then((resp) => {
console.debug('请求结果是:'+resp.result);
let aiModel=JSON.parse(resp.result.toString()) as AiPestModel;
let label=aiModel.predicted_label??'';
let scores=aiModel.scores??[];
let code=aiModel.error_code??'';
let msg=aiModel.error_msg??'';
if (code !='') {
AlertDialog.show({
title:'服务异常~',
message:'AI诊断预测服务不可用,请稍后再试。'
});
} else {
let value=this.findValueByKey(label,scores)??0; // AI预测结果的置信度
let pest: PestModel[]=LIST_PEST_DATA.filter(PestModel => PestModel.PredictedLabel === label);
if(value<0.9 || pest==undefined || pest.length==0){
AlertDialog.show({
title:'诊断结果',
message:'未发现病虫害,仅供参考。',
cancel:() =>{
// 关闭对话框
}
});
} else {
model=pest[0];
this.pestObj!.PestName=model.PestName;
this.pestObj!.Type=model.Type;
this.pestObj!.ID=model.ID;
this.pestObj!.PestCtrl=model.PestCtrl;
}
}
})
.catch((err:BusinessError) => {
AlertDialog.show({
title:'网络异常~',
message:err.message
});
console.error('网络异常:'+ err.message);
})
}
AI诊断预测成功后,解析完接口返回的数据并在PestInfoView组件中显示。
下一篇:实现“保存到我的诊断记录”功能
更多关于HarmonyOS鸿蒙NEXT中病虫害AI诊断预测功能实现的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
HarmonyOS NEXT中实现病虫害AI诊断预测功能主要涉及以下技术点:
- 使用ArkTS开发AI推理模块,调用NPU加速
- 集成华为HiAI Foundation的模型部署能力
- 采用MindSpore Lite框架部署预训练的图像识别模型
- 基于分布式能力实现端云协同推理
- 利用鸿蒙的Sensor API获取作物环境数据辅助诊断
数据流程:通过相机获取作物图像,经AI模型分析后返回病虫害类型及概率,结合环境传感器数据提升准确率。需准备标注好的病虫害数据集训练专用模型。
更多关于HarmonyOS鸿蒙NEXT中病虫害AI诊断预测功能实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
您的代码实现已经比较完整地展示了HarmonyOS中调用AI模型服务进行病虫害诊断的流程。以下是几点技术要点分析:
- 文件处理部分:
- 使用了fileIo模块的openSync/copyFileSync进行文件操作
- 通过image.createImagePacker()实现了图片压缩,建议quality参数(40)可根据实际需求调整
- 网络请求部分:
- 正确构建了multipart/form-data格式的请求体
- 使用了http.createHttp()进行API调用
- 边界字符串boundary的生成方式可以优化为更标准的UUID
- 性能优化建议:
- 可考虑添加图片尺寸检查,避免上传过大图片
- 可添加请求超时设置(默认60秒可能过长)
- 建议对ArrayBuffer操作添加try-catch异常处理
- 业务逻辑部分:
- 置信度阈值0.9的设置合理
- 错误处理机制完善,区分了服务异常和网络异常
整体实现符合HarmonyOS应用开发规范,代码结构清晰。后续可考虑添加本地缓存机制,在无网络时显示历史诊断记录。