使用机器学习套件检测图片中的对象以构建视觉化商品搜索:Android

1. 准备工作

727608486a28395d.png

您看过 Google 智能镜头演示视频吗?您在那里可以将手机摄像头对准某个物体,并找到在线购买物品的位置。如果您想要了解如何向应用添加同一功能,此 Codelab 很适合您。它是学习路线的一部分,将向您介绍如何在移动应用中构建产品图片搜索功能。

在此 Codelab 中,您将学习构建产品图片搜索结果功能的第一步:如何检测图片中的对象,并让用户选择要搜索的对象。您将使用 机器学习套件对象检测和跟踪 来构建此功能。

您可以在学习路线中了解其余步骤,包括如何使用 Vision API Product Search 构建商品搜索后端。

构建内容

  • 在此 Codelab 中,您将使用机器学习套件构建一个 Android 应用。您的应用将使用机器学习套件对象检测和跟踪 API 来检测给定图片中的对象。然后,用户将选择要在我们的产品数据库中搜索的对象。
  • 最后,您应该会看到与右侧图片类似的内容。

学习内容

  • 如何将机器学习套件 SDK 集成到 Android 应用中
  • 机器学习套件对象检测和跟踪 API

所需条件

  • 最新版 Android Studio (v4.1.2+)
  • Android Studio 模拟器或一台实体 Android 设备
  • 示例代码
  • 使用 Kotlin 进行 Android 开发的基础知识

此 Codelab 重点介绍机器学习套件。我们不讨论其他概念和代码块,只提供给您复制和粘贴。

2. 进行设置

下载代码

点击下面的链接可下载本 Codelab 的所有代码:

解压下载的 ZIP 文件。此操作会解压缩一个根文件夹 (odml-pathways-main),其中包含您需要的所有资源。对于此 Codelab,您只需要 product-search/codelab1/android 子目录中的源代码。

mlkit-android 代码库中的对象检测子目录包含两个目录:

  • android_studio_folder.pngstarter - 在此 Codelab 中帮助您开始构建的起始代码。
  • android_studio_folder.pngfinal - 完成后的示例应用的完整代码。

3. 将机器学习套件的对象检测和跟踪 API 添加到项目中

将应用导入 Android Studio

首先,将起始应用导入 Android Studio。

前往 Android Studio,选择“Import Project (Gradle, Eclipse ADT, etc.)”,然后从之前下载的源代码中选择 starter 文件夹。

7c0f27882a2698ac.png

添加机器学习套件对象检测和跟踪的依赖项

借助 ML Kit 依赖项,您可以在应用中集成 ML Kit ODT SDK。

前往项目的 app/build.gradle 文件,并确认依赖项已存在:

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

将您的项目与 Gradle 文件同步

为确保您的应用拥有所有依赖项,此时您应该将项目与 Gradle 文件同步。

在 Android Studio 工具栏中选择 Sync Project with Gradle Files 图标 ( b451ab2d04d835f9.png)。

(如果此按钮已停用,请确保仅导入 starter/app/build.gradle,而非整个代码库。)

4. 运行起始应用

现在,您已将项目导入 Android Studio 并添加了机器学习套件对象检测和跟踪的依赖项,可以首次运行应用了。

通过 USB 将 Android 设备连接到主机,或启动 Android Studio 模拟器,然后点击 Android Studio 工具栏中的 Run ( execute.png)。

运行并探索应用

应用应在 Android 设备上启动。它包含一些样板代码,可让您拍摄照片或选择预设图片,并将其馈送到您将在本 Codelab 中构建的对象检测和跟踪流水线。在编写代码之前,先稍微探索一下应用:

首先,底部有一个按钮 ( c6d965d639c3646.png),用于

  • 启动设备/模拟器中集成的相机应用
  • 相机应用中拍照
  • 起始应用接收拍摄的图片
  • 显示图片

试用“拍照”按钮。按照提示拍摄照片,接受照片,然后观察照片是否显示在起始应用中。

其次,有 3 张预设图片可供选择。如果您在 Android 模拟器上运行,稍后可以使用这些图片来测试对象检测代码。

  1. 从 3 张预设图片中选择一张图片。
  2. 查看图片是否显示在较大视图中。

1290481786af21b9.png

5. 添加设备端对象检测功能

在此步骤中,您将向起始应用添加检测图片中对象的功能。如上一步中所述,起始应用包含样板代码,用于使用设备上的相机应用拍摄照片。如果您在 Android 模拟器上学习本 Codelab,还可以试用应用中的 3 张预设图片进行对象检测。

当您选择图片(无论是从预设图片中选择还是通过相机应用拍照)时,样板代码会将该图片解码为 Bitmap 实例,将其显示在屏幕上,并使用该图片调用 runObjectDetection 方法。

在此步骤中,您将向 runObjectDetection 方法添加代码以执行对象检测!

设置并对图片进行设备端对象检测

只需 3 个简单步骤,即可完成 3 个 API 的设置,从而使用 ML Kit ODT

  • 准备图片:InputImage
  • 创建检测器对象:ObjectDetection.getClient(options)
  • 连接上面的 2 个对象:process(image)

您可以在 MainActivity.kt 文件中通过 **runObjectDetection(bitmap: Bitmap)**函数实现这些操作。

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

目前该函数为空。接下来,请按照以下步骤集成机器学习套件 ODT!在此过程中,Android Studio 会提示您添加必要的导入

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

第 1 步:创建 InputImage

机器学习套件 提供了一个简单的 API,用于从 Bitmap 创建 InputImage。然后,您可以将 InputImage 馈送到机器学习套件 API 中。

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

将上述代码添加runObjectDetection(bitmap:Bitmap) 的顶部。

第 2 步:创建检测器实例

机器学习套件遵循构建器设计模式;在此模式下,您将配置传递给构建器,然后从中获取检测器。有 3 个配置选项(Codelab 中使用的是粗体选项):

  • 检测器模式(单张图片数据流
  • 检测模式(单个或 多个 对象检测
  • 分类模式(开启 或关闭

此 Codelab 适用于单张图片 - 多对象检测和分类,我们来完成以下操作:

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

第 3 步:将图片传递给检测器

对象检测和分类是异步处理:

  • 您将图片发送给检测器(通过 process()
  • 检测器会尽力检测
  • 检测器通过回调向您报告结果

以下代码正是这样做的(复制并附加fun runObjectDetection(bitmap:Bitmap)): 内的现有代码中):

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

完成后,检测器会通过以下方式通知您

  1. 检测到的对象总数
  2. 每个检测到的对象都通过以下内容描述:
  • trackingId:用于跨帧跟踪的整数(在此 Codelab 中未使用)
  • boundingBox:对象的边界框
  • 检测到的对象的标签列表(仅在启用分类时)labels:
  • index(获取相应标签的索引)
  • text(获取此标签的文本,包括“时尚商品”“食品”“家居用品”“地点”“植物”)
  • confidence(介于 0.0 和 1.0 之间的浮点数,1.0 表示 100%)

您可能已经注意到,该代码使用 debugPrint() 将检测到的结果输出到 Logcat。将其添加到 MainActivity 类中:

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

现在,您已准备好接受图片以进行检测!

点击 Android Studio 工具栏中的 Run 图标 ( execute.png) 来运行 Codelab。尝试选择预设图片或拍摄照片,然后查看 IDE 内的 logcat 窗口( 16bd6ea224cf8cf1.png)。您应该会看到如下所示的内容:

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Fashion good
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

这意味着检测器检测到了 3 个对象:

  • 类别为时尚商品家居商品
  • 由于第二个是未知类别,因此未返回任何类别。
  • trackingId(因为这是单图片检测模式)
  • boundingBox 矩形内的位置(例如:(481, 2021) - (2426, 3376))
  • 检测器相当确信第 1 个是时尚商品 (90%)(是连衣裙

从技术上来说,这就是 机器学习套件 对象检测正常运行所需执行的一切工作:目前您已完成所有操作!恭喜

是的,在界面方面,您仍处于开始阶段,但您可以在界面上利用检测到的结果,例如绘制出边界框,以打造更出色的体验。下一步是直观呈现检测到的结果!

6. 检测结果的后处理

在前面的步骤中,您将检测结果输出到 logcat 中:简单快速。

在本部分中,您将使用图片中的结果:

  • 在图片上绘制边界框
  • 在边界框内绘制类别名称和置信度

了解可视化实用程序

Codelab 中包含一些样板代码,可帮助您直观呈现检测结果。利用这些实用程序可以简化可视化图表代码:

  • class ImageClickableView:这是一个图片视图类,提供了一些便捷的实用程序,用于可视化和与检测结果互动。
  • fun drawDetectionResults(results: List<DetectedObject>) 此方法会在检测到的每个对象的中心绘制白色圆圈。
  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) 这是一个回调,用于接收仅包含用户已点按的对象的剪裁后的图片。您将在后续的 Codelab 中将此剪裁后的图片发送到图片搜索后端,以获取外观类似的结果。在此 Codelab 中,您暂时不会使用此方法。

显示 机器学习套件 检测结果

使用可视化实用程序在输入图片上显示机器学习套件对象检测结果。

前往您调用 debugPrint() 的位置,并在其下方添加以下代码段:

runOnUiThread {
    viewBinding.ivPreview.drawDetectionResults(it)
}

开始运行

现在,点击 Android Studio 工具栏中的 Run 图标 ( execute.png)。

应用加载后,按带有相机图标的按钮,将相机对准某个对象,拍摄照片,接受照片(在相机应用中),或者您也可以轻松点按任意预设图片。您应该会看到检测结果;再次按下按钮或选择另一张图片,重复几次,体验最新的机器学习套件 ODT!

5027148750dc0748.png

7. 恭喜!

您已使用机器学习套件为应用添加对象检测功能:

  • 3 个步骤,3 个 API
  • 创建输入图片
  • 创建检测器
  • 将图片发送到检测器

它现在可以立即运行并使用了!

所学内容

  • 如何将机器学习套件的对象检测和跟踪功能添加到 Android 应用中
  • 如何使用机器学习套件的设备端对象检测和跟踪功能来检测图片中的对象

后续步骤

  • 您可以尝试此 Codelab,了解如何将检测到的对象发送到 Product Search 后端并显示搜索结果
  • 借助机器学习套件 ODT 探索更多内容,使用更多图片和实时视频来体验检测和分类准确率以及性能
  • 不妨查看深入了解对象检测学习路线,了解如何训练自定义模型
  • 阅读有关对象检测的 Material Design 建议:实时相机静态图片
  • 在您自己的 Android 应用中应用 ML Kit ODT

了解详情