Wykrywanie obiektów na obrazach za pomocą ML Kit: Android

1. Zanim zaczniesz

ML Kit to mobilny pakiet SDK, który udostępnia w aplikacjach na Androida i iOS funkcje uczenia maszynowego na urządzeniu opracowane przez Google. Możesz używać zaawansowanych, ale prostych w obsłudze interfejsów Vision API i Natural Language API, aby rozwiązywać typowe problemy w aplikacjach lub tworzyć zupełnie nowe wrażenia użytkownika. Wszystkie są oparte na najlepszych w branży modelach uczenia maszynowego Google i dostępne bezpłatnie.

Interfejsy API ML Kit działają na urządzeniu, co umożliwia korzystanie z nich w czasie rzeczywistym, np. podczas przetwarzania strumienia z kamery na żywo. Oznacza to też, że funkcja jest dostępna w trybie offline.

W tym samouczku znajdziesz proste instrukcje dodawania do istniejącej aplikacji na Androida funkcji wykrywania i śledzenia obiektów (ODT) na podstawie danego obrazu. Pamiętaj, że w tym samouczku zastosowano pewne uproszczenia, aby podkreślić sposób użycia funkcji ODT w ML Kit.

Co utworzysz

W tym ćwiczeniu z programowania utworzysz aplikację na Androida z ML Kit. Aplikacja będzie używać interfejsu ML Kit Object Detection and Tracking API do wykrywania obiektów na danym obrazie.Na koniec zobaczysz coś podobnego do obrazu po prawej stronie.

Czego się nauczysz

  • Integrowanie pakietu SDK ML Kit z aplikacją na Androida
  • Interfejs ML Kit do wykrywania i śledzenia obiektów

Czego potrzebujesz

  • Najnowsza wersja Androida Studio (4.1.2 lub nowsza)
  • Emulator Androida Studio lub fizyczne urządzenie z Androidem
  • Przykładowy kod
  • Podstawowa wiedza na temat tworzenia aplikacji na Androida w języku Kotlin

Ten moduł Codelab dotyczy ML Kit. Nieistotne koncepcje i bloki kodu zostały pominięte. Można je po prostu skopiować i wkleić.

2. Konfiguracja

Pobieranie kodu

Kliknij ten link, aby pobrać cały kod do tych ćwiczeń:

Rozpakuj pobrany plik ZIP. Spowoduje to rozpakowanie folderu głównego (mlkit-android-main) ze wszystkimi potrzebnymi zasobami. W tym ćwiczeniu potrzebne będą tylko źródła w podkatalogu object-detection.

Podkatalog object-detection w repozytorium mlkit-android zawiera 2 katalogi:

  • android_studio_folder.pngstarter – kod początkowy, na którym będziesz pracować w ramach tych ćwiczeń z programowania.
  • android_studio_folder.pngfinal – ukończony kod gotowej aplikacji przykładowej.

3. Dodawanie do projektu interfejsu ML Kit Object Detection and Tracking API

Importowanie aplikacji do Android Studio

Zacznijmy od zaimportowania aplikacji startowej do Androida Studio.

Otwórz Android Studio, wybierz Importuj projekt (Gradle, Eclipse ADT itp.) i wybierz folder starter z pobranego wcześniej kodu źródłowego.

7c0f27882a2698ac.png

Dodaj zależności dla wykrywania i śledzenia obiektów w ML Kit

Zależności ML Kit umożliwiają zintegrowanie pakietu ML Kit ODT SDK z aplikacją. Na końcu pliku app/build.gradle projektu dodaj te wiersze:

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

Synchronizowanie projektu z plikami Gradle

Aby mieć pewność, że wszystkie zależności są dostępne dla aplikacji, na tym etapie zsynchronizuj projekt z plikami Gradle.

Na pasku narzędzi Android Studio wybierz Synchronizuj projekt z plikami Gradle ( b451ab2d04d835f9.png).

(Jeśli ten przycisk jest wyłączony, upewnij się, że importujesz tylko starter/app/build.gradle , a nie całe repozytorium).

4. Uruchamianie aplikacji startowej

Po zaimportowaniu projektu do Androida Studio i dodaniu zależności do wykrywania i śledzenia obiektów w ML Kit możesz po raz pierwszy uruchomić aplikację.

Podłącz urządzenie z Androidem do hosta za pomocą kabla USB lub uruchom emulator Android Studio i kliknij Uruchom ( execute.png) na pasku narzędzi Android Studio.

Uruchamianie aplikacji i zapoznawanie się z nią

Aplikacja powinna się uruchomić na urządzeniu z Androidem. Zawiera on powtarzalny kod, który umożliwia zrobienie zdjęcia lub wybranie gotowego obrazu i przesłanie go do potoku wykrywania i śledzenia obiektów, który utworzysz w tym Codelabs. Zanim zaczniemy pisać kod, przyjrzyjmy się aplikacji.

Na dole znajduje się przycisk ( c6d965d639c3646.png), który umożliwia:

  • otwórz aplikację aparatu zintegrowaną z urządzeniem lub emulatorem;
  • zrób zdjęcie w aplikacji aparatu;
  • otrzymać zarejestrowany obraz w aplikacji startowej;
  • wyświetlić obraz,

Wypróbuj przycisk Zrób zdjęcie, postępuj zgodnie z instrukcjami, aby zrobić zdjęcie, zaakceptuj je i sprawdź, czy wyświetla się w aplikacji startowej.

Powtórz te czynności kilka razy, aby zobaczyć, jak to działa:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

Po drugie, możesz wybrać jeden z 3 gotowych obrazów. Jeśli korzystasz z emulatora Androida, możesz później użyć tych obrazów do testowania kodu wykrywania obiektów.

Wybierz obraz z 3 wstępnie ustawionych obrazów. Sprawdź, czy obraz wyświetla się w większym widoku:

1dd41b3ec978f1d9.png

5. Dodawanie wykrywania obiektów na urządzeniu

W tym kroku dodasz do aplikacji startowej funkcję wykrywania obiektów na obrazach. Jak widać w poprzednim kroku, aplikacja startowa zawiera powtarzalny kod do robienia zdjęć za pomocą aplikacji aparatu na urządzeniu. W aplikacji są też 3 gotowe obrazy, na których możesz wypróbować wykrywanie obiektów, jeśli korzystasz z ćwiczeń z programowania na emulatorze Androida.

Po wybraniu obrazu (z obrazów wstępnie ustawionych lub po zrobieniu zdjęcia w aplikacji aparatu) powtarzalny kod dekoduje go do instancji Bitmap, wyświetla go na ekranie i wywołuje metodę runObjectDetection z obrazem.

W tym kroku dodasz kod do metody runObjectDetection, aby wykrywać obiekty.

Konfigurowanie i uruchamianie wykrywania obiektów na obrazie na urządzeniu

Aby skonfigurować ML Kit ODT, wystarczą 3 proste kroki z użyciem 3 interfejsów API:

  • przygotować obraz: InputImage
  • utworzyć obiekt detektora: ObjectDetection.getClient(options)
  • połącz 2 obiekty powyżej: process(image)

Możesz to zrobić w funkcji runObjectDetection(bitmap: Bitmap) w pliku MainActivity.kt.

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

Obecnie funkcja jest pusta. Aby wdrożyć ML Kit ODT, wykonaj te czynności. W trakcie tego procesu Android Studio poprosi Cię o dodanie niezbędnych importów:

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

Krok 1. Utwórz InputImage

ML Kit udostępnia prosty interfejs API do tworzenia InputImageBitmap. Następnie możesz przekazać InputImage do interfejsów ML Kit API.

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

Dodaj powyższy kod na początku pliku runObjectDetection(bitmap:Bitmap).

Krok 2. Utwórz instancję detektora

ML Kit korzysta ze wzoru projektowego Builder. Przekażesz konfigurację do narzędzia do tworzenia, a następnie uzyskasz z niego detektor. Możesz skonfigurować 3 opcje (w tym samouczku używamy opcji wytłuszczonych):

  • tryb detektora (pojedynczy obraz lub strumień);
  • tryb wykrywania (pojedyncze lub wiele wykrywanie obiektów);
  • tryb klasyfikacji (włączony lub wyłączony);

Te warsztaty dotyczą wykrywania i klasyfikacji wielu obiektów na jednym obrazie. Dodaj teraz:

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

Krok 3. Prześlij obrazy do detektora

Wykrywanie i klasyfikacja obiektów to przetwarzanie asynchroniczne:

  • Wysyłasz obraz do detektora (za pomocą process()).
  • Wykrywacz bardzo się przy tym napracuje.
  • Detektor zwraca wynik za pomocą wywołania zwrotnego.

Poniższy kod wykonuje właśnie to działanie (skopiuj go i dołącz do istniejącego kodu w sekcji fun runObjectDetection(bitmap:Bitmap)):

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

Po zakończeniu wykrywania detektor powiadomi Cię o:

  • Łączna liczba wykrytych obiektów. Każdy wykryty obiekt jest opisany za pomocą tych informacji:
  • trackingId: liczba całkowita używana do śledzenia jej w różnych klatkach (NIE jest używana w tym laboratorium).
  • boundingBox: ramka ograniczająca obiektu.
  • labels: listę etykiet wykrytego obiektu (tylko wtedy, gdy włączona jest klasyfikacja);
  • index (Pobierz indeks tej etykiety)
  • text (Pobierz tekst tej etykiety, w tym „Artykuły modowe”, „Żywność”, „Artykuły gospodarstwa domowego”, „Miejsce”, „Roślina”)
  • confidence ( liczba zmiennoprzecinkowa od 0,0 do 1,0, przy czym 1,0 oznacza 100%)

Pewnie zauważysz, że kod przetwarza wykryty wynik w sposób podobny do funkcji printf, używając znaku debugPrint().

Dodaj go do klasy MainActivity:

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

Możesz już akceptować obrazy do wykrywania.

Uruchommy codelab, klikając Uruchom ( execute.png) na pasku narzędzi Android Studio. Wybierz gotowy obraz lub zrób zdjęcie, a następnie otwórz okno logcat16bd6ea224cf8cf1.png w IDE.

Powinien pojawić się ekran podobny do tego:

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Food
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

...co oznacza, że detektor wykrył 3 obiekty:

  • Kategorie to JedzenieArtykuły gospodarstwa domowego.
  • W przypadku drugiego elementu nie ma zwróconej kategorii, ponieważ jest to nieznana klasa.
  • Nie ma trackingId (ponieważ jest to tryb wykrywania pojedynczego obrazu).
  • Pozycja w prostokącie boundingBox (np. (481, 2021) – (2426, 3376))
  • Detektor jest dość pewny, że 1 to jedzenie (90% – to była sałatka).

Technicznie to wszystko, czego potrzebujesz, aby wykrywanie obiektów w ML Kit działało: masz już wszystko! Gratulacje!

W interfejsie użytkownika nadal jesteś na etapie, na którym zaczęliśmy, ale możesz wykorzystać wykryte wyniki w interfejsie, np. narysować ramkę ograniczającą, aby zwiększyć wygodę użytkownika. Przejdźmy do następnego kroku – przetwarzania końcowego wykrytych wyników.

6. Przetwarzanie końcowe wyników wykrywania

W poprzednich krokach wyświetlasz wykryty wynik w logcat: prosto i szybko.

W tej sekcji wykorzystasz wynik na obrazie:

  • narysować ramkę ograniczającą na obrazie;
  • rysuj nazwę kategorii i poziom ufności w ramce ograniczającej,

Omówienie narzędzi do wizualizacji

W tym laboratorium kodu znajdziesz fragmenty kodu, które pomogą Ci wizualizować wyniki wykrywania. Skorzystaj z tych narzędzi, aby uprościć kod wizualizacji:

  • data class BoxWithText(val box: Rect, val text: String) Jest to klasa danych do przechowywania wyniku wykrywania obiektów na potrzeby wizualizacji. box to ramka ograniczająca, w której znajduje się obiekt, a text to ciąg znaków z wynikiem wykrywania, który ma być wyświetlany razem z ramką ograniczającą obiektu.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap Ta metoda rysuje wyniki wykrywania obiektów w detectionResults na wejściowym bitmap i zwraca jego zmodyfikowaną kopię.

Oto przykład wyniku działania metody narzędziowej drawDetectionResult:

58c6f1d4ddb00dfa.png

Wyświetlanie wizualizacji wyniku wykrywania ML Kit

Użyj narzędzi do wizualizacji, aby narysować wynik wykrywania obiektów w ML Kit na obrazie wejściowym.

Przejdź do miejsca, w którym wywołujesz funkcję debugPrint(), i dodaj pod nią ten fragment kodu:

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • Zacznij od przeanalizowania DetectedObject ML Kit i utworzenia listy obiektów BoxWithText, aby wyświetlić wynik wizualizacji.
  • Następnie narysuj wynik wykrywania na obrazie wejściowym za pomocą metody narzędziowej drawDetectionResult i wyświetl go na ekranie.

Stosuj

Teraz na pasku narzędzi Android Studio kliknij Uruchom ( execute.png).

Po wczytaniu aplikacji naciśnij przycisk z ikoną aparatu, skieruj aparat na obiekt, zrób zdjęcie i zaakceptuj je (w aplikacji Aparat) lub kliknij dowolne gotowe zdjęcie. Powinny pojawić się wyniki wykrywania. Naciśnij ponownie przycisk lub wybierz inny obraz, aby powtórzyć tę czynność kilka razy i sprawdzić najnowszą wersję ODT w ML Kit.

a03109cb30d5014d.png

7. Gratulacje!

Za pomocą ML Kit udało Ci się dodać do aplikacji funkcje wykrywania obiektów:

  • 3 kroki z 3 interfejsami API
  • Utwórz obraz wejściowy
  • Tworzenie detektora
  • Wysyłanie obrazu do detektora

To wszystko, czego potrzebujesz, aby zacząć korzystać z tej funkcji.

W trakcie pracy możesz ulepszyć model. Jak widzisz, domyślny model rozpoznaje tylko 5 kategorii – nie zna nawet noża, widelca ani butelki. Aby dowiedzieć się, jak wytrenować własny model, zapoznaj się z innym samouczkiem z naszej ścieżki szkoleniowej dotyczącej uczenia maszynowego na urządzeniu – wykrywanie obiektów.

Omówione zagadnienia

  • Dodawanie do aplikacji na Androida funkcji wykrywania i śledzenia obiektów z ML Kit
  • Jak używać wykrywania i śledzenia obiektów na urządzeniu w ML Kit do wykrywania obiektów na obrazach

Następne kroki

  • Odkryj więcej możliwości ML Kit ODT na większej liczbie zdjęć i w transmisjach na żywo, aby przekonać się o dokładności i skuteczności wykrywania i klasyfikacji.
  • Zapoznaj się ze ścieżką szkoleniową Wykrywanie obiektów w sekcji Uczenie maszynowe na urządzeniu, aby dowiedzieć się, jak wytrenować model niestandardowy.
  • Stosowanie ML Kit ODT we własnej aplikacji na Androida

Więcej informacji