Zadanie detektora obiektów umożliwia wykrywanie obecności i lokalizacji wielu klas obiektów. Na przykład system do wykrywania obiektów może znajdować psy na obrazie. Z tych instrukcji dowiesz się, jak korzystać z zadania Detektor obiektów na Androidzie. Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub. Aby zobaczyć, jak to zadanie działa w praktyce, obejrzyj to demonstrację w internecie. 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 Object Detector na Androida. Przykład wykorzystuje kamerę na fizycznym urządzeniu z Androidem do ciągłego wykrywania obiektów, ale może też używać zdjęć i filmów z galerii urządzenia do wykrywania obiektów w sposób statyczny.
Możesz użyć tej aplikacji jako punktu wyjścia do utworzenia własnej aplikacji na Androida lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod usługi Object Detector 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:
- Sklonuj repozytorium Git za pomocą tego polecenia:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Opcjonalnie skonfiguruj instancję git do korzystania z rzadkiego sprawdzania, aby mieć tylko pliki przykładowej aplikacji Detector obiektów:
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/object_detection/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 Wykrywanie obiektów:
- ObjectDetectorHelper.kt – inicjalizuje detektor obiektów i obsługuje model oraz wybór delegata
- MainActivity.kt – implementuje aplikację i montuje komponenty interfejsu użytkownika.
- OverlayView.kt – obsługuje i wyświetla wyniki.
Konfiguracja
W tej sekcji opisaliśmy najważniejsze kroki konfigurowania środowiska programistycznego i projektów kodu na potrzeby korzystania z Obiektowego modułu rozpoznawania. 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
Detektor obiektó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 Wykrywanie obiektów MediaPipe wymaga wytrenowanego modelu zgodnego z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach usługi Detektor obiektów 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. Przykład kodu znajdziesz w następnej sekcji.
Tworzenie zadania
Do utworzenia zadania możesz użyć funkcji createFromOptions. Funkcja createFromOptions przyjmuje opcje konfiguracji, takie jak tryb działania, lokalizacja wyświetlania nazw, maksymalna liczba wyników, próg ufności oraz lista dozwolonych i zabronionych kategorii. Jeśli opcja konfiguracji nie jest określona, zostanie użyta wartość domyślna. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.
Zadanie wykrywania obiektów obsługuje 3 typy danych wejściowych: zdjęcia, pliki wideo i transmisje wideo na żywo. Podczas tworzenia zadania musisz określić tryb wykonywania odpowiadający typowi danych wejściowych. Wybierz kartę odpowiadającą typowi danych wejściowych, aby dowiedzieć się, jak utworzyć zadanie i przeprowadzić wnioskowanie.
Obraz
ObjectDetectorOptions options =
ObjectDetectorOptions.builder()
.setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
.setRunningMode(RunningMode.IMAGE)
.setMaxResults(5)
.build();
objectDetector = ObjectDetector.createFromOptions(context, options);
Wideo
ObjectDetectorOptions options =
ObjectDetectorOptions.builder()
.setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
.setRunningMode(RunningMode.VIDEO)
.setMaxResults(5)
.build();
objectDetector = ObjectDetector.createFromOptions(context, options);
Transmisja na żywo
ObjectDetectorOptions options = ObjectDetectorOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build()) .setRunningMode(RunningMode.LIVE_STREAM) .setMaxResults(5) .setResultListener((result, inputImage) -> { // Process the detection result here. }) .setErrorListener((result, inputImage) -> { // Process the classification errors here. }) .build(); objectDetector = ObjectDetector.createFromOptions(context, options);
Implementacja przykładowego kodu usługi Object Detector umożliwia użytkownikowi przełączanie się między trybami przetwarzania. Takie podejście skomplikuje kod tworzący zadanie i może nie być odpowiednie w Twoim przypadku. Ten kod znajdziesz w funkcji setupObjectDetector() klasy ObjectDetectorHelper.
Opcje konfiguracji
W tym zadaniu dostępne są te opcje konfiguracji aplikacji na Androida:
| Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
|---|---|---|---|
runningMode |
Ustawia tryb działania zadania. Dostępne są 3 tryby: OBRAZ: tryb dla pojedynczych obrazów wejściowych. FILM: tryb dekodowanych klatek filmu. LIVE_STREAM: tryb transmisji na żywo danych wejściowych, takich jak dane z kamery. W tym trybie należy wywołać metodę resultListener, aby skonfigurować odbiornik, który będzie asynchronicznie odbierał wyniki. |
{IMAGE, VIDEO, LIVE_STREAM} |
IMAGE |
displayNamesLocales |
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 |
maxResults |
Ustawia opcjonalną maksymalną liczbę wyników wykrywania o najwyższym wyniku, które mają zostać zwrócone. | dowolne liczby dodatnie. | -1 (zwracane są wszystkie wyniki). |
scoreThreshold |
Ustawia próg wyniku prognozy, który zastępuje próg podany w metadanych modelu (jeśli takie istnieją). Wyniki poniżej tej wartości są odrzucane. | Dowolna liczba zmiennych typu float | Nie ustawiono |
categoryAllowlist |
Ustawia opcjonalną listę dozwolonych nazw kategorii. Jeśli wyniki wykrywania nie są puste, a nazwa kategorii nie znajduje się w tym zbiorze, zostaną odfiltrowane. Powtarzające się lub nieznane nazwy kategorii są ignorowane.
Ta opcja jest wzajemnie wykluczająca się z opcją categoryDenylist. Użycie obu spowoduje błąd. |
dowolne ciągi znaków; | Nie ustawiono |
categoryDenylist |
Ustawia opcjonalną listę nazw kategorii, które są niedozwolone. Jeśli nie jest pusty, wyniki wykrywania, których nazwa kategorii znajduje się w tym zbiorze, zostaną odfiltrowane. Powtarzające się lub nieznane nazwy kategorii są ignorowane. Ta opcja jest wzajemnie wykluczająca się z opcją categoryAllowlist, a użycie obu spowoduje błąd. |
dowolne ciągi znaków; | Nie ustawiono |
resultListener |
Gdy detektor obiektów jest w trybie transmisji na żywo, ustawia odbiornik wyników tak, aby otrzymywał wyniki asynchronicznie. Z tej opcji można korzystać tylko wtedy, gdy ustawienie runningMode ma wartość LIVE_STREAM. | Nie dotyczy | Nie ustawiono |
Przygotuj dane
Przed przekazaniem do usługi Detector obiektów musisz przekonwertować wejściowy obraz lub kadr na obiekt com.google.mediapipe.framework.image.MPImage.
W przypadku każdego z dostępnych typów danych znajdziesz przykłady, które pokazują, jak przygotować dane do przetwarzania:
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 values. Use these values // 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() MPImage mpImage = new MediaImageBuilder(mediaImage).build();
W przykładowym kodzie detektora obiektów przygotowanie danych jest obsługiwane w klasie ObjectDetectorHelper w funkcjach detectImage(), detectVideoFile() i detectLivestreamFrame().
Uruchamianie zadania
W zależności od typu danych, z którymi pracujesz, użyj metody ObjectDetector.detect...() odpowiedniej dla tego typu danych. Używaj:
detect() do pojedynczych obrazów,
detectForVideo() do klatek w plikach wideo, detectAsync() do strumieni wideo. Podczas wykrywania treści w strumieniach wideo należy uruchamiać wykrywanie na osobnym wątku, aby nie blokować wątku interfejsu użytkownika.
Poniższe przykłady kodu pokazują proste przykłady uruchamiania modułu Object Detector w różnych trybach danych:
Obraz
ObjectDetectorResult detectionResult = objectDetector.detect(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. ObjectDetectorResult detectionResult = objectDetector.detectForVideo(image, frameTimestampMs);
Transmisja na żywo
// Run inference on the frame. The detection results will be available // via the `resultListener` provided in the `ObjectDetectorOptions` when // the object detector was created. objectDetector.detectAsync(image, frameTimestampMs);
Przykład kodu detektora obiektów pokazuje szczegółowe implementacje tych trybów: detect(), detectVideoFile() i detectAsync().
Przykładowy kod umożliwia użytkownikowi przełączanie się między trybami przetwarzania, co może nie być wymagane w Twoim przypadku.
Pamiętaj:
- W trybie wideo lub transmisji na żywo musisz też podać zadaniu detektora obiektów sygnaturę czasową ramki wejściowej.
- W trybie obrazu lub filmu zadanie wykrywania obiektów blokuje bieżący wątek, dopóki nie zakończy przetwarzania obrazu wejściowego lub klatki. Aby uniknąć blokowania bieżącego wątku, przeprowadź przetwarzanie w wątku tła.
- W trybie transmisji na żywo zadanie detektora obiektów nie blokuje bieżącego wątku, ale zwraca wynik natychmiast. Za każdym razem, gdy zakończy przetwarzanie ramki wejściowej, wywoła swojego słuchacza z wynikiem wykrywania. Jeśli funkcja wykrywania jest wywoływana, gdy zadanie detektora obiektów jest zajęte przetwarzaniem innego kadru, nowy kadr wejściowy zostanie zignorowany.
Obsługa i wyświetlanie wyników
Po przeprowadzeniu wnioskowania zadanie detektora obiektów zwraca obiekt ObjectDetectorResult, który opisuje obiekty znalezione na wejściowym obrazie.
Poniżej znajdziesz przykład danych wyjściowych z tego zadania:
ObjectDetectorResult:
Detection #0:
Box: (x: 355, y: 133, w: 190, h: 206)
Categories:
index : 17
score : 0.73828
class name : dog
Detection #1:
Box: (x: 103, y: 15, w: 138, h: 369)
Categories:
index : 17
score : 0.73047
class name : dog
Na ilustracji poniżej widać wynik wykonania zadania:
Przykładowy kod detektora obiektów pokazuje, jak wyświetlać wyniki wykrywania zwrócone przez zadanie. Więcej informacji znajdziesz w klasie OverlayView.