Zadanie MediaPipe Image Classifier umożliwia klasyfikację obrazów. Możesz użyć tego zadania, aby określić, co obraz reprezentuje w zbiorze kategorii zdefiniowanych w czasie trenowania. Te instrukcje pokazują, jak używać klasyfikatora obrazów w aplikacjach na Androida. Dostępny jest przykładowy kod opisany w tych instrukcjach włączono GitHub
Aby zobaczyć, jak to zadanie działa, możesz obejrzeć wersję demonstracyjną w przeglądarce. Więcej informacji o funkcjach, modelach i opcjach konfiguracji zapoznaj się z Przeglądem.
Przykładowy kod
Przykładowy kod MediaPipe Tasks to prosta implementacja klasyfikatora obrazów na Androida. W tym przykładzie użyliśmy aparatu w fizycznym urządzeniu z Androidem, stale klasyfikować obiekty, a także korzystać z obrazów i filmów pochodzących galerii urządzeń do statycznego klasyfikowania obiektów.
Możesz użyć tej aplikacji jako punktu wyjścia dla własnej aplikacji na Androida lub odnieść się do niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod klasyfikatora obrazów jest hostowany GitHub
Pobieranie kodu
Poniżej znajdziesz instrukcje tworzenia lokalnej kopii przykładu. za pomocą narzędzia wiersza poleceń git.
Aby pobrać przykładowy kod:
- Sklonuj repozytorium git za pomocą tego polecenia:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Opcjonalnie możesz skonfigurować instancję git tak, aby wykorzystywała rozproszony proces płatności,
masz więc tylko pliki z przykładowej aplikacji Image Classifier:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_classification/android
Po utworzeniu lokalnej wersji przykładowego kodu możesz zaimportować projekt w Android Studio i uruchom aplikację. Instrukcje znajdziesz w Przewodnik po konfiguracji na Androida
Kluczowe elementy
Te pliki zawierają kluczowy kod dla tego obrazu przykład zastosowania klasyfikacji:
- ImageClassifierHelper.kt – Inicjuje klasyfikator obrazów, obsługuje model i przekazuje dostęp do niego wyboru.
- MainActivity.kt –
Implementuje aplikację, w tym wywołuje funkcję
ImageClassificationHelper
orazClassificationResultsAdapter
- ClassificationResultsAdapter.kt - Obsługuje wyniki i formatuje je.
Konfiguracja
W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach kodu, w których używa się klasyfikatora obrazów. Ogólne informacje na temat: skonfigurować środowisko programistyczne do korzystania z zadań MediaPipe, w tym wymagań wersji platformy, patrz Przewodnik po konfiguracji na Androida
Zależności
Klasyfikator obrazów używa biblioteki com.google.mediapipe:tasks-vision
. Dodaj to
zależności od pliku build.gradle
Projekt tworzenia aplikacji na Androida. Zaimportuj wymagane zależności za pomocą:
ten kod:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Model
Zadanie MediaPipe Image Classifier wymaga wytrenowanego modelu zgodnego z tym zadanie. Więcej informacji o dostępnych wytrenowanych modelach na potrzeby klasyfikatora obrazów znajdziesz tutaj zapoznaj się z omówieniem zadania sekcją Modele.
Wybierz i pobierz model, a następnie zapisz go w katalogu projektu:
<dev-project-root>/src/main/assets
Użyj metody BaseOptions.Builder.setModelAssetPath()
, aby podać ścieżkę
używane przez model. Tę metodę przywołaliśmy w przykładzie kodu w następnym
.
W
przykładowy kod klasyfikatora obrazów,
model jest zdefiniowany w ImageClassifierHelper.kt
.
Tworzenie zadania
Do utworzenia zadania możesz użyć funkcji createFromOptions
.
Funkcja createFromOptions
akceptuje opcje konfiguracji, w tym uruchomione
tryb, język wyświetlanych nazw, maksymalna liczba wyników, próg ufności,
oraz listy dozwolonych lub odrzuconych kategorii. Więcej informacji o konfiguracji
Więcej informacji znajdziesz w artykule Omówienie konfiguracji.
Zadanie Klasyfikator obrazów obsługuje 3 typy danych wejściowych: obrazy, pliki wideo i transmisje wideo na żywo. Musisz określić tryb działania odpowiadający parametrowi typ danych wejściowych podczas tworzenia zadania. Wybierz kartę odpowiadającą typ danych wejściowych, aby zobaczyć, jak utworzyć zadanie i uruchomić wnioskowanie.
Obraz
ImageClassifierOptions options = ImageClassifierOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.IMAGE) .setMaxResults(5) .build(); imageClassifier = ImageClassifier.createFromOptions(context, options);
Wideo
ImageClassifierOptions options = ImageClassifierOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.VIDEO) .setMaxResults(5) .build(); imageClassifier = ImageClassifier.createFromOptions(context, options);
Transmisja na żywo
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)
Przykładowa implementacja kodu klasyfikatora obrazów pozwala użytkownikowi przełączać się między
i przetwarzania danych. Takie podejście sprawia, że kod tworzenia zadań jest bardziej skomplikowany,
może nie być odpowiednia w Twoim przypadku użycia. Możesz zobaczyć ten kod w
Funkcja setupImageClassifier()
ImageClassifierHelper.kt
.
.
Opcje konfiguracji
To zadanie zawiera te opcje konfiguracji aplikacji na Androida:
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
runningMode |
Ustawia tryb działania zadania. Są trzy
tryby: IMAGE: tryb wprowadzania pojedynczego obrazu. WIDEO: tryb zdekodowanych klatek filmu. LIVE_STREAM: tryb transmisji danych wejściowych na przykład z kamery. W tym trybie detektor wyników musi mieć wartość wywołano, aby skonfigurować detektor i otrzymywać wyniki asynchronicznie. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
displayNamesLocale |
Ustawia język etykiet, które mają być używane w przypadku nazw wyświetlanych w kolumnie
metadane modelu zadania, jeśli są dostępne. Wartość domyślna to en dla
Angielski. Do metadanych modelu niestandardowego możesz dodać zlokalizowane etykiety
za pomocą interfejsu TensorFlow Lite Metadata Writer API. |
Kod języka | en |
maxResults |
Ustawia opcjonalną maksymalną liczbę wyników klasyfikacji na . Jeśli < 0 – zostaną zwrócone wszystkie dostępne wyniki. | Dowolne liczby dodatnie | -1 |
scoreThreshold |
Ustawia próg wyniku prognozy, który zastępuje próg podany w polu metadane modelu (jeśli występują). Wyniki poniżej tej wartości zostały odrzucone. | Dowolna liczba zmiennoprzecinkowa | Nie ustawiono |
categoryAllowlist |
Ustawia opcjonalną listę dozwolonych nazw kategorii. Jeśli pole nie jest puste,
wyniki klasyfikacji, których nazwa kategorii nie znajduje się w tym zbiorze, zostaną
zostały odfiltrowane. Zduplikowane lub nieznane nazwy kategorii są ignorowane.
Ta opcja nie działa z usługą categoryDenylist i korzysta z funkcji
skutkuje to błędem. |
Dowolne ciągi | Nie ustawiono |
categoryDenylist |
Ustawia opcjonalną listę nazw kategorii, które nie są dozwolone. Jeśli
niepuste, wyniki klasyfikacji, których nazwa kategorii znajduje się w tym zbiorze, zostaną odfiltrowane
na zewnątrz. Zduplikowane lub nieznane nazwy kategorii są ignorowane. Ta opcja jest wzajemna
tylko w polu categoryAllowlist , co spowoduje błąd. |
Dowolne ciągi | Nie ustawiono |
resultListener |
Konfiguruje detektor wyników, aby otrzymywać wyniki klasyfikacji
asynchronicznie, gdy w transmisji na żywo działa Klasyfikator obrazów.
i trybu uzyskiwania zgody. Tej opcji można używać tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM |
Nie dotyczy | Nie ustawiono |
errorListener |
Ustawia opcjonalny detektor błędów. | Nie dotyczy | Nie ustawiono |
Przygotuj dane
Klasyfikator obrazów działa z obrazami, plikami wideo i transmisjami wideo na żywo. Zadanie obsługuje wstępne przetwarzanie danych wejściowych, w tym zmianę rozmiaru, obrót i wartość ich normalizację.
Musisz przekonwertować obraz lub klatkę wejściową do
com.google.mediapipe.framework.image.MPImage
obiekt przed przekazaniem do
Klasyfikator obrazów.
Obraz
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();
Wideo
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();
Transmisja na żywo
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();
W
Przykładowy kod klasyfikatora obrazów. Przygotowanie danych odbywa się tutaj:
ImageClassifierHelper.kt
.
Uruchamianie zadania
Aby aktywować wnioskowanie, możesz wywołać funkcję classify
odpowiadającą Twojemu trybowi działającemu. Interfejs Image Classifier API zwraca możliwe kategorie obiektu w obrazie lub ramce wejściowej.
Obraz
ImageClassifierResult classifierResult = imageClassifier.classify(image);
Wideo
// 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);
Transmisja na żywo
// 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);
Pamiętaj:
- Gdy pracujesz w trybie wideo lub w trybie transmisji na żywo, musisz też podaj sygnaturę czasową ramki wejściowej do zadania Klasyfikator obrazów.
- W trybie obrazu lub wideo zadanie Klasyfikator obrazów blokuje bieżący wątek do czasu zakończenia przetwarzania obrazu wejściowego lub ramki. Aby uniknąć blokowania interfejsu użytkownika, wykonaj przetwarzanie w w wątku w tle.
- W trybie transmisji na żywo zadanie klasyfikacji obrazów nie jest blokowane.
w bieżącym wątku, ale wraca natychmiast. Wywoła swój wynik
detektor z wynikiem wykrywania za każdym razem, gdy zakończy przetwarzanie
ramki wejściowej. Jeśli funkcja
classifyAsync
jest wywoływana przy użyciu klasyfikatora obrazów zadanie jest zajęte przetwarzaniem innej ramki, zadanie zignoruje nową ramkę wejściową.
W
Przykładowy kod klasyfikatora obrazów, funkcje classify
są zdefiniowane w
ImageClassifierHelper.kt
.
.
Obsługa i wyświetlanie wyników
Po uruchomieniu wnioskowania zadanie Klasyfikator obrazów zwraca obiekt ImageClassifierResult
zawierający listę możliwych kategorii obiektów w obrazie lub ramce wejściowej.
Poniżej znajdziesz przykładowe dane wyjściowe tego zadania:
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
Ten wynik uzyskano po uruchomieniu Bird Classifier. dnia:
W
Przykładowy kod klasyfikatora obrazów, klasa ClassificationResultsAdapter
w tagu
ClassificationResultsAdapter.kt
.
obsługuje wyniki:
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]
}
}
}