在 Android 上使用以 AutoML 訓練的模型偵測圖片中的物件

使用 AutoML Vision Edge 訓練專屬模型後,您就可以在應用程式中使用該模型,偵測圖片中的物件。

您可以透過兩種方式整合從 AutoML Vision Edge 訓練的模型:將模型打包至應用程式的素材資源資料夾,或是從 Firebase 動態下載模型。

模型捆綁選項
在應用程式中封裝
  • 模型是應用程式 APK 的一部分
  • 可立即使用型號,即使 Android 裝置離線也沒問題
  • 不需要 Firebase 專案
透過 Firebase 代管
  • 將模型上傳至 Firebase Machine Learning 進行代管
  • 縮減 APK 大小
  • 系統會視需要下載模型
  • 無須重新發布應用程式,即可推送模型更新
  • 使用 Firebase 遠端設定輕鬆進行 A/B 版本測試
  • 需要 Firebase 專案

事前準備

  1. 如果您要下載模型,請務必將 Firebase 新增至 Android 專案 (如果您尚未這麼做)。當您將模型打包時,則不需要這麼做。

  2. 將 TensorFlow Lite 工作程式庫的依附元件新增至模組的應用程式層級 Gradle 檔案,通常為 app/build.gradle

    如要將模型與應用程式組合:

    dependencies {
      // ...
      // Object detection with a bundled Auto ML model
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT'
    }
    

    如要從 Firebase 動態下載模型,請一併新增 Firebase ML 依附元件:

    dependencies {
      // ...
      // Object detection with an Auto ML model deployed to Firebase
      implementation platform('com.google.firebase:firebase-bom:26.1.1')
      implementation 'com.google.firebase:firebase-ml-model-interpreter'
    
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly'
    }
    

1. 載入模型

設定本機模型來源

如何將模型與應用程式組合:

  1. Google Cloud 主控台下載的 ZIP 封存檔中,擷取模型。
  2. 在應用程式套件中加入模型:
    1. 如果專案中沒有 Assets 資料夾,請在 app/ 資料夾上按一下滑鼠右鍵,然後依序點選「New」>「Folder」>「Assets Folder」建立資料夾。
    2. 將含有嵌入中繼資料的 tflite 模型檔案複製到素材資源資料夾。
  3. 請在應用程式的 build.gradle 檔案中新增以下內容,確保 Gradle 在建構應用程式時不會壓縮模型檔案:

    android {
        // ...
        aaptOptions {
            noCompress "tflite"
        }
    }
    

    模型檔案將納入應用程式套件中,並以原始素材資源的形式提供。

設定 Firebase 託管的模型來源

如要使用遠端代管的模型,請建立 RemoteModel 物件,並指定您在發布模型時指派的名稱:

Java

// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin

// Specify the name you assigned when you deployed the model.
val remoteModel =
    FirebaseCustomRemoteModel.Builder("your_model_name").build()

接著,啟動模型下載工作,並指定要允��下載的條件。如果裝置上沒有該模型,或者有較新版本的模型,這項工作就會以非同步方式從 Firebase 下載模型:

Java

DownloadConditions downloadConditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(@NonNull Task<Void> task) {
                // Success.
            }
        });

Kotlin

val downloadConditions = DownloadConditions.Builder()
    .requireWifi()
    .build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
    .addOnSuccessListener {
        // Success.
    }

許多應用程式會在初始化程式碼中啟動下載工作,但您可以在需要使用模型之前的任何時間啟動下載工作。

使用模型建立物件偵測器

設定模型來源後,請從其中一個來源建立 ObjectDetector 物件。

如果您只有本機內建的模型,請直接從模型檔案建立物件偵測器,並設定所需的信心分數門檻 (請參閱「評估模型」):

Java

// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);

Kotlin

// Initialization
val options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)

如果您使用的是遠端代管模型,請務必先確認模型已下載,再執行模型。您可以使用模型管理員的 isModelDownloaded() 方法,查看模型下載作業的狀態。

雖然您只需要在執行物件偵測器前確認這項資訊,但如果您同時擁有遠端代管模型和本機內建模型,在例項化物件偵測器時執行這項檢查可能會比較合理:如果已下載遠端模型,請從該模型建立物件偵測器;如果未下載,請從本機模型建立物件偵測器。

Java

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
            }
        });

Kotlin

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener { success ->

        }

如果您只有遠端代管的模型,請在確認模型已下載前,停用模型相關功能 (例如將部分 UI 設為灰色或隱藏)。方法是將事件監聽器附加至模型管理員的 download() 方法。

確認模型已下載後,請使用模型檔案建立物件偵測器:

Java

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    ObjectDetectorOptions options = ObjectDetectorOptions.builder()
                            .setScoreThreshold(0)
                            .build();
                    objectDetector = ObjectDetector.createFromFileAndOptions(
                            getApplicationContext(), modelFile.getPath(), options);
                }
            }
        });

Kotlin

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnSuccessListener { modelFile ->
            val options = ObjectDetectorOptions.builder()
                    .setScoreThreshold(0f)
                    .build()
            objectDetector = ObjectDetector.createFromFileAndOptions(
                    applicationContext, modelFile.path, options)
        }

2. 準備輸入圖片

然後,為要加上標籤的每張圖片建立 TensorImage 物件。您可以使用 fromBitmap 方法,從 Bitmap 建立 TensorImage 物件:

Java

TensorImage image = TensorImage.fromBitmap(bitmap);

Kotlin

val image = TensorImage.fromBitmap(bitmap)

如果圖片資料不在 Bitmap 中,您可以載入像素陣列,如 TensorFlow Lite 文件所示。

3. 執行物件偵測工具

如要偵測圖片中的物件,請將 TensorImage 物件傳遞至 ObjectDetectordetect() 方法。

Java

List<Detection> results = objectDetector.detect(image);

Kotlin

val results = objectDetector.detect(image)

4. 取得標記物件的相關資訊

如果物件偵測作業成功,系統會傳回 Detection 物件清單。每個 Detection 物件都代表在圖片中偵測到的項目。您可以取得每個物件的邊界框和標籤。

例如:

Java

for (Detection result : results) {
    RectF bounds = result.getBoundingBox();
    List<Category> labels = result.getCategories();
}

Kotlin

for (result in results) {
    val bounds = result.getBoundingBox()
    val labels = result.getCategories()
}

改善即時成效的訣竅

如要在即時應用程式中標示圖片,請遵循下列指南,以獲得最佳的幀率:

  • 限制對圖像標註工具的呼叫。如果圖片標籤工具執行期間有新的影片影格可供使用,請捨棄影格。如需範例,請參閱快速入門範例應用程式中的 VisionProcessorBase 類別。
  • 如果您使用圖片標註器的輸出內容,在輸入圖片上疊加圖形,請先取得結果,然後在單一步驟中算繪圖片和疊加圖形。這樣一來,您只需為每個輸入影格轉譯一次顯示介面。如需範例,請參閱快速入門導覽課程範例應用程式中的 CameraSourcePreview GraphicOverlay 類別。
  • 如果您使用 Camera2 API,請以 ImageFormat.YUV_420_888 格式擷取圖片。

    如果您使用舊版 Camera API,請拍攝 ImageFormat.NV21 格式的圖片。