MediaPipe 圖片區隔工作可讓您根據預先定義的類別,將圖片分為不同的區域,以便套用背景模糊效果等視覺效果。以下操作說明將說明如何搭配使用圖片區隔與 Android 應用程式。如需這些操作說明中提及的程式碼範例,請前往 GitHub。如要進一步瞭解這項工作的功能、模型和設定選項,請參閱總覽。
程式碼範例
MediaPipe Tasks 程式碼範例包含兩個適用於 Android 圖片區隔應用程式的簡易實作方式:
這些範例使用實體 Android 裝置的相機,對即時攝影機畫面執行圖片區隔,或從裝置圖片庫中選擇圖片和影片。您可以將這些應用程式做為建構 Android 應用程式的起點,或在修改現有應用程式時參照這些應用程式。圖片區隔範例程式碼由 GitHub 代管。
以下各節將介紹具有類別遮罩的圖片區隔應用程式。
下載程式碼
以下操作說明說明如何使用 git 指令列工具建立範例程式碼的本機副本。
如要下載範例程式碼,請按照下列步驟操作:
- 使用下列指令複製 Git 存放區:
git clone https://github.com/google-ai-edge/mediapipe-samples
- 您可以選擇將 Git 執行個體設為使用稀疏檢查,因此只有 Image Segmenter 範例應用程式的檔案:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_segmentation/android
建立範例程式碼的本機版本後,您可以將專案匯入 Android Studio 並執行應用程式。如需操作說明,請參閱「Android 設定指南」。
重要元件
下列檔案包含此圖片區隔範例應用程式的重要程式碼:
- ImageSegmenterHelper.kt - 初始化圖片區隔工作並處理模型並委派選取。
- CameraFragment.kt - 提供相機的使用者介面和控製程式碼。
- GalleryFragment.kt - 提供使用者介面和控製程式碼,用於選取圖片和影片檔案。
- OverlayView.kt - 處理區隔結果並設定格式。
設定
本節說明設定開發環境及程式碼專案以使用 Image Segmenter 的重要步驟。如需瞭解如何設定開發環境以使用 MediaPipe 工作 (包括平台版本需求),請參閱「Android 設定指南」。
依附元件
圖片區隔工具使用 com.google.mediapipe:tasks-vision
程式庫。將這個依附元件新增至 Android 應用程式開發專案的 build.gradle
檔案。使用下列程式碼匯入必要的依附元件:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
型號
MediaPipe 圖片區隔工作需要與這項工作相容的已訓練模型。如要進一步瞭解影像區隔可用的訓練模型,請參閱工作總覽模型一節。
選取並下載模型,然後將其儲存在專案目錄中:
<dev-project-root>/src/main/assets
請使用 BaseOptions.Builder.setModelAssetPath()
方法指定模型使用的路徑。在下一節的程式碼範例中稱為此方法。
在圖片區隔器 範例程式碼中,模型是在 setupImageSegmenter()
函式的 ImageSegmenterHelper.kt
類別中定義。
建立工作
您可以使用 createFromOptions
函式建立工作。createFromOptions
函式可接受設定選項,包括遮罩輸出類型。如要進一步瞭解工作設定,請參閱設定選項一文。
圖片區隔工作支援下列輸入資料類型:靜態圖片、影片檔案和即時影片串流。建立工作時,您必須指定與輸入資料類型相對應的執行模式。選擇輸入資料類型的分頁,瞭解建立工作的方式。
圖片
ImageSegmenterOptions options = ImageSegmenterOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.IMAGE) .setOutputCategoryMask(true) .setOutputConfidenceMasks(false) .build(); imagesegmenter = ImageSegmenter.createFromOptions(context, options);
影片
ImageSegmenterOptions options = ImageSegmenterOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.VIDEO) .setOutputCategoryMask(true) .setOutputConfidenceMasks(false) .build(); imagesegmenter = ImageSegmenter.createFromOptions(context, options);
直播
ImageSegmenterOptions options = ImageSegmenterOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.LIVE_STREAM) .setOutputCategoryMask(true) .setOutputConfidenceMasks(false) .setResultListener((result, inputImage) -> { // Process the segmentation result here. }) .setErrorListener((result, inputImage) -> { // Process the segmentation errors here. }) .build() imagesegmenter = ImageSegmenter.createFromOptions(context, options)
Image Segmenter 程式碼範例實作可讓使用者切換處理模式。這種做法會讓工作建立程式碼變得更加複雜,並且可能不適合您的用途。您可以在 ImageSegmenterHelper
類別中,由 setupImageSegmenter()
函式看到此程式碼。
設定選項
這項工作的 Android 應用程式設定選項如下:
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
runningMode |
設定工作的執行模式。共有三種模式: IMAGE:單一圖片輸入的模式。 影片:影片已解碼影格的模式。 LIVE_STREAM:輸入資料串流 (例如攝影機) 的直播模式。在這個模式下,必須呼叫 resultListener 才能設定事件監聽器,以非同步方式接收結果。 |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
outputCategoryMask |
如果設為 True ,輸出結果會包含 uint8 圖片的區隔遮罩,其中每個像素值都代表勝出類別值。 |
{True, False } |
False |
outputConfidenceMasks |
如果設為 True ,輸出結果會包含以浮點值圖片形式的區隔遮罩,其中每個浮點值都代表該類別的可信度分數對應關係。 |
{True, False } |
True |
displayNamesLocale |
設定標籤語言,用於工作模型中繼資料內的顯示名稱 (如有)。英文的預設值是 en 。您可以使用 TensorFlow Lite Metadata Writer API,在自訂模型的中繼資料中加入本地化標籤。 | 語言代碼 | en |
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 user’s device as a Bitmap object using BitmapFactory. // Convert an Android’s Bitmap object to a MediaPipe’s 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 video’s metadata, load the METADATA_KEY_DURATION and // METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them // to calculate the timestamp of each frame later. // Loop through the video and load each frame as a Bitmap object. // Convert the Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(frame).build();
直播
import com.google.mediapipe.framework.image.MediaImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Create a CameraX’s ImageAnalysis to continuously receive frames // from the device’s camera. Configure it to output frames in RGBA_8888 // format to match with what is required by the model. // For each Android’s ImageProxy object received from the ImageAnalysis, // extract the encapsulated Android’s Image object and convert it to // a MediaPipe’s Image object. android.media.Image mediaImage = imageProxy.getImage() Image mpImage = new MediaImageBuilder(mediaImage).build();
在圖片區隔器範例程式碼中,資料準備是由 segmentLiveStreamFrame()
函式在 ImageSegmenterHelper
類別中處理。
執行工作
您可以根據目前使用的執行模式呼叫其他 segment
函式。Image Segmenter 函式會傳回輸入圖片或影格中已識別的區段區域。
圖片
ImageSegmenterResult segmenterResult = imagesegmenter.segment(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. ImageSegmenterResult segmenterResult = imagesegmenter.segmentForVideo(image, frameTimestampMs);
直播
// Run inference on the frame. The segmentations results will be available via // the `resultListener` provided in the `ImageSegmenterOptions` when the image // segmenter was created. imagesegmenter.segmentAsync(image, frameTimestampMs);
注意事項:
- 以影片模式或直播模式執行時,您也必須為圖片區隔工作提供輸入影格的時間戳記。
- 在圖片或影片模式中執行時,「圖片區隔」工作會封鎖目前的執行緒,直到完成輸入圖片或影格的處理為止。如要避免封鎖使用者介面,請在背景執行緒中執行處理作業。
- 以直播模式執行時,圖片區隔工作不會封鎖目前的執行緒,但會立即傳回。每當它處理完輸入影格時,就會透過偵測結果叫用結果監聽器。如果在圖片區隔工作忙於處理其他影格時呼叫
segmentAsync
函式,工作會忽略新的輸入影格。
在圖片區隔器範例程式碼中,ImageSegmenterHelper.kt
檔案中定義了 segment
函式。
處理並顯示結果
執行推論時,圖片區隔工作會傳回 ImageSegmenterResult
物件,其中包含區隔工作的結果。輸出內容的內容取決於您在設定工作時設定的 outputType
。
以下各節說明這項工作的輸出資料範例:
類別可信度
下圖顯示類別可信度遮罩的工作輸出內容。可信度遮罩輸出包含介於 [0, 1]
之間的浮點值。
原始圖片和類別可信度遮罩輸出內容。Pascal VOC 2012 資料集的來源映像檔。
類別值
下圖以視覺化方式呈現類別值遮罩的工作輸出內容。類別遮罩範圍為 [0, 255]
,每個像素值代表模型輸出的勝出類別索引。勝出類別索引是模型可識別類別中的最高分數。
原始圖片和類別遮罩輸出內容。Pascal VOC 2012 資料集的來源映像檔。