HarmonyOS智慧农业管理应用开发教程--高高种地--第16篇:HarmonyOS AI能力概述与集成
AI能力说明应用场景Vision Kit图像识别与分析植物识别、病虫害诊断、文字识别Speech Kit语音识别与合成语音播报、语音输入NLP Kit自然语言处理文本分析、智能问答翻译服务多语言翻译本项目使用的AI能力✅Vision Kit:用于植物识别、病虫害诊断✅:用于操作提示的语音播报识别类型枚举值功能说明文字识别识别图片中的文字(OCR)主体识别识别图片主体并支持抠图物体搜索识别物体并提供
第16篇:HarmonyOS AI能力概述与集成
📚 本篇导读
在前面的教程中,我们已经完成了地图导航、数据分析等核心功能。从本篇开始,我们将进入AI能力的学习,这是HarmonyOS平台的一大亮点。通过集成HarmonyOS AI Kit,我们可以为应用添加图像识别、语音合成等智能功能,让农业管理更加智能化。
本篇将实现:
- 🤖 HarmonyOS AI Kit概述(Vision Kit、Speech Kit)
- 🔧 Vision Kit集成配置(图像识别能力)
- 🎙️ Core Speech Kit集成配置(语音合成能力)
- 🔐 AI能力权限配置
- ⚙️ AI服务初始化
🎯 学习目标
完成本篇教程后,你将掌握:
- HarmonyOS AI Kit的整体架构和能力
- 如何集成Vision Kit实现图像识别
- 如何集成Core Speech Kit实现语音合成
- AI能力所需的权限配置
- AI服务的初始化流程
一、HarmonyOS AI Kit概述
1.1 什么是HarmonyOS AI Kit?
HarmonyOS AI Kit是华为提供的端侧AI能力开放平台,为开发者提供了一系列开箱即用的AI能力,包括:
| AI能力 | 说明 | 应用场景 |
|---|---|---|
| Vision Kit | 图像识别与分析 | 植物识别、病虫害诊断、文字识别 |
| Speech Kit | 语音识别与合成 | 语音播报、语音输入 |
| NLP Kit | 自然语言处理 | 文本分析、智能问答 |
| Translation Kit | 翻译服务 | 多语言翻译 |
本项目使用的AI能力:
- ✅ Vision Kit:用于植物识别、病虫害诊断
- ✅ Core Speech Kit (TTS):用于操作提示的语音播报
1.2 AI能力的优势
端侧AI的优势:
- 🚀 响应快速:无需网络请求,毫秒级响应
- 🔒 隐私保护:数据不上传云端,本地处理
- 💰 成本低廉:无需调用云端API,节省费用
- 📱 离线可用:无网络环境也能使用
1.3 AI能力架构
应用层
├── ImageScanPage(图像识别页面)
└── TTSService(语音合成服务)
↓
AI Kit层
├── Vision Kit
│ ├── ImageAnalyzer(图像分析器)
│ ├── TEXT(文字识别)
│ ├── SUBJECT(主体识别)
│ └── OBJECT_LOOKUP(物体搜索)
└── Core Speech Kit
├── TextToSpeechEngine(TTS引擎)
├── speak()(朗读文本)
└── stop()(停止播报)
↓
系统层
└── HarmonyOS AI能力底层
二、Vision Kit集成
2.1 Vision Kit简介
Vision Kit提供了强大的图像识别能力,主要包括:
| 识别类型 | 枚举值 | 功能说明 |
|---|---|---|
| 文字识别 | ImageAnalyzerType.TEXT |
识别图片中的文字(OCR) |
| 主体识别 | ImageAnalyzerType.SUBJECT |
识别图片主体并支持抠图 |
| 物体搜索 | ImageAnalyzerType.OBJECT_LOOKUP |
识别物体并提供搜索功能 |
2.2 导入Vision Kit
在页面文件中导入Vision Kit相关模块:
// 导入Vision Kit
import { visionImageAnalyzer } from '@kit.VisionKit';
// 导入图像处理相关
import { image } from '@kit.ImageKit';
// 导入文件操作
import { fileIo } from '@kit.CoreFileKit';
import { picker } from '@kit.CoreFileKit';
// 导入相机
import { cameraPicker } from '@kit.CameraKit';
import { camera } from '@kit.CameraKit';
模块说明:
@kit.VisionKit:Vision Kit核心模块@kit.ImageKit:图像处理模块(PixelMap)@kit.CoreFileKit:文件操作模块@kit.CameraKit:相机调用模块
2.3 创建图像分析控制器
@Entry
@ComponentV2
struct ImageScanPage {
// 选中的图片URI
@Local selectedImageUri: string = '';
// 选中的图片PixelMap(用于显示和识别)
@Local selectedPixelMap: image.PixelMap | null = null;
// Vision Kit图像分析控制器
private visionImageAnalyzerController: visionImageAnalyzer.VisionImageAnalyzerController =
new visionImageAnalyzer.VisionImageAnalyzerController();
}
关键点:
VisionImageAnalyzerController:图像分析控制器,负责管理识别过程PixelMap:图像的像素数据,Vision Kit需要RGBA_8888格式- 控制器在页面创建时初始化,无需额外配置
2.4 设置识别监听器
在页面显示时设置各种识别事件的监听器:
onPageShow(): void {
// 1. 监听识别界面可见性变化
this.visionImageAnalyzerController.on('imageAnalyzerVisibilityChange',
(visibility: visionImageAnalyzer.ImageAnalyzerVisibility) => {
console.info('[ImageScanPage] 识别界面可见性:', JSON.stringify(visibility));
});
// 2. 监听文字识别结果
this.visionImageAnalyzerController.on('textAnalysis', (text: string) => {
console.info('[ImageScanPage] 文字识别结果:', text);
// 可以在这里处理识别到的文字
});
// 3. 监听选中文字变化
this.visionImageAnalyzerController.on('selectedTextChange', (selectedText: string) => {
console.info('[ImageScanPage] 选中文字:', selectedText);
});
// 4. 监听主体识别结果
this.visionImageAnalyzerController.on('subjectAnalysis',
(subjects: visionImageAnalyzer.Subject[]) => {
console.info('[ImageScanPage] 主体识别结果:', JSON.stringify(subjects));
// 可以在这里处理识别到的主体
});
// 5. 监听选中主体变化
this.visionImageAnalyzerController.on('selectedSubjectsChange',
(subjects: visionImageAnalyzer.Subject[]) => {
console.info('[ImageScanPage] 选中主体:', JSON.stringify(subjects));
});
// 6. 监听识别失败
this.visionImageAnalyzerController.on('analyzerFailed', (error: BusinessError) => {
console.error('[ImageScanPage] 识别失败:', JSON.stringify(error));
promptAction.showToast({
message: '识别失败,请重试',
duration: 2000
});
});
}
监听器说明:
| 监听器 | 触发时机 | 用途 |
|---|---|---|
imageAnalyzerVisibilityChange |
识别界面显示/隐藏 | 监控识别状态 |
textAnalysis |
文字识别完成 | 获取OCR结果 |
selectedTextChange |
用户选中文字 | 处理选中的文字 |
subjectAnalysis |
主体识别完成 | 获取主体信息 |
selectedSubjectsChange |
用户选中主体 | 处理选中的主体 |
analyzerFailed |
识别失败 | 错误处理 |
2.5 在Image组件中启用AI识别
Vision Kit的核心是通过Image组件的特殊配置来启用AI识别:
// 图片预览区域
if (this.selectedPixelMap) {
Image(this.selectedPixelMap, {
// 配置识别类型
types: [
ImageAnalyzerType.TEXT, // 文字识别
ImageAnalyzerType.SUBJECT, // 主体识别
ImageAnalyzerType.OBJECT_LOOKUP // 物体搜索
],
// 绑定控制器
aiController: this.visionImageAnalyzerController
})
.width('100%')
.height(400)
.objectFit(ImageFit.Contain)
.borderRadius(12)
.enableAnalyzer(true) // 启用AI分析器
}
关键配置:
types:指定要启用的识别类型(可多选)aiController:绑定图像分析控制器enableAnalyzer(true):启用AI分析功能
用户交互:
- 用户长按图片会触发识别
- 系统会自动显示识别结果的交互界面
- 用户可以选择文字、主体进行操作(复制、分享、搜索等)
2.6 图片选择与转换
Vision Kit需要PixelMap格式的图片,我们需要将URI转换为PixelMap:
/**
* 从相册选择图片
*/
async selectImageFromGallery(): Promise<void> {
try {
// 1. 配置选择器选项
const photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = 1; // 只选择一张
// 2. 打开相册选择器
const photoPicker = new picker.PhotoViewPicker();
const photoSelectResult = await photoPicker.select(photoSelectOptions);
// 3. 获取选中的图片URI
if (photoSelectResult && photoSelectResult.photoUris &&
photoSelectResult.photoUris.length > 0) {
this.selectedImageUri = photoSelectResult.photoUris[0];
console.info('[ImageScanPage] 选中图片URI:', this.selectedImageUri);
// 4. 将URI转换为PixelMap
await this.convertUriToPixelMap(this.selectedImageUri);
}
} catch (error) {
const err = error as BusinessError;
console.error('[ImageScanPage] 选择图片失败:', err);
promptAction.showToast({
message: '选择图片失败',
duration: 2000
});
}
}
/**
* 将URI转换为PixelMap(RGBA_8888格式)
*/
async convertUriToPixelMap(uri: string): Promise<void> {
try {
// 1. 打开文件
const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
// 2. 创建ImageSource
const imageSourceApi: image.ImageSource = image.createImageSource(file.fd);
// 3. 创建PixelMap,指定格式为RGBA_8888(Vision Kit要求)
const pixelMap: image.PixelMap = await imageSourceApi.createPixelMap({
desiredPixelFormat: image.PixelMapFormat.RGBA_8888
});
// 4. 保存PixelMap
this.selectedPixelMap = pixelMap;
// 5. 释放资源
await imageSourceApi.release();
fileIo.closeSync(file);
console.info('[ImageScanPage] PixelMap创建成功');
} catch (error) {
const err = error as BusinessError;
console.error('[ImageScanPage] 转换PixelMap失败:', err);
promptAction.showToast({
message: '图片加载失败',
duration: 2000
});
}
}
转换流程:
- 打开图片文件获取文件描述符(fd)
- 使用ImageSource创建图像源
- 创建PixelMap并指定RGBA_8888格式
- 释放资源避免内存泄漏
重要提示:
- Vision Kit要求PixelMap格式为
RGBA_8888 - 必须释放ImageSource和文件资源
- 转换过程是异步的,需要使用await
2.7 相机拍照
除了从相册选择,还可以调用相机拍照:
/**
* 拍照
*/
async takePhoto(): Promise<void> {
try {
const context = getContext(this) as common.UIAbilityContext;
// 1. 配置相机参数
const pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, // 后置摄像头
saveUri: '' // 空表示使用默认路径
};
// 2. 调用系统相机拍照
const result: cameraPicker.PickerResult = await cameraPicker.pick(
context,
[cameraPicker.PickerMediaType.PHOTO], // 拍照模式
pickerProfile
);
// 3. 获取拍照结果
if (result && result.resultCode === 0 && result.resultUri) {
this.selectedImageUri = result.resultUri;
console.info('[ImageScanPage] 拍照URI:', this.selectedImageUri);
// 4. 转换为PixelMap
await this.convertUriToPixelMap(this.selectedImageUri);
}
} catch (error) {
const err = error as BusinessError;
console.error('[ImageScanPage] 拍照失败:', err);
promptAction.showToast({
message: '拍照失败',
duration: 2000
});
}
}
相机配置说明:
CAMERA_POSITION_BACK:使用后置摄像头(也可选择前置)PickerMediaType.PHOTO:拍照模式(也可选择视频)resultCode === 0:表示拍照成功
三、Core Speech Kit集成(TTS语音合成)
3.1 Core Speech Kit简介
Core Speech Kit提供了文字转语音(TTS)和语音识别(ASR)能力,本项目使用TTS功能实现语音播报。
TTS功能特点:
- 🎙️ 支持多种音色(男声、女声)
- 🌐 支持多语言(中文、英文等)
- ⚙️ 可调节语速、音量、音调
- 📱 支持在线和离线模式
3.2 创建TTS服务类
为了方便复用,我们创建一个单例的TTS服务类:
文件位置:entry/src/main/ets/services/TTSService.ets
/**
* AI语音合成服务 - 使用 TextToSpeech API
*/
import { textToSpeech } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* TTS服务类(单例模式)
*/
export class TTSService {
private static instance: TTSService | null = null;
private ttsEngine: textToSpeech.TextToSpeechEngine | null = null;
private isInitialized: boolean = false;
private constructor() {}
/**
* 获取单例实例
*/
static getInstance(): TTSService {
if (TTSService.instance === null) {
TTSService.instance = new TTSService();
}
return TTSService.instance;
}
/**
* 初始化TTS引擎
*/
async initialize(): Promise<void> {
if (this.isInitialized) {
console.info('[TTSService] 已经初始化');
return;
}
try {
// 1. 配置引擎参数
let extraParam: Record<string, Object> = {
'style': 'interaction-broadcast', // 交互播报风格
'locate': 'CN', // 中国地区
'name': 'LangduTTS' // 引擎名称
};
let initParamsInfo: textToSpeech.CreateEngineParams = {
language: 'zh-CN', // 中文
person: 0, // 音色:0=聆小珊(女声)
online: 1, // 在线模式
extraParams: extraParam
};
// 2. 创建TTS引擎
this.ttsEngine = await textToSpeech.createEngine(initParamsInfo);
this.isInitialized = true;
console.info('[TTSService] 初始化成功');
} catch (error) {
const err = error as BusinessError;
console.error(`[TTSService] 初始化失败: ${err.code} - ${err.message}`);
throw Error(`TTS初始化失败: ${err.message}`);
}
}
}
// 导出单例实例
export const ttsService = TTSService.getInstance();
初始化参数说明:
| 参数 | 说明 | 可选值 |
|---|---|---|
language |
语言 | ‘zh-CN’(中文)、‘en-US’(英文) |
person |
音色 | 0(女声)、1(男声) |
online |
模式 | 0(离线)、1(在线) |
style |
风格 | ‘interaction-broadcast’(交互播报) |
3.3 实现语音播报方法
/**
* 朗读文本
* @param text 要朗读的文本(最大10000字符)
* @param speed 语速(0.5-2.0),默认1.0
* @param volume 音量(0.0-1.0),默认1.0
*/
async speak(text: string, speed: number = 1.0, volume: number = 1.0): Promise<void> {
if (!this.isInitialized || this.ttsEngine === null) {
console.error('[TTSService] 服务未初始化');
throw Error('TTS服务未初始化');
}
if (text.length === 0) {
console.warn('[TTSService] 文本为空');
return;
}
// 文本长度限制
if (text.length > 10000) {
console.warn('[TTSService] 文本过长,截断到10000字符');
text = text.substring(0, 10000);
}
try {
// 1. 配置播报参数
let extraParam: Record<string, Object> = {
'speed': speed, // 语速
'volume': volume, // 音量
'pitch': 1.0, // 音调
'languageContext': 'zh-CN',
'audioType': 'pcm'
};
let speakParams: textToSpeech.SpeakParams = {
requestId: Date.now().toString(), // 请求ID(用于标识)
extraParams: extraParam
};
// 2. 设置监听器
return new Promise<void>((resolve, reject) => {
let speakListener: textToSpeech.SpeakListener = {
// 开始播报
onStart: (requestId: string, response: textToSpeech.StartResponse) => {
console.info(`[TTSService] 开始播报, requestId: ${requestId}`);
},
// 播报完成
onComplete: (requestId: string, response: textToSpeech.CompleteResponse) => {
console.info(`[TTSService] 播报完成, requestId: ${requestId}`);
resolve();
},
// 停止播报
onStop: (requestId: string, response: textToSpeech.StopResponse) => {
console.info(`[TTSService] 停止播报, requestId: ${requestId}`);
resolve();
},
// 播报错误
onError: (requestId: string, errorCode: number, errorMessage: string) => {
console.error(`[TTSService] 播报错误: ${errorCode} - ${errorMessage}`);
reject(new Error(`TTS错误: ${errorMessage}`));
},
// 音频数据回调(可选)
onData: (requestId: string, audio: ArrayBuffer,
response: textToSpeech.SynthesisResponse) => {
// 音频数据回调,可用于自定义处理
}
};
// 3. 设置监听器并开始播报
this.ttsEngine!.setListener(speakListener);
this.ttsEngine!.speak(text, speakParams);
});
} catch (error) {
const err = error as BusinessError;
console.error(`[TTSService] 播报失败: ${err.message}`);
throw Error(`TTS播报失败: ${err.message}`);
}
}
/**
* 停止当前播报
*/
stop(): void {
if (this.ttsEngine !== null) {
this.ttsEngine.stop();
console.info('[TTSService] 已停止');
}
}
/**
* 判断是否正在播报
*/
isBusy(): boolean {
if (this.ttsEngine !== null) {
return this.ttsEngine.isBusy();
}
return false;
}
/**
* 释放资源
*/
async release(): Promise<void> {
if (this.ttsEngine !== null) {
await this.ttsEngine.shutdown();
this.ttsEngine = null;
}
this.isInitialized = false;
console.info('[TTSService] 资源已释放');
}
播报参数说明:
| 参数 | 类型 | 范围 | 说明 |
|---|---|---|---|
speed |
number | 0.5-2.0 | 语速,1.0为正常速度 |
volume |
number | 0.0-1.0 | 音量,1.0为最大音量 |
pitch |
number | 0.5-2.0 | 音调,1.0为正常音调 |
3.4 在页面中使用TTS服务
import { ttsService } from '../../services/TTSService';
@Entry
@ComponentV2
struct ImageScanPage {
async aboutToAppear(): Promise<void> {
// 初始化TTS服务
await ttsService.initialize();
}
onPageHide(): void {
// 页面隐藏时停止TTS
ttsService.stop();
}
// 朗读图片加载完成提示
async speakImageLoadedTip(): Promise<void> {
try {
const tipText = '图片选择完成,请长按图片进行分享或者搜索';
await ttsService.speak(tipText);
console.info('[ImageScanPage] TTS提示已播报');
} catch (error) {
console.error('[ImageScanPage] TTS播报失败:', error);
}
}
}
使用要点:
- 在页面加载时初始化TTS服务
- 在页面隐藏时停止播报,避免后台播放
- 使用try-catch捕获播报错误
四、权限配置
4.1 AI能力所需权限
虽然Vision Kit和Speech Kit是端侧AI,但仍需要一些基础权限:
module.json5配置:
{
"module": {
"requestPermissions": [
// 网络权限(在线模式需要)
{
"name": "ohos.permission.INTERNET"
},
// 相机权限(拍照需要)
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
// 读取媒体库权限(选择图片需要)
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}
权限说明:
| 权限 | 用途 | 是否必需 |
|---|---|---|
INTERNET |
TTS在线模式、图片上传 | 可选 |
CAMERA |
调用相机拍照 | 拍照功能必需 |
READ_MEDIA |
从相册选择图片 | 选择图片必需 |
4.2 权限申请代码
对于敏感权限(如相机),需要在运行时动态申请:
import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* 请求相机权限
*/
async requestCameraPermission(): Promise<boolean> {
const permissions: Permissions[] = ['ohos.permission.CAMERA'];
try {
const context = getContext(this) as common.UIAbilityContext;
const atManager = abilityAccessCtrl.createAtManager();
// 请求权限
const result = await atManager.requestPermissionsFromUser(context, permissions);
// 检查授权结果
const grantStatus = result.authResults;
if (grantStatus[0] === 0) {
console.info('[ImageScanPage] 相机权限已授权');
return true;
} else {
console.warn('[ImageScanPage] 相机权限被拒绝');
promptAction.showToast({
message: '需要相机权限才能拍照',
duration: 2000
});
return false;
}
} catch (error) {
const err = error as BusinessError;
console.error(`[ImageScanPage] 请求权限失败: ${err.code}, ${err.message}`);
return false;
}
}
权限申请时机:
- 在用户点击"拍照"按钮时申请相机权限
- 在用户点击"选择图片"按钮时申请媒体库权限
- 避免在应用启动时一次性申请所有权限
五、完整示例:图像识别页面
5.1 页面结构
@Entry
@ComponentV2
struct ImageScanPage {
// 状态变量
@Local selectedImageUri: string = '';
@Local selectedPixelMap: image.PixelMap | null = null;
// AI控制器
private visionImageAnalyzerController: visionImageAnalyzer.VisionImageAnalyzerController =
new visionImageAnalyzer.VisionImageAnalyzerController();
// 生命周期
async aboutToAppear(): Promise<void> {
await ttsService.initialize();
}
onPageShow(): void {
// 设置Vision Kit监听器
this.setupVisionListeners();
}
onPageHide(): void {
ttsService.stop();
}
build() {
Column() {
// 导航栏
this.buildNavigationBar()
Scroll() {
Column({ space: 16 }) {
// 图片预览区域
if (this.selectedPixelMap) {
this.buildImagePreview()
} else {
this.buildEmptyState()
}
// 操作按钮
this.buildActionButtons()
// 使用说明
if (!this.selectedPixelMap) {
this.buildInstructions()
}
}
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.background'))
}
}
5.2 图片预览组件
@Builder
buildImagePreview() {
Column({ space: 12 }) {
// AI识别图片
Image(this.selectedPixelMap, {
types: [
ImageAnalyzerType.TEXT,
ImageAnalyzerType.SUBJECT,
ImageAnalyzerType.OBJECT_LOOKUP
],
aiController: this.visionImageAnalyzerController
})
.width('100%')
.height(400)
.objectFit(ImageFit.Contain)
.borderRadius(12)
.shadow({ radius: 8, color: '#20000000', offsetY: 2 })
.enableAnalyzer(true)
// 操作提示
Row({ space: 8 }) {
Text('💡')
.fontSize(16)
Text('长按图片识别花草或者物品分享给朋友')
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
}
.width('100%')
.padding(12)
.backgroundColor($r('app.color.background'))
.borderRadius(8)
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(16)
.margin(16)
}
5.3 操作按钮
@Builder
buildActionButtons() {
Row({ space: 12 }) {
Button('选择图片')
.fontSize(16)
.layoutWeight(1)
.backgroundColor($r('app.color.primary_home_gardening'))
.onClick(() => {
this.selectImageFromGallery();
})
Button('拍照')
.fontSize(16)
.layoutWeight(1)
.backgroundColor($r('app.color.primary_professional'))
.onClick(() => {
this.takePhoto();
})
}
.width('100%')
.padding({ left: 16, right: 16 })
}
六、实操练习
练习1:测试图像识别
任务:选择一张包含文字的图片,测试文字识别功能
步骤:
- 运行应用,进入"扫一扫"页面
- 点击"选择图片"按钮
- 从相册选择一张包含文字的图片
- 长按图片,观察识别结果
- 查看控制台日志,确认识别成功
预期结果:
- 图片加载后自动播报提示音
- 长按图片后显示识别界面
- 可以选择识别到的文字进行复制
练习2:测试语音播报
任务:修改TTS播报内容和参数
步骤:
- 修改
speakImageLoadedTip()方法中的文本 - 调整语速参数(如1.5倍速)
- 重新运行应用
- 选择图片,听取播报效果
代码示例:
async speakImageLoadedTip(): Promise<void> {
const tipText = '您好,图片已加载完成,请长按进行识别';
await ttsService.speak(tipText, 1.5, 1.0); // 1.5倍速
}
练习3:测试相机拍照
任务:使用相机拍照并识别
步骤:
- 点击"拍照"按钮
- 授权相机权限
- 拍摄一张照片
- 长按照片进行识别
- 测试主体识别功能
预期结果:
- 相机正常启动
- 拍照后图片正常显示
- 可以识别照片中的主体
七、常见问题与解决方案
问题1:Vision Kit识别无响应
现象:长按图片没有任何反应
可能原因:
- PixelMap格式不正确
- 未启用enableAnalyzer
- 监听器未正确设置
解决方案:
// 1. 确保PixelMap格式为RGBA_8888
const pixelMap = await imageSourceApi.createPixelMap({
desiredPixelFormat: image.PixelMapFormat.RGBA_8888
});
// 2. 确保启用分析器
Image(this.selectedPixelMap, {
types: [ImageAnalyzerType.TEXT, ImageAnalyzerType.SUBJECT],
aiController: this.visionImageAnalyzerController
})
.enableAnalyzer(true) // 必须设置
// 3. 在onPageShow中设置监听器
onPageShow(): void {
this.visionImageAnalyzerController.on('textAnalysis', (text: string) => {
console.info('识别结果:', text);
});
}
问题2:TTS播报无声音
现象:调用speak()方法但没有声音
可能原因:
- TTS引擎未初始化
- 设备音量为0
- 文本为空
解决方案:
// 1. 确保初始化
async aboutToAppear(): Promise<void> {
try {
await ttsService.initialize();
console.info('TTS初始化成功');
} catch (error) {
console.error('TTS初始化失败:', error);
}
}
// 2. 检查文本
if (text && text.length > 0) {
await ttsService.speak(text);
}
// 3. 检查引擎状态
if (ttsService.isBusy()) {
console.info('TTS正在播报');
}
八、总结
本篇教程完成了HarmonyOS AI能力的基础集成,主要包括:
✅ 已实现功能
| 功能 | 说明 |
|---|---|
| Vision Kit集成 | 图像识别控制器、监听器配置 |
| 文字识别 | OCR文字识别功能 |
| 主体识别 | 图片主体识别与抠图 |
| 物体搜索 | 物体识别与搜索 |
| TTS语音合成 | 文字转语音播报 |
| 图片选择 | 相册选择、相机拍照 |
| 权限管理 | 相机、媒体库权限申请 |
🎯 核心技术点
- VisionImageAnalyzerController:图像分析控制器
- ImageAnalyzerType:识别类型配置
- TextToSpeechEngine:TTS引擎
- PixelMap:图像像素数据(RGBA_8888格式)
- 权限动态申请:运行时权限管理
🚀 下一步
在下一篇教程中,我们将学习:
- 植物识别功能实现
- 识别结果处理与展示
- 识别历史记录管理
- 识别结果分享功能
教程版本:v1.0
更新日期:2024-01-20
作者:高高种地开发团队
相关资源:
恭喜! 🎉 你已经完成了HarmonyOS AI能力的基础集成。现在你的应用具备了图像识别和语音播报的能力,为后续的智能功能打下了坚实的基础。
更多推荐

所有评论(0)