Android 圖片分類指南

MediaPipe 圖片分類器工作可讓您對圖片進行分類。您可以利用這項工作,在訓練時定義的一組類別中,找出圖片所代表的意義。以下操作說明會說明如何使用圖片分類器 使用 Android 應用程式在此說明中所述的程式碼範例 為 GitHub

您可以前往 Web 示範 查看這項工作的實際操作體驗。 進一步瞭解功能、模型和設定選項 請參閱總覽

程式碼範例

MediaPipe Tasks 範例程式碼是圖片分類器的簡易實作, App Engine 應用程式這個範例會使用實體 Android 裝置上的相機執行以下動作: 持續分類物件,也能使用 可將物件靜態分類

您可以將應用程式做為起點,當做 Android 應用程式的起點,也可以參照應用程式 做出決定Image Classifier 範例程式碼 GitHub

下載程式碼

以下說明如何建立範例的本機副本 git 指令列工具編寫程式碼。

如要下載範例程式碼,請按照下列步驟操作:

  1. 使用下列指令複製 git 存放區:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. 您也可以選擇設定 Git 執行個體,以使用稀疏結帳功能。 因此,您只擁有 Image Classifier 範例應用程式的檔案:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_classification/android
    

建立範例程式碼的本機版本後,您可以匯入專案 然後執行應用程式如需操作說明,請參閱 Android 設定指南

重要元件

下列檔案包含這張圖片的重要程式碼 分類範例應用程式

設定

本節說明設定開發環境的重要步驟,以及 程式碼專案使用 Image Classifier。如需 設定開發環境以使用 MediaPipe 工作,包括: 平台版本需求,請參閱 Android 設定指南

依附元件

圖片分類器使用 com.google.mediapipe:tasks-vision 程式庫。新增此項目 build.gradle 檔案的依附元件 Android 應用程式開發專案。使用下列指令匯入必要的依附元件 下列程式碼:

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

型號

MediaPipe Image Classifier 需要與這個模型相容的已訓練模型 工作。如要進一步瞭解圖片分類器可用的已訓練模型,請參閱: 工作總覽的「模型」一節

選取並下載模型,然後將模型儲存在專案目錄中:

<dev-project-root>/src/main/assets

使用 BaseOptions.Builder.setModelAssetPath() 方法指定路徑 以便訓練模型此方法將在接下來 專區。

在 Image Classifier 範例程式碼 模型定義於 ImageClassifierHelper.kt 檔案。

建立工作

您可以使用 createFromOptions 函式建立工作。 createFromOptions 函式接受設定選項,包括執行中 模式, 顯示名稱語言代碼, 結果數量上限, 可信度門檻 以及類別允許清單或拒絕清單進一步瞭解設定 選項,請參閱設定總覽

圖片分類器工作支援 3 種輸入資料類型:靜態圖片、影片檔案、 和即時影像串流您必須指定相應的執行模式 輸入資料類型請選擇與 輸入資料類型,瞭解如何建立工作及執行推論。

圖片

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

影片

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

直播

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
         // Process the classification result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the classification errors here.
    })
    .build()
imageClassifier = ImageClassifier.createFromOptions(context, options)
    

Image Classifier 程式碼範例程式碼實作方式可讓使用者在 處理模式這種方法使得工作建立程式碼變得更加複雜, 可能會不適合您的用途您可以在 setupImageClassifier() 函式 ImageClassifierHelper.kt 檔案。

設定選項

這項工作有下列 Android 應用程式設定選項:

選項名稱 說明 值範圍 預設值
runningMode 設定任務的執行模式。在架構中 模式:

圖片:單一圖片輸入模式。

VIDEO:影片已解碼的影格模式。

LIVE_STREAM:輸入串流模式 擷取的資訊等。在此模式下, resultListener 設定接聽程式來接收結果 以非同步方式載入物件
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
displayNamesLocale 設定標籤語言,供 工作模型的中繼資料 (如有)。以下項目的預設值為 en: 英語。您可以在自訂模型的中繼資料中加入經本地化的標籤 使用 TensorFlow Lite Metadata Writer API 語言代碼 en
maxResults 將最高分數分類結果的選用數量上限設為 傳回。如果0,系統會傳回所有可用的結果。 任何正數 -1
scoreThreshold 設定預測分數門檻,此門檻會覆寫 模型中繼資料 (如有)低於這個值的結果遭到拒絕。 任何浮點值 未設定
categoryAllowlist 設定允許使用的類別名稱清單 (選用)。如果非空白 如果類別名稱不在這個組合中,就會由此 過濾掉。系統會忽略重複或不明的類別名稱。 這個選項與 categoryDenylist 互斥, 這兩個都會造成錯誤。 任何字串 未設定
categoryDenylist 設定不允許使用的類別名稱清單 (選填)。如果 非空白的分類結果如果屬於這個集合的類別名稱,系統就會加以篩選 。系統會忽略重複或不明的類別名稱。這個選項會互相影響 只使用 categoryAllowlist 且同時使用兩者都會發生錯誤。 任何字串 未設定
resultListener 設定用來接收分類結果的結果監聽器 當圖片分類程式在直播中時以非同步方式顯示 模式。只有在執行模式設為「LIVE_STREAM」時才能使用 不適用 未設定
errorListener 設定選用的錯誤事件監聽器。 不適用 未設定

準備資料

「圖片分類器」適用於圖片、影片檔案和直播影片。工作內容 處理資料輸入預先處理作業,包括調整大小、旋轉和值 以便處理正規化的情況

您需要將輸入圖片或影格轉換為 com.google.mediapipe.framework.image.MPImage 物件,然後再將該物件傳送至 。

圖片

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the users device as a Bitmap object using BitmapFactory.

// Convert an Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

影片

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the videos metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. Youll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

直播

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraXs ImageAnalysis to continuously receive frames 
// from the devices camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Androids ImageProxy object received from the ImageAnalysis, 
// extract the encapsulated Androids Image object and convert it to 
// a MediaPipes Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

在 Image Classifier 範例程式碼,則會在 ImageClassifierHelper.kt敬上 檔案。

執行工作

您可以呼叫與執行模式相對應的 classify 函式來觸發推論。Image Classifier API 會在輸入圖片或頁框中傳回物件的可能類別。

圖片

ImageClassifierResult classifierResult = imageClassifier.classify(image);
    

影片

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageClassifierResult classifierResult =
    imageClassifier.classifyForVideo(image, frameTimestampMs);
    

直播

// Run inference on the frame. The classifications results will be available 
// via the `resultListener` provided in the `ImageClassifierOptions` when 
// the image classifier was created.
imageClassifier.classifyAsync(image, frameTimestampMs);
    

注意事項:

  • 以錄影模式或直播模式執行時,你也必須 向圖片分類器工作提供輸入影格的時間戳記。
  • 以圖片或影片模式執行時,圖片分類器工作 會阻斷目前的執行緒,直到執行緒處理完成輸入圖片, 相框。為避免封鎖使用者介面,請在 背景執行緒。
  • 在直播模式下執行時,圖片分類器工作不會封鎖 但會立即傳回這會叫用結果 並傳送偵測結果 輸入影格如果在圖片分類器時呼叫 classifyAsync 函式 工作正忙於處理另一個影格,工作會忽略新的輸入影格。

在 圖片分類器範例程式碼,定義了 classify 函式,如 ImageClassifierHelper.kt 檔案。

處理及顯示結果

執行推論時,圖片分類器工作會傳回 ImageClassifierResult 物件,其中包含輸入圖片或頁框中物件的可能類別清單。

以下範例顯示這項工作的輸出資料範例:

ImageClassifierResult:
 Classifications #0 (single classification head):
  head index: 0
  category #0:
   category name: "/m/01bwb9"
   display name: "Passer domesticus"
   score: 0.91406
   index: 671
  category #1:
   category name: "/m/01bwbt"
   display name: "Passer montanus"
   score: 0.00391
   index: 670

此結果是執行 Bird Classifier 取得 已開啟:

在 Image Classifier 範例程式碼,即 ClassificationResultsAdapter 類別中的 ClassificationResultsAdapter.kt 檔案會處理結果:

fun updateResults(imageClassifierResult: ImageClassifierResult? = null) {
    categories = MutableList(adapterSize) { null }
    if (imageClassifierResult != null) {
        val sortedCategories = imageClassifierResult.classificationResult()
            .classifications()[0].categories().sortedBy { it.index() }
        val min = kotlin.math.min(sortedCategories.size, categories.size)
        for (i in 0 until min) {
            categories[i] = sortedCategories[i]
        }
    }
}