使用机器学习套件检测图片中的对象:Android

1. 准备工作

ML Kit 是一款移动 SDK,可将 Google 的设备端机器学习专业知识融入到 Android 和 iOS 应用中。您可以使用功能强大但易于使用的 Vision 和 Natural Language API 来解决应用中的常见难题,或打造全新的用户体验。所有这些功能均由 Google 一流的机器学习模型提供支持,并且可免费使用。

机器学习套件的 API 全部在设备端运行,因此可支持需要处理实时相机数据流的实时用例。这也意味着该功能可在离线状态下使用。

此 Codelab 会引导您逐步完成一些简单步骤,以向现有 Android 应用添加针对给定图片的物体检测和跟踪 (ODT) 功能。请注意,此 Codelab 采取了一些捷径来重点介绍机器学习套件 ODT 的用法。

构建内容

在此 Codelab 中,您将使用机器学习套件构建一个 Android 应用。您的应用将使用机器学习套件 Object Detection and Tracking API 来检测给定图片中的对象。最后,您应该会看到与右侧图片类似的内容。

学习内容

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

所需条件

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

此 Codelab 重点介绍机器学习套件。对于不相关的概念,我们仅会略作介绍,但是会提供相应代码块供您复制和粘贴。

2. 进行设置

下载代码

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

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

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

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

借助机器学习套件依赖项,您可以在应用中集成机器学习套件 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),用于执行以下操作:

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

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

重复几次,看看效果如何:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

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

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

1dd41b3ec978f1d9.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) {
}

目前该函数为空。请按照以下步骤实现 ML Kit 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())
   }

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

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

您可能已经注意到,该代码使用 debugPrint() 对检测到的结果执行了 printf 类处理。

将其添加到 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: Food
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 中包含一些样板代码,可帮助您直观呈现检测结果。利用这些实用程序可以简化可视化图表代码:

  • data class BoxWithText(val box: Rect, val text: String):这是一个用于存储对象检测结果以进行可视化的数据类。box 是对象所在的边界框,text 是与对象的边界框一起显示的检测结果字符串。
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap:此方法会在输入 bitmap 上绘制 detectionResults 中的对象检测结果,并返回修改后的副本。

以下是 drawDetectionResult 实用程序方法的输出示例:

58c6f1d4ddb00dfa.png

直观呈现机器学习套件检测结果

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

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

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • 首先,您需要解析机器学习套件的 DetectedObject 并创建一个 BoxWithText 对象列表来显示可视化结果。
  • 然后,使用 drawDetectionResult 实用程序方法在输入图片上绘制检测结果,并在屏幕上显示该结果。

开始运行

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

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

a03109cb30d5014d.png

7. 恭喜!

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

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

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

随着学习的深入,您可能希望增强模型:如您所见,默认模型只能识别 5 个类别,甚至不知道刀、叉和瓶子。请查看设备端机器学习 - 对象检测学习路线中的其他 Codelab,了解如何训练自定义模型。

所学内容

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

后续步骤

  • 借助机器学习套件 ODT 探索更多内容,使用更多图片和实时视频来体验检测和分类准确率以及性能
  • 不妨查看设备端机器学习 - 对象检测学习路线,了解如何训练自定义模型
  • 在您自己的 Android 应用中应用 ML Kit ODT

了解详情