【HMS Core】一张图片带你玩转机器学习服务
1、介绍
总览
Cloud DB(云数据库)是一款端云协同的数据库产品,提供端云数据的协同管理、统一的数据模型和丰富的数据管理API接口等能力。在保证数据的可用性、可靠性、一致性,以及安全等特性基础上,能够实现数据在客户端和云端之间的无缝同步。
ML Kit为(机器学习服务)开发者提供简单易用、服务多样、技术领先的机器学习能力,助力开发者更快更好地开发各类AI应用。
您将建立什么
在本次Codelab中,您将建立一个示例项目并集成ML Kit和Cloud DB。在该项目中,您可以:
1、使用键盘或图像分类进行图像搜索
2、列出Cloud DB中的图像
3、检测图像描述的语言
4、翻译图像描述
5、声化图像描述
您需要什么
在本codelab中,你需要学习:
1、如何在AppGallery Connect中创建项目和应用程序
2、如何集成ML Kit和Cloud DB
3、如何使用ML Kit和Cloud DB
2、您需要什么
硬件需求
- 一台笔记本或台式电脑。 
- 华为手机:EMUI 8.0版本或以上,运行HMS Core (APK) 5.0.1.301及以上版本;非华为手机:Android 7.0或以上,运行HMS Core (APK) 5.0.1.301或以上版本。 
- 手机用于运行和调试demo 
软件需求
- JDK版本:1.8或以上 
- Android Studio版本:3.X或以上 
- minSdkVersion:24或以上 
- targetSdkVersion:29 
- compileSdkVersion:29 
- Gradle版本:4.6或以上 
必备知识
安卓应用开发基础知识
3、集成前准备
集成前,需要完成以下准备工作:
说明:
在进行准备前,请先注册开发者帐号。
- 在AppGallery Connect中创建项目和应用。 
- 创建Android Studio项目。 
- 生成签名证书。 
- 生成签名证书指纹。 
- 在AppGallery Connect中将签名指纹添加到应用中。 
- 添加必要配置。 
- 配置项目签名。 
- 同步项目。 
详情请参见HUAWEI HMS Core集成准备。
4、集成HMS Core SDK
添加您应用的AppGallery Connect配置文件
- 登录AppGallery Connect,点击“我的项目”,在项目列表中找到并点击您的项目。 
- 在“项目设置”页面选择“常规”页签。 
- 在“项目”区域下点击“数据处理位置”后的“启用”。   
- 点击“应用”区域的“agconnect-services.json”下载配置文件。   
- 将配置文件"agconnect-services.json"复制到应用级根目录下。   
添加编译依赖
- 打开应用级的“build.gradle”文件。 
- 在dependencies代码段中添加如下编译依赖。 - dependencies {
 // Import Cloud DB.
 implementation 'com.huawei.agconnect:agconnect-cloud-database:{version}'
 // Import Image Classification
 implementation 'com.huawei.hms:ml-computer-vision-classification:{version}'
 // Import Image Classification Model
 Implementation 'com.huawei.hms:ml-computer-vision-image-classification-model:{version}'
 // Import Real-Time Translation
 implementation 'com.huawei.hms:ml-computer-translate:{version}'
 // Import Real-Time Language Detection
 implementation 'com.huawei.hms:ml-computer-language-detection:{version}'
 // Import Text To Speech
 implementation 'com.huawei.hms:ml-computer-voice-tts:{version}'
 } - 具体说明如下: - a.将{version}替换为Cloud DB的最新版本号,例如com.huawei.agconnect:agconnect-cloud-database:1.5.4.300。有关最新版本号的详细信息,请参见文档。 - b.将{version}替换为ML Kit的最新版本号,例如com.huawei.agconnect:agconnect-function-ktx 1.7.1.300。有关最新版本号的详细信息,请参见文档。 
- 在build.gradle文件中,设置Java源代码的兼容性模式为JDK1.8。 - compileOptions {
 sourceCompatibility = 1.8
 targetCompatibility = 1.8
 } 
- 在应用级build.gradle文件中设置minSdkVersion。 - android {
 ...
 defaultConfig {
 ...
 minSdkVersion 26
 ...
 }
 ...
 } 
- 检查是否已添加AppGallery Connect插件。如没有,在应用级build.gradle文件中添加该插件。 - apply plugin: 'com.huawei.agconnect' 
配置混淆脚本
编译APK前需要配置混淆脚本,避免混淆HMS Core SDK。如果出现混淆,HMS Core SDK可能无法正常工作。
Android Studio开发环境里的混淆脚本是“proguard-rules.pro”。
加入排除HMS SDK的混淆配置。
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
5、设计UI
 
 
6、在AppGallery Connect中初始化云数据库
步骤一:创建云数据库的存储区
1)登录AppGallery Connect,单击我的项目。
2)在项目列表中选择一个项目,单击需要添加Cloud DB区域的应用。
3)在左侧导航栏中,选择“Serverless > 云数据库”。
4)点击云数据库区域选项卡。
5)点击“新增”,进入云数据库区域创建页面。
 
 
步骤二:在AGC中创建云数据库对象类型
1)登录AppGallery Connect,单击我的项目。
2)在项目列表中选择一个项目,单击需要添加Cloud DB区域的应用。
3)在左侧导航栏中,选择“Serverless > 云数据库”。
4)根据需求执行以下操作:
a.创建对象类型:点击“新增”
b.编辑现有对象类型:点击“修改”
 
 
7、初始化云数据库
步骤一:初始化云数据库
private lateinit var mCloudDB: AGConnectCloudDB
private var handler: CompletableDeferred<Result<Unit>>? = null
private var cloudDBZone: CloudDBZone? = null
override suspend fun initialize(): Result<Unit> {
    handler = CompletableDeferred()
    AGConnectCloudDB.initialize(context)
    initializeCloudDB()
    initializeZone()
    handler?.let { return it.await() }
        ?: run { return Result.Error("An error occurred") }
}
private fun initializeCloudDB() {
    val instance = AGConnectInstance.buildInstance(
        AGConnectOptionsBuilder().setRoutePolicy(
            AGCRoutePolicy.GERMANY
        ).build(context)
    )
    mCloudDB = AGConnectCloudDB.getInstance(
        instance,
        AGConnectAuth.getInstance()
    )  mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())
}
private fun initializeZone() {
    val mConfig = CloudDBZoneConfig(
        "ImageDbZone",
        CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,      CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC
    )
    mConfig.persistenceEnabled = true
    val task = mCloudDB.openCloudDBZone2(mConfig, true)
    task.addOnSuccessListener {
        cloudDBZone = it
        handler?.complete(Result.Success(Unit))
    }.addOnFailureListener {
        handler?.complete(Result.Error(it.message ?: "An error occurred."))
    }
}
步骤二:将“query”作为搜索入参。对于接收到的“query”。根据图像对象对应的“key”字段在Cloud DB中完成过滤,根据过滤结果列出云数据库中的图像对象。
override suspend fun searchImage(query: String): List<Image> {
    val result = CompletableDeferred<List<Image>>()
    cloudDBZone?.let { dbZone ->
        dbZone.executeQuery(
            CloudDBZoneQuery.where(Image::class.java)
                .equalTo("key", query),
            CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_DEFAULT
        ).addOnCompleteListener{
            if(it.isSuccessful) {
                val cursor = it.result.snapshotObjects
                val images = mutableListOf<Image>()
                while(cursor.hasNext()) {
                    images.add(cursor.next())
                }
                result.complete(images)
            }else {
                throw it.exception
            }
        }
    }?: run {
        throw CloudDbNotInitializedException()
    }
    return result.await()}
8、集成机器学习服务
步骤一:查看权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
步骤二:ML Kit方法返回Task。创建Task.await()扩展函数,用于在协程和Task API之间转换。Task.await()等待任务完成,而不阻塞线程,并返回未包装的结果(Task<T>中的T)。
suspend fun <T> Task<T>.await(): T = suspendCoroutine { continuation ->
    addOnCompleteListener { task ->
        if (task.isSuccessful) {
            continuation.resume(task.result)
        } else {
            continuation.resumeWithException(
                task.exception ?: Exception("Unknown task exception")
            )
        }
    }
}
步骤三:图像分类
/**
 * Step 1: Create an image classification analyzer.
 *  Use customized parameter settings or default parameter settings
 *  for on-device recognition.
 *
 *      Customized ->
 *          var setting = MLLocalClassificationAnalyzerSetting
 *                        .Factory()
 *                        .setMinAcceptablePossibility(0.8f)
 *                        .create()
 *          var analyzer = MLAnalyzerFactory
 *                        .getInstance()
 *                        .getLocalImageClassificationAnalyzer(setting)
 *
 *      Default -> var analyzer = MLAnalyzerFactory
 *                               .getInstance()
 *                               .localImageClassificationAnalyzer
 *
 * Step 2: Create an MLFrame object using android.graphics.Bitmap.
 * JPG, JPEG, PNG, and BMP images are supported.
 *
 * Step 3: Call the asyncAnalyseFrame method to classify images.
 *
 * Step 4: After the recognition is complete, stop the analyzer to
 * release recognition resources.
*/
override suspend fun classifyImage(bitmap: Bitmap): List<MLImageClassification> {
    val analyzer = MLAnalyzerFactory
        .getInstance()
        .localImageClassificationAnalyzer //Step 1
    val frame = MLFrame.fromBitmap(bitmap) //Step 2
    val task = analyzer.asyncAnalyseFrame(frame) //Step 3
    val classificationResult = task.await()
    analyzer.stop() //Step 4
    return classificationResult
}
步骤四:语种检测
/**
 * Step 1: Create a language detector.
 *  Use customized parameter settings or default parameter settings
 *  to create a language detector.
 *
 *      Customized -> val setting = MLRemoteLangDetectorSetting
 *                                  .Factory()
 *                                  .setTrustedThreshold(0.01f)
 *                                  .create()
 *                    val mlRemoteLangDetector = MLLangDetectorFactory
 *                                            .getInstance()
 *                                            .getRemoteLangDetector(setting)
 *
 *      Default -> val mlRemoteLangDetector = MLLangDetectorFactory
 *                                            .getInstance()
 *                                            .remoteLangDetector
 *
 * Step 2: Implement language detection.
 *
 * Step 3: Release resources after the detection is complete.
 */
override suspend fun detectLanguage(text: String): String {
    val mlRemoteLangDetector = MLLangDetectorFactory  //Step 1
        .getInstance()
        .remoteLangDetector
    val firstBestDetectTask = mlRemoteLangDetector //Step 2
        .firstBestDetect(text)
    val detectResult = firstBestDetectTask.await()
    mlRemoteLangDetector.stop() //Step 3
    return detectResult
}
步骤五:文本翻译
/**
 * Step 1: Create a real-time text translator.
 * Language Code -> The BCP-47 standard is used for Traditional Chinese,
 * and the ISO 639-1 standard is used for other languages.
 *
 * Step 2: Implement real-time translation.
 *
 * Step 3: Release resources after the translation is complete.
 */
override suspend fun translateText(
    text: String,
    sourceLanguage:String,
    targetLanguage: String
): String {
    val setting = MLRemoteTranslateSetting //Step 1
        .Factory()
        .setSourceLangCode(sourceLanguage)
        .setTargetLangCode(targetLanguage)
        .create()
    val mlRemoteTranslator = MLTranslatorFactory
        .getInstance()
        .getRemoteTranslator(setting)
    val translatorTask = mlRemoteTranslator //Step 2
        .asyncTranslate(text)
    val translationResult = translatorTask.await()
    mlRemoteTranslator.stop() //Step 3
    return translationResult
}
步骤六:语音合成
private lateinit var mlTtsEngine: MLTtsEngine
private lateinit var mlConfigs: MLTtsConfig
// Step 1: Create a TTS engine.
override fun createInstance(){
    // Use customized parameter settings to create a TTS engine.
    mlConfigs = MLTtsConfig()
        // Set the text converted from speech to English.
        .setLanguage(MLTtsConstants.TTS_EN_US)
        // Set the English timbre.
        .setPerson(MLTtsConstants.TTS_SPEAKER_FEMALE_EN)
        // Set the speech speed.
        // The range is (0,5.0]. 1.0 indicates a normal speed.
        .setSpeed(1.0f)
        // Set the volume.
        // The range is (0,2). 1.0 indicates a normal volume.
        .setVolume(1.0f)
    mlTtsEngine = MLTtsEngine(mlConfigs)
    mlTtsEngine.setTtsCallback(callback)
}
// Step 3: Control the playback
override fun startSpeaking(text: String) {
    mlTtsEngine.speak(text,MLTtsEngine.QUEUE_APPEND)
}
// Step 3: Control the playback
override fun resumeSpeaking() {
    mlTtsEngine.resume()
}
// Step 3: Control the playback
override fun pauseSpeaking() {
    mlTtsEngine.pause()
}
// Step 4: Stop the ongoing TTS tasks and clear all TTS tasks in the queue.
override fun stopSpeaking() {
    mlTtsEngine.stop()
}
// Step 5: Release resources after TTS ends.
override fun shutDownTextToSpeech() {
    mlTtsEngine.shutdown()
}
// Step 2: Create a TTS callback function to process the TTS result.
//Pass the TTS callback to the TTS engine created in Step 1 to perform TTS.
private var callback: MLTtsCallback = object : MLTtsCallback {
    override fun onEvent(taskId: String, eventName: Int, bundle: Bundle?) {
        when(eventName){
            MLTtsConstants.EVENT_PLAY_START -> {/* Handle Event */}
            MLTtsConstants.EVENT_PLAY_RESUME -> {/* Handle Event */}
            MLTtsConstants.EVENT_PLAY_PAUSE -> {/* Handle Event */}
            MLTtsConstants.EVENT_PLAY_STOP -> {/* Handle Event */}
            MLTtsConstants.EVENT_SYNTHESIS_START -> {/* Handle Event */}
            MLTtsConstants.EVENT_SYNTHESIS_END -> {/* Handle Event */}
            MLTtsConstants.EVENT_SYNTHESIS_COMPLETE -> {{/* Handle Event */}}
        }
    }
    override fun onError(taskId: String, err: MLTtsError) {
        //Processing logic for TTS failure.
    }
    override fun onWarn(taskId: String, warn: MLTtsWarn) {
        //Alarm handling without affecting service logic.
    }
    //Return the mapping between the currently played segment and text.
    //start: start position of the audio segment in the input text;
    //end (excluded): end position of the audio segment in the input text
    override fun onRangeStart(taskId: String, start: Int, end: Int) {
        //Process the mapping between the currently played segment and text.
    }
    //taskId: ID of an audio synthesis task corresponding to the audio.
    //audioFragment: audio data.
    //offset: offset of the audio segment to be transmitted in the queue.
    //One audio synthesis task corresponds to an audio synthesis queue.
    //range: text area where the audio segment to be transmitted is located;
    //range.first (included): start position;
    //range.second (excluded): end position.
    override fun onAudioAvailable(
        taskId: String?,
        audioFragment: MLTtsAudioFragment?,
        offset: Int,
        range: android.util.Pair<Int, Int>?,
        bundle: Bundle?
    ) {
    //Audio stream callback API,
    // which is used to return the synthesized audio data to the app.
    }
}
9、恭喜您
祝贺您,您已经成功完成本codelab并学到了:
- 如何集成云数据库。 
- 如何使用ML Kit(图像分类、语种检测、文本翻译、语音合成)。 
10、参考文件
点击此处下载源码。
欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh
【HMS Core】一张图片带你玩转机器学习服务的更多相关文章
- 【HMS Core 6.0全球上线】华为钥匙环服务,打造跨应用跨形态无缝登录体验
		华为钥匙环服务(Keyring),是HMS Core在安全领域开放的全新服务,为全球开发者提供用户认证凭据(以下简称"凭据")本地存储和跨应用.跨形态共享能力,帮助您在安卓应用.快 ... 
- HMS Core助力宝宝巴士为全球开发者展现高品质儿童数字内容
		本文分享于HMS Core开发者论坛<宝宝巴士携HMS Core为全球家庭用户提供优质儿童数字内容>采访稿整理 宝宝巴士是国内有着十多年出海经验的开发者,其旗下有超过200多款儿童益智互动 ... 
- 华为HMS Core携手超图为三维GIS注入新动能
		6月30日,在2022(第五届)GIS软件技术大会GIS基础软件新技术板块论坛上,华为联合超图推出了基于HMS Core 3D Engine开发的高保真三维GIS插件,通过3D渲染技术助力三维GIS实 ... 
- 小红书携手HMS Core,畅玩高清视界,种草美好生活
		在相同流量消耗的情况下,540p可秒变1080p?这不是魔法,通过视频超分辨率技术(简称视频超分),就能让视频变得更清晰. 7月20日,在小红书最新版本7.48的App中,用户就能体验到这项技术带来的 ... 
- HMS Core Discovery第16期回顾|与虎墩一起,玩转AI新“声”态
		HMS Core 在AI领域最新的技术能力有哪些?本期Discovery直播以<与虎墩一起,玩转AI新"声"态>为主题,邀请了HMS Core 机器学习服务产品经理.机 ... 
- 码上来战!探索“智”感生活,HMS Core线上Codelabs挑战赛第4期开始!
		HMS Core线上Codelabs挑战赛第4期正式开始!我们向所有实践力超强.创新力满满的开发者发出邀请,用你的超级"码"力,解锁更多应用价值! 生活里,我们被手机"秒 ... 
- 对抗噪音,一键清晰,HMS Core音频编辑服务给你“录音棚”般的体验
		短视频时代来临,一部手机就可以玩转多种花样,所以越来越多的自由创作者加入这个行业,平时生活中用手机拍短视频.街头唱歌的非专业从业者随处可见.离开了录音棚,没有专业.统一的录音设备,无论在家里还是在路边 ... 
- Google发布机器学习平台Tensorflow游乐场~带你玩神经网络(转载)
		Google发布机器学习平台Tensorflow游乐场-带你玩神经网络 原文地址:http://f.dataguru.cn/article-9324-1.html> 摘要: 昨天,Google发 ... 
- [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)  【由浅至深】redis 实现发布订阅的几种方式  .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
		[翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ... 
- 【有奖互动】HMS Core. Sparkle游戏应用创新沙龙,诚邀您参与
		活动简介 随着互联网基础设施的完善和"宅经济"效应凸显,游戏行业逆势上扬,迎来巨大消费市场.同时,用户需求愈加多样化,如何进一步创新和技术升级.提升核心竞争力已成为游戏开发与运营的 ... 
随机推荐
- Swagger的介绍
			一.Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 二.Swagger 的优势? 支持 API 自动生成同步的在线 ... 
- MediatRPC - 基于MediatR和Quic通讯实现的RPC框架,比GRPC更简洁更低耦合,开源发布第一版
			大家好,我是失业在家,正在找工作的博主Jerry.作为一个.Net架构师,就要研究编程艺术,例如SOLID原则和各种设计模式.根据这些原则和实践,实现了一个更简洁更低耦合的RPC(Remote Pro ... 
- 使用CRD扩展Kubernetes API
			本文是如何创建 CRD 来扩展 Kubernetes API 的教程.CRD 是用来扩展 Kubernetes 最常用的方式,在 Service Mesh 和 Operator 中也被大量使用.因此读 ... 
- 【RPC和Protobuf】之Protobuf环境配置及组合工作
			Protobuf定义:是一种数据描述语言,作为接口规范的描述语言,可作为设计安全的跨语言RPC接口的基础工具 一.Protobuf入门 作用:最终保证RPC接口规范和安全 最基本的数据单元:messa ... 
- Xamarin.Android带参数返回上一级界面
			在ActivityA跳转到ActivityB后.activityB返回到ActivityA并带参数返回 首先再activitya中跳转到b var intent = new Intent(this, ... 
- elasticsearch的教程
			简介: 假期自学了elasticsearch搭建与使用,写个博客记录一下 另外我电脑是linux,我懒得再说windows各种配置方法了,不过都是大同小异 1.软件的简介 ElasticSearch是 ... 
- vite安装使用流程
			安装vite 使用npm npm create vite@latest 使用yarn yarn create vite 使用pnpm pnpm create vite 还有一些选择配置比如使用那种框架 ... 
- Python全栈工程师之从网页搭建入门到Flask全栈项目实战(4) - Flask模板语法与继承
			1.Flask模板介绍 前置:理解渲染机制即上篇笔记中render_template()功能是如何实现的! 1)找到html文件地址 2)读取html文件中的内容 3)替换html中的特殊字符 4)将 ... 
- python安装清华源
			pip install pip -Upip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple# "pi ... 
- 教你铁威马NAS中如何进行阵列升级
			磁盘阵列 (RAID) 是磁盘阵列的管理工具.当TNAS 中安装的硬盘多于1个时,组建适当的磁盘阵列能提高硬盘的存储效率,提高数据的安全性. 磁盘阵列升级,比如,将原来是RAID 0 或者RAID 1 ... 
