基于HarmonyOS的AI圖像識別應用開發(fā)(ETS)
前言
原本打算在九聯開發(fā)板上搭配攝像頭開發(fā),去實現拍照并對圖片進行AI識別的應用開發(fā),但是遇到了點問題。
不過基于HarmonyOS的AI圖像識別案例可以正常運作,于是作此文章作為小分享O(∩_∩)O。
概述
本案例是通過網絡請求連接到百度云,調用百度云AI圖像識別的API,再將結果返回至應用顯示。??百度云文檔??。
舉例效果圖:
正文
一、創(chuàng)建項目
項目選擇HarmonyOS的Empty Ability模板,API選擇8,語言選擇ets。
二、添加權限及導入模塊
1、在config.json文件中添加權限。
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
2、在index.ets文件中導入模塊,第一個是資源管理模塊,第二個是網絡模塊。
import resourceManager from '@ohos.resourceManager';
import http from '@ohos.net.http';
三、創(chuàng)建網絡請求并根據百度云API傳參
該API調用前需要獲取access_token,具體方法見其??文檔??(注意的是創(chuàng)建應用后要去開啟圖像識別的服務)。
定義變量
access_token: string = 'Hello World'
Base64Str: string = 'Hello World'
result_description: string = 'description'
result_keyword: string = 'keyword'
result_root: string = 'root'
result_image: string = 'image'
并上傳要識別的圖片到項目中,此案例中使用的是一張蓮藕的圖片。
編寫函數獲取access_token
GetAccessToken() {
let httpRequest = http.createHttp();
httpRequest.request(
//自行替換AK和SK
"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【百度云應用的AK】&client_secret=【百度云應用的SK】",
{
method: http.RequestMethod.POST,
connectTimeout: 60000,
readTimeout: 60000,
}, (err, data) => {
if (!err) {
let obj = JSON.parse(data.result.toString());
this.access_token=obj.access_token
console.info('Result1:' + data.result);
console.info('Result1_token:' + this.access_token);
} else {
console.info('Result1_error:' + JSON.stringify(err));
httpRequest.destroy();
}
})
}
編寫函數編碼圖片并去掉編碼頭
resourceManager.getResourceManager 此API只適用于FA模型,stage模型不適用。(所以在標準系統(tǒng)相機開發(fā)模型為stage時,不能用此方法對圖片編碼)。
//base64編碼
GetBase64(){
let that = this
resourceManager.getResourceManager((error, mgr) => {
if (error != null) {
console.log("ResourceManager error is " + error)
} else {
mgr.getMediaBase64($r('app.media.lianou').id, (error, value) => {
if (error != null) {
console.log("base64_error is " + error)
} else {
console.info('base64_result:' + value)
that.Base64Str = that.getCaption(value)
console.info('base64Str:' + this.Base64Str)
}
});
}
});
}
//去掉編碼頭
getCaption(obj) {
var index = obj.lastIndexOf("\,");
obj = obj.substring(index + 1, obj.length);
return obj;
}
編寫函數調用圖像識別API
注:這里 header:{‘Content-Type’: ‘application/x-www-form-urlencoded’} 才能傳image參數到百度云。HTTP請求頭字段,默認{‘Content-Type’: ‘application/json’} 。筆者將能在harmonyOS模擬器上跑起來的同樣代碼復制到一個新建的openHarmony項目中,但是會報錯:缺參。通過后臺調試發(fā)現能接收url的參數access_token和header參數,當header為默認類型時能接收到extraData里的參數,但當header為’application/x-www-form-urlencoded’時,無法收到extraData里的參數,所以初步認為是筆者所用OH系統(tǒng)版本的網絡請求庫不支持application/x-www-form-urlencoded傳參。
AI_request() {
let httpRequest = http.createHttp();
httpRequest.request(
"https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general?access_token="+ this.access_token,
{
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
extraData: {
'image': this.Base64Str,
'baike_num': 1
},
connectTimeout: 60000,
readTimeout: 60000,
}, (err, data) => {
if (!err) {
let obj = JSON.parse(data.result.toString());
this.result_description = obj.result[0].baike_info.description;
this.result_keyword = obj.result[0].keyword;
this.result_image = obj.result[0].baike_info.image_url;
this.result_root = obj.result[0].root;
console.info('Result_description:' + this.result_description)
console.info('Result_keyword:' + this.result_keyword)
console.info('Result_root:' + this.result_root)
console.info('Result_image:' + this.result_image)
} else {
console.info('Result2_error:' + JSON.stringify(err));
httpRequest.destroy();
}
})
}
四、編寫UI界面調用函數
因為圖片編碼需要點時間,為了避免傳參時出現錯誤,于是添加了一個延遲函數。
build() {
Column({ space: 10 }) {
Button('AI識別')
.onClick(() => {
this.GetBase64()
this.GetAccessToken()
setTimeout(()=>{
this.AI_request()
},1400)
})
Image(this.result_image)
.width(150)
.height(150)
Row({ space: 20 }) {
Text(this.result_keyword)
.fontSize(20)
.width(150)
.height(35)
.textAlign(TextAlign.Start)
.margin(15)
Text(this.result_root)
.fontSize(20)
.textAlign(TextAlign.Start)
.width(150)
.height(35)
.margin(15)
}.width('100%')
.height(35)
Text(this.result_description)
.fontSize(20)
.textAlign(TextAlign.Start)
.width('90%')
.height(250)
}
.width('100%')
.height('100%')
}
}
結語
以上就是本次的小分享啦!