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

1. 准备工作

727608486a28395d

您看过 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

首先,将 starter 应用导入 Android Studio。

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

7c0f27882a2698ac

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

借助机器学习套件依赖项,您可以将机器学习套件 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 中构建的对象检测和跟踪流水线。在编写代码之前,先熟悉一下应用:

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

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

试用“拍照”按钮。按照提示拍照,接受照片,并观察起始应用中显示的照片。

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

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

1290481786af21b9

5. 添加设备端对象检测

在此步骤中,您将向起始应用添加用于检测图片中的对象的功能。正如您在上一步中看到的,起始应用包含样板代码,可使用设备上的相机应用拍摄照片。应用内还有 3 张预设图片,如果您是在 Android 模拟器上运行此 Codelab,则可以尝试使用对象检测功能。

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

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

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

使用 3 个 API 只需 3 个简单步骤,即可设置机器学习套件 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))
  • 检测器非常确信第一个是时尚 (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)。

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

5027148750dc0748

7. 恭喜!

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

  • 使用 3 个 API 完成 3 个步骤
  • 创建输入图片
  • 创建检测器
  • 将图片发送到检测器

您只需完成这些操作即可启动并运行!

所学内容

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

后续步骤

  • 试用此 codelab,了解如何将检测到的对象发送到商品搜索后端并显示搜索结果
  • 使用机器学习套件 ODT 对更多图片和实时视频进行更深入的探索,以体验检测和分类准确率和性能
  • 查看深入了解对象检测学习在线课程,了解如何训练自定义模型
  • 了解 Material Design 关于对象检测实时相机静态图片的建议
  • 在您自己的 Android 应用中运用机器学习套件 ODT

了解详情