Interaktywny przewodnik po segmentacji obrazu na Androidzie

Zadanie MediaPipe Interactive Image Segmenter przyjmuje lokalizację na obrazie, szacuje granice obiektu w tej lokalizacji i zwraca segmentację obiektu jako dane obrazu. Te instrukcje pokazują, jak używać interaktywnego narzędzia do dzielenia obrazu w przypadku aplikacji na Androida. Przykład kodu opisany w tych instrukcjach jest dostępny na GitHub. Więcej informacji o możliwościach, modelach i opcjach konfiguracji związanych z tym zadaniem znajdziesz w sekcji Omówienie.

Przykładowy kod

Przykładowy kod MediaPipe Tasks to prosta implementacja aplikacji do segmentacji obrazów na Androida. Przykład działa z obrazami wybranymi z galerii urządzenia.

Możesz użyć tej aplikacji jako punktu wyjścia do stworzenia własnej aplikacji na Androida lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod segmentatora interaktywnych obrazów jest hostowany na GitHub.

Pobieranie kodu

Z tych instrukcji dowiesz się, jak utworzyć lokalną kopię przykładowego kodu za pomocą narzędzia wiersza poleceń git.

Aby pobrać przykładowy kod:

  1. Sklonuj repozytorium Git za pomocą tego polecenia:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcjonalnie skonfiguruj instancję git, aby używać skanowania rzadkiego, aby mieć tylko pliki przykładowej aplikacji Interactive Image Segmenter:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/interactive_segmentation/android
    

Po utworzeniu lokalnej wersji przykładowego kodu możesz zaimportować projekt do Android Studio i uruchomić aplikację. Instrukcje znajdziesz w przewodniku konfiguracji Androida.

Kluczowe komponenty

Te pliki zawierają kluczowy kod przykładowej aplikacji do segmentacji obrazu:

Konfiguracja

W tej sekcji opisaliśmy najważniejsze kroki konfiguracji środowiska programistycznego i projektów kodu, które należy wykonać, aby korzystać z narzędzia Interactive Image Segmenter. Ogólne informacje o konfigurowaniu środowiska programistycznego do korzystania z zadań MediaPipe, w tym wymagania dotyczące wersji platformy, znajdziesz w przewodniku konfiguracji na Androida.

Zależności

Narzędzie do segmentacji interaktywnych obrazów korzysta z biblioteki com.google.mediapipe:tasks-vision. Dodaj tę zależność do pliku build.gradle w projekcie tworzenia aplikacji na Androida. Zaimportuj wymagane zależności za pomocą tego kodu:

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

Model

Zadanie MediaPipe Interactive Image Segmenter wymaga wytrenowanego modelu zgodnego z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach narzędzia Interactive Image Segmenter znajdziesz w sekcji Modele w omówieniu zadania.

Wybierz i pobierz model, a potem zapisz go w katalogu projektu:

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

Użyj metody BaseOptions.Builder.setModelAssetPath(), aby określić ścieżkę używaną przez model. Ta metoda jest przedstawiona w przykładowym kodzie w następnej sekcji.

W przykładowym kodzie segmentera interaktywnych obrazów model jest zdefiniowany w klasie InteractiveSegmenterHelper.kt w funkcji setupInteractiveSegmenter().

Tworzenie zadania

Do utworzenia zadania możesz użyć funkcji createFromOptions. Funkcja createFromOptions akceptuje opcje konfiguracji, w tym typy danych wyjściowych maski. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.

InteractiveSegmenterOptions options =
  InteractiveSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .setResultListener((result, inputImage) -> {
         // Process the segmentation result here.
    })
    .setErrorListener(exception -> {
         // Process the segmentation errors here.
    })    
    .build();
interactivesegmenter = InteractiveSegmenter.createFromOptions(context, options);

Bardziej szczegółowy przykład konfigurowania tego zadania znajdziesz w funkcji setupInteractiveSegmenter() klasy InteractiveSegmenterHelper.

Opcje konfiguracji

W tym zadaniu dostępne są te opcje konfiguracji aplikacji na Androida:

Nazwa opcji Opis Zakres wartości Wartość domyślna
outputCategoryMask Jeśli ustawisz tę opcję na True, dane wyjściowe będą zawierać maskę segmentacji w postaci obrazu uint8, gdzie każda wartość piksela wskazuje, czy dany piksel należy do obiektu znajdującego się w obszarze zainteresowania. {True, False} False
outputConfidenceMasks Jeśli ustawisz tę opcję na True, dane wyjściowe będą zawierać maskę segmentacji w postaci obrazu z wartością zmiennoprzecinkową, gdzie każda wartość zmiennoprzecinkowa reprezentuje poziom pewności, że piksel należy do obiektu znajdującego się w obszarze zainteresowania. {True, False} True
displayNamesLocale Określa język etykiet, których należy używać do wyświetlanych nazw podanych w metadanych modelu zadania (jeśli są dostępne). Wartość domyślna to en w przypadku języka angielskiego. Możesz dodawać zlokalizowane etykiety do metadanych modelu niestandardowego, korzystając z interfejsu TensorFlow Lite Metadata Writer API. Kod języka en
errorListener Ustawia opcjonalny odbiornik błędów. Nie dotyczy Nie ustawiono

Przygotuj dane

Interaktywny segmentator obrazów działa na obrazach, a zadanie obsługuje wstępne przetwarzanie danych, w tym zmianę rozmiaru, obrót i normalizację wartości. Zanim przekażesz obraz do zadania, musisz przekonwertować go na obiekt 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.
MPImage mpImage = new BitmapImageBuilder(bitmap).build();

W przykładowym kodzie segmentatora interaktywnych obrazów przygotowanie danych jest obsługiwane w klasie InteractiveSegmenterHelper za pomocą funkcji segment().

Uruchamianie zadania

Wywołaj funkcję segment, aby przeprowadzić prognozę i wygenerować segmenty. Zadanie Segmentacja interaktywnego obrazu zwraca zidentyfikowane obszary segmentów na obrazie wejściowym.

RegionOfInterest roi = RegionOfInterest.create(
    NormalizedKeypoint.create(
        normX * it.width,
        normY * it.height
    )
);

ImageSegmenterResult segmenterResult = interactivesegmenter.segment(image, roi);

W przykładowym kodzie segmentatora interaktywnych obrazów funkcje segment są zdefiniowane w pliku InteractiveSegmenterHelper.kt.

Obsługa i wyświetlanie wyników

Po uruchomieniu wnioskowania zadanie Interactive Image Segmenter zwraca obiekt ImageSegmenterResult, który zawiera wyniki zadania podziału na segmenty. Treść danych wyjściowych może zawierać maskę kategorii lub maskę wiarygodności albo obie te maski, w zależności od tego, co zostało ustawione podczas konfigurowania zadania.

W następnych sekcjach znajdziesz więcej informacji o danych wyjściowych z tego zadania:

Maska kategorii

Na poniższych obrazach pokazano wizualizację wyniku zadania w przypadku maski kategorii i wartości z wskazanym punktem zainteresowania. Każdy piksel to wartość uint8, która wskazuje, czy piksel jest częścią obiektu znajdującego się w obszarze zainteresowania. Czarny i biały okrąg na drugim obrazie wskazuje wybrany obszar zainteresowania.

Pies stojący na stosie liści Zarysowany kształt psa z poprzedniego obrazu

Wyjście oryginalnej maski obrazu i kategorii. Obraz źródłowy z danych Pascal VOC 2012.

Maska ufności

Dane wyjściowe maski ufności zawierają wartości zmiennoprzecinkowe z zakresu [0, 1] dla każdego kanału wejściowego obrazu. Wyższe wartości wskazują na większą pewność, że piksel obrazu jest częścią obiektu znajdującego się w obszarze zainteresowania.