使用 ML Kit:Android 偵測圖片中的物件,以便建立視覺化產品搜尋服務

1. 事前準備

727608486a28395d.png

你看過 Google 智慧鏡頭示範影片後,可以將手機相機對準物體,然後尋找可在線上購買的產品嗎?如要瞭解如何在應用程式中新增相同功能,本程式碼研究室就適合您。這是一種學習課程的一部分,可協助您瞭解如何在行動應用程式中建構產品圖片搜尋功能。

在本程式碼研究室中,您將瞭解建構產品圖片搜尋功能的第一步:如何偵測圖片中的物件,以及如何讓使用者選擇要搜尋的物件。您將使用 ML Kit 物件偵測與追蹤功能建構這項功能。

您可以參閱學習課程,瞭解其餘步驟,包括如何使用 Vision API Product Search 建立產品搜尋後端。

建構項目

  • 在這個程式碼研究室中,您將使用 ML Kit 建構 Android 應用程式。您的應用程式將使用 ML Kit Object Detection and Tracking API 偵測指定圖片中的物件。接著,使用者需要在產品資料庫中挑選要搜尋的物件。
  • 最後,您應該會看到與右圖相似的圖片。

課程內容

  • 如何將 ML Kit SDK 整合至 Android 應用程式
  • ML Kit 物件偵測與追蹤 API

軟硬體需求

  • 最新版本的 Android Studio (4.1.2 以上版本)
  • Android Studio 模擬器或實體 Android 裝置
  • 程式碼範例
  • 對使用 Kotlin 進行 Android 開發作業的基本知識

本程式碼研究室著重於 ML Kit,其他概念和程式碼區塊未經討論,但會事先提供給您,您只要複製及貼上即可。

2. 做好準備

下載程式碼

點選下方連結即可下載這個程式碼研究室的所有程式碼:

將下載的 ZIP 檔案解壓縮。這麼做會將根資料夾 (odml-pathways-main) 解壓縮到所有所需資源。在這個程式碼研究室中,您只需要 product-search/codelab1/android 子目錄中的來源。

mlkit-android 存放區的物件偵測子目錄包含兩個目錄:

  • android_studio_folder.pngstarter:啟動您在本程式碼研究室所建構的程式碼。
  • android_studio_folder.png最終:已完成的範例應用程式的程式碼。

3. 將 ML Kit Object Detection and Tracking API 加進專案

將應用程式匯入 Android Studio

首先,請將 starter 應用程式匯入 Android Studio。

前往 Android Studio,選取「Import Project」(Gradle、Eclipse ADT 等),然後從先前下載的原始碼中選擇「starter」資料夾。

7c0f27882a2698ac.png

新增 ML Kit 物件偵測和追蹤的依附元件

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,並新增 ML Kit 物件偵測和追蹤依附元件,可以開始使用應用程式了。

透過 USB 將 Android 裝置連線至主機,或「啟動 Android Studio 模擬器」,然後按一下 Android Studio 工具列中的「Run」圖示 ( 執行.png)。

執行並探索應用程式

應用程式應該會在您的 Android 裝置上啟動。其中包含一些樣板程式碼,可用來拍照或選取預設圖片,並提供給您將在這個程式碼研究室中建構的物件偵測和追蹤管道。編寫程式碼前,請先探索應用程式:

首先,畫面底部有一個按鈕 ( c6d965d639c3646.png),藉此

  • 啟動裝置/模擬器中整合的相機應用程式
  • 透過相機應用程式拍照
  • 範例應用程式接收拍攝的圖片
  • 顯示圖片

請嘗試使用「拍照」功能按鈕。按照提示拍照,接受相片,然後觀察相片是否顯示在範例應用程式中。

第二種預設圖片可供選擇。如果是在 Android 模擬器上執行,可以之後再使用這些映像檔來測試物件偵測程式碼。

  1. 選取 3 張預設圖片中的圖片。
  2. 確認圖片顯示在較大的檢視畫面中。

1290481786af21b9.png

5. 新增裝置端物件偵測功能

在這個步驟中,您要在範例應用程式中新增這項功能,以偵測圖片中的物件。如上一步驟所示,範例應用程式包含樣板程式碼,可透過裝置上的相機應用程式拍照。如果您正在 Android 模擬器中執行程式碼研究室,應用程式中還有 3 張預設圖片,可以試試物件偵測功能。

當您選取圖片時,無論是從預設圖片或使用相機應用程式拍照,樣板程式碼都會將該圖片解碼為 Bitmap 例項,在螢幕上顯示,並使用圖片呼叫 runObjectDetection 方法。

在這個步驟中,您需要在 runObjectDetection 方法中加入程式碼,進行物件偵測!

設定並執行圖片的裝置端物件偵測功能

設定 ML Kit ODT 時,只需 3 個簡單步驟,就能搭配 3 個 API

  • 準備圖片: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

ML Kit 提供簡單的 API,讓您從 Bitmap 建立 InputImage。接著,您就能將 InputImage 動態饋給至 ML Kit API。

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

新增上述程式碼至 runObjectDetection(bitmap:Bitmap) 的頂端。

步驟 2:建立偵測工具執行個體

ML Kit 遵循建構工具設計模式,因此您需要將設定傳送至建構工具,然後從建構工具中取得「偵測工具」。有 3 種設定選項 (程式碼研究室會使用以粗體顯示的選項):

  • 偵測工具模式 (單一圖片 或串流)
  • 偵測模式 (單一或 多個 物件偵測)
  • 分類模式 (開啟 或關閉)

本程式碼研究室適用於單一圖片 - 多項物件偵測,分為以下幾件事:

// 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:這是用來追蹤跨影格的整數 (「未」用於本程式碼研究室)
  • 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」 ( 執行.png) 來執行程式碼研究室。請嘗試選取預設圖片或拍照,然後在 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 個物件:

  • 類別包括「時尚美妝」和「居家美學」
  • 系統沒有為第 2 個傳回的類別,因為該類別為不明類別。
  • 不含trackingId (因為這是單一圖片偵測模式)
  • 放置在 boundingBox 矩形內部 (例如 (481, 2021) – (2426、3376))
  • 偵測工具確定第 1 個是時尚商品 (90%) (這是一件洋裝)

就技術層面而言,您現在已取得所有功能,即可讓 ML Kit 物件偵測正常運作。恭喜

沒錯,在 UI 端,您一開始仍然處於舞台,但不妨利用 UI 偵測到的結果,例如繪製定界框,以便提供更優質的體驗。下一步是視覺化呈現偵測到的結果!

6. 對偵測結果進行後續處理

在先前的步驟中,您已將偵測到的結果列印到 logcat 中:簡單又快速。

在本節中,您將在圖片中使用 結果:

  • 在圖片上繪製定界框
  • 在定界框內繪製類別名稱和信心

瞭解視覺化公用程式

程式碼研究室中包含一些樣板程式碼,可協助您以視覺化方式呈現偵測結果。運用以下公用程式,簡化視覺化程式碼:

  • class ImageClickableView 這是圖片檢視類別,提供一些便利的公用程式,可視覺化呈現偵測結果以及與偵測結果互動。
  • fun drawDetectionResults(results: List<DetectedObject>) 這個方法會在偵測到每個物件的中心點繪製白色圓圈。
  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) 這個回呼可接收經過裁剪的圖片,其中只包含使用者輕觸的物件。在後續的程式碼研究室中,您會將這張裁剪的圖片傳送至圖片搜尋後端,藉此取得外觀相似的結果。在本程式碼研究室中,您還無法使用這個方法。

顯示 ML Kit 的偵測結果

使用視覺化公用程式,在輸入圖片上方顯示 ML Kit 物件偵測結果。

前往呼叫 debugPrint() 的位置,並在下方加入下列程式碼片段:

runOnUiThread {
    viewBinding.ivPreview.drawDetectionResults(it)
}

開始執行

現在,按一下 Android Studio 工具列中的「Run」 ( 執行.png)。

應用程式載入後,請按下附有相機圖示的按鈕、將相機鏡頭對準物件、拍攝相片、接受相片 (在「相機」應用程式中),或者輕鬆輕觸任何預設圖片。畫面上應該會顯示偵測結果;請再次按下按鈕或選取其他圖片多次,即可體驗最新的 ML Kit ODT!

5027148750dc0748.png

7. 恭喜!

您已使用 ML Kit 在應用程式中新增物件偵測功能:

  • 使用 3 個 API 的 3 個步驟
  • 建立輸入圖片
  • 建立偵測工具
  • 將圖片傳送到偵測工具

只要完成這些動作,就能開始運作!

涵蓋內容

  • 如何在 Android 應用程式中加入 ML Kit 物件偵測和追蹤功能
  • 如何在 ML Kit 中使用裝置端物件偵測和追蹤功能,偵測圖片中的物件

後續步驟

  • 使用這個程式碼研究室,瞭解如何將偵測到的物件傳送至產品搜尋後端,並顯示搜尋結果
  • 透過 ML Kit ODT 取得更多圖片和即時影像,協助偵測體驗及分類準確率與成效
  • 請參考「進一步運用物件偵測」學習課程,瞭解如何訓練自訂模型
  • 查看對物件偵測即時相機static-image 的 Material Design 建議
  • 在自己的 Android 應用程式中套用 ML Kit ODT

瞭解詳情