Dziękujemy za zapoznanie się z Google I/O. Zobacz wszystkie sesje na żądanie Oglądaj na żądanie

Krótkie wprowadzenie do Androida

Ta strona pokazuje, jak zbudować aplikację na Androida z TensorFlow Lite, aby analizować obraz z kamery na żywo i identyfikować obiekty. Ten przypadek użycia uczenia maszynowego nazywa się wykrywaniem obiektów . Przykładowa aplikacja wykorzystuje bibliotekę zadań TensorFlow Lite do obsługi wizji za pośrednictwem usług Google Play, aby umożliwić wykonanie modelu uczenia maszynowego wykrywania obiektów, co jest zalecanym podejściem do budowania aplikacji ML za pomocą TensorFlow Lite.

Animowane demo wykrywania obiektów

Skonfiguruj i uruchom przykład

W pierwszej części tego ćwiczenia pobierz przykładowy kod z GitHub i uruchom go za pomocą Android Studio . W poniższych sekcjach tego dokumentu omówiono odpowiednie sekcje przykładowego kodu, dzięki czemu można je zastosować do własnych aplikacji na Androida. Musisz zainstalować następujące wersje tych narzędzi:

  • Android Studio 4.2 lub nowszy
  • Android SDK w wersji 21 lub nowszej

Pobierz przykładowy kod

Utwórz lokalną kopię przykładowego kodu, aby móc go skompilować i uruchomić.

Aby sklonować i skonfigurować przykładowy kod:

  1. Sklonuj repozytorium git
    git clone https://github.com/tensorflow/examples.git
    
  2. Skonfiguruj swoją instancję git tak, aby używała sparse checkout, więc masz tylko pliki dla przykładowej aplikacji do wykrywania obiektów:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/object_detection/android_play_services
    

Zaimportuj i uruchom projekt

Użyj Android Studio, aby utworzyć projekt z pobranego przykładowego kodu, skompilować projekt i uruchomić go.

Aby zaimportować i zbudować przykładowy projekt kodu:

  1. Uruchom Android Studio .
  2. Na stronie powitalnej Android Studio wybierz Importuj projekt lub wybierz Plik > Nowy > Importuj projekt .
  3. Przejdź do przykładowego katalogu kodu zawierającego plik build.gradle ( ...examples/lite/examples/object_detection/android_play_services/build.gradle ) i wybierz ten katalog.

Po wybraniu tego katalogu Android Studio tworzy nowy projekt i kompiluje go. Po zakończeniu kompilacji Android Studio wyświetla komunikat BUILD SUCCESSFUL w panelu stanu Build Output .

Aby uruchomić projekt:

  1. W Android Studio uruchom projekt, wybierając opcję Uruchom > Uruchom… i MainActivity .
  2. Wybierz podłączone urządzenie z systemem Android z aparatem, aby przetestować aplikację.

Jak działa przykładowa aplikacja

Przykładowa aplikacja wykorzystuje wstępnie wytrenowany model wykrywania obiektów, taki jak mobilenetv1.tflite , w formacie TensorFlow Lite szuka obiektów w strumieniu wideo na żywo z kamery urządzenia z systemem Android. Kod tej funkcji znajduje się głównie w tych plikach:

  • ObjectDetectorHelper.kt — inicjuje środowisko uruchomieniowe, włącza przyspieszenie sprzętowe i uruchamia model ML wykrywania obiektów.
  • CameraFragment.kt — buduje strumień danych obrazu z kamery, przygotowuje dane dla modelu i wyświetla wyniki wykrywania obiektów.

W następnych sekcjach przedstawiono kluczowe składniki tych plików kodu, dzięki czemu możesz zmodyfikować aplikację na Androida, aby dodać tę funkcję.

Zbuduj aplikację

W poniższych sekcjach wyjaśniono kluczowe kroki, aby zbudować własną aplikację na Androida i uruchomić model pokazany w przykładowej aplikacji. W tych instrukcjach wykorzystano przykładową aplikację pokazaną wcześniej jako punkt odniesienia.

Dodaj zależności projektu

W podstawowej aplikacji na Androida dodaj zależności projektu do uruchamiania modeli uczenia maszynowego TensorFlow Lite i uzyskiwania dostępu do funkcji narzędziowych danych ML. Te funkcje narzędziowe konwertują dane, takie jak obrazy, na format danych tensora, który może być przetwarzany przez model.

Przykładowa aplikacja wykorzystuje bibliotekę zadań TensorFlow Lite Task dla wizji z usług Google Play, aby umożliwić wykonanie modelu uczenia maszynowego wykrywania obiektów. Poniższe instrukcje wyjaśniają, jak dodać wymagane zależności biblioteki do własnego projektu aplikacji dla systemu Android.

Aby dodać zależności modułu:

  1. W module aplikacji na Androida, który używa TensorFlow Lite, zaktualizuj plik build.gradle modułu, aby uwzględnić następujące zależności. W przykładowym kodzie ten plik znajduje się tutaj: ...examples/lite/examples/object_detection/android_play_services/app/build.gradle

    ...
    dependencies {
    ...
        // Tensorflow Lite dependencies
        implementation 'org.tensorflow:tensorflow-lite-task-vision-play-services:0.4.2'
        implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    ...
    }
    
  2. W Android Studio zsynchronizuj zależności projektu, wybierając: Plik > Synchronizuj projekt z plikami Gradle .

Zainicjuj usługi Google Play

Gdy używasz usług Google Play do uruchamiania modeli TensorFlow Lite, musisz zainicjować usługę, zanim będziesz mógł z niej korzystać. Jeśli chcesz korzystać z obsługi akceleracji sprzętowej w usłudze, takiej jak akceleracja GPU, możesz również włączyć tę obsługę w ramach tej inicjalizacji.

Aby zainicjować TensorFlow Lite z usługami Google Play:

  1. Utwórz obiekt TfLiteInitializationOptions i zmodyfikuj go, aby włączyć obsługę GPU:

    val options = TfLiteInitializationOptions.builder()
        .setEnableGpuDelegateSupport(true)
        .build()
    
  2. Użyj metody TfLiteVision.initialize() , aby włączyć korzystanie ze środowiska uruchomieniowego usług Play, i ustaw detektor, aby sprawdzić, czy został załadowany pomyślnie:

    TfLiteVision.initialize(context, options).addOnSuccessListener {
        objectDetectorListener.onInitialized()
    }.addOnFailureListener {
        // Called if the GPU Delegate is not supported on the device
        TfLiteVision.initialize(context).addOnSuccessListener {
            objectDetectorListener.onInitialized()
        }.addOnFailureListener{
            objectDetectorListener.onError("TfLiteVision failed to initialize: "
                    + it.message)
        }
    }
    

Zainicjuj interpreter modelu ML

Zainicjuj interpreter modelu uczenia maszynowego TensorFlow Lite, ładując plik modelu i ustawiając parametry modelu. Model TensorFlow Lite zawiera plik .tflite zawierający kod modelu. Powinieneś przechowywać swoje modele w katalogu src/main/assets swojego projektu deweloperskiego, na przykład:

.../src/main/assets/mobilenetv1.tflite`

Aby zainicjować model:

  1. Dodaj plik modelu .tflite do katalogu src/main/assets projektu programistycznego, takiego jak ssd_mobilenet_v1 .
  2. Ustaw zmienną modelName , aby określić nazwę pliku modelu ML:

    val modelName = "mobilenetv1.tflite"
    
  3. Ustaw opcje modelu, takie jak próg prognozy i rozmiar zestawu wyników:

    val optionsBuilder =
        ObjectDetector.ObjectDetectorOptions.builder()
            .setScoreThreshold(threshold)
            .setMaxResults(maxResults)
    
  4. Włącz akcelerację GPU za pomocą opcji i pozwól, aby kod nie powiódł się, jeśli akceleracja nie jest obsługiwana na urządzeniu:

    try {
        optionsBuilder.useGpu()
    } catch(e: Exception) {
        objectDetectorListener.onError("GPU is not supported on this device")
    }
    
    
  5. Użyj ustawień z tego obiektu, aby skonstruować obiekt TensorFlow Lite ObjectDetector , który zawiera model:

    objectDetector =
        ObjectDetector.createFromFileAndOptions(
            context, modelName, optionsBuilder.build())
    

Aby uzyskać więcej informacji na temat używania delegatów przyspieszenia sprzętowego z TensorFlow Lite, zobacz Delegates TensorFlow Lite .

Przygotuj dane do modelu

Przygotowujesz dane do interpretacji przez model, przekształcając istniejące dane, takie jak obrazy, do formatu danych Tensor , aby mogły być przetwarzane przez model. Dane w tensorze muszą mieć określone wymiary lub kształt, które pasują do formatu danych używanych do uczenia modelu. W zależności od używanego modelu może być konieczne przekształcenie danych w celu dopasowania do oczekiwań modelu. Przykładowa aplikacja używa obiektu ImageAnalysis do wyodrębniania ramek obrazu z podsystemu kamery.

Aby przygotować dane do przetwarzania przez model:

  1. Zbuduj obiekt ImageAnalysis , aby wyodrębnić obrazy w wymaganym formacie:

    imageAnalyzer =
        ImageAnalysis.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            .setTargetRotation(fragmentCameraBinding.viewFinder.display.rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .setOutputImageFormat(OUTPUT_IMAGE_FORMAT_RGBA_8888)
            .build()
            ...
    
  2. Podłącz analizator do podsystemu kamery i utwórz bufor bitmapy na dane otrzymane z kamery:

            .also {
            it.setAnalyzer(cameraExecutor) { image ->
                if (!::bitmapBuffer.isInitialized) {
                    bitmapBuffer = Bitmap.createBitmap(
                        image.width,
                        image.height,
                        Bitmap.Config.ARGB_8888
                    )
                }
                detectObjects(image)
            }
        }
    
  3. Wyodrębnij określone dane obrazu wymagane przez model i przekaż informacje o obrocie obrazu:

    private fun detectObjects(image: ImageProxy) {
        // Copy out RGB bits to the shared bitmap buffer
        image.use { bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer) }
        val imageRotation = image.imageInfo.rotationDegrees
        objectDetectorHelper.detect(bitmapBuffer, imageRotation)
    }    
    
  4. Wykonaj wszelkie końcowe przekształcenia danych i dodaj dane obrazu do obiektu TensorImage , jak pokazano w ObjectDetectorHelper.detect() przykładowej aplikacji:

    val imageProcessor = ImageProcessor.Builder().add(Rot90Op(-imageRotation / 90)).build()
    
    // Preprocess the image and convert it into a TensorImage for detection.
    val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
    

Uruchom prognozy

Po utworzeniu obiektu TensorImage z danymi obrazu w poprawnym formacie, możesz uruchomić model względem tych danych, aby uzyskać prognozę lub wnioskowanie . W przykładowej aplikacji ten kod jest zawarty w ObjectDetectorHelper.detect() .

Aby uruchomić model i wygenerować prognozy z danych obrazu:

  • Uruchom prognozę, przekazując dane obrazu do funkcji prognozowania:

    val results = objectDetector?.detect(tensorImage)
    

Wyjście modelu uchwytu

Po uruchomieniu danych obrazu względem modelu wykrywania obiektów generuje listę wyników przewidywania, które kod aplikacji musi obsłużyć, wykonując dodatkową logikę biznesową, wyświetlając wyniki użytkownikowi lub wykonując inne działania. Model wykrywania obiektów w przykładowej aplikacji tworzy listę prognoz i ramek ograniczających dla wykrytych obiektów. W przykładowej aplikacji wyniki prognozy są przekazywane do obiektu odbiornika w celu dalszego przetwarzania i wyświetlenia użytkownikowi.

Aby obsłużyć wyniki prognozowania modelu:

  1. Użyj wzorca odbiornika, aby przekazać wyniki do kodu aplikacji lub obiektów interfejsu użytkownika. Przykładowa aplikacja używa tego wzorca do przekazywania wyników wykrywania z obiektu ObjectDetectorHelper do obiektu CameraFragment :

    objectDetectorListener.onResults( // instance of CameraFragment
        results,
        inferenceTime,
        tensorImage.height,
        tensorImage.width)
    
  2. Działaj na podstawie wyników, na przykład wyświetlając prognozę użytkownikowi. Przykładowa aplikacja rysuje nakładkę na obiekcie CameraPreview , aby pokazać wynik:

    override fun onResults(
      results: MutableList<Detection>?,
      inferenceTime: Long,
      imageHeight: Int,
      imageWidth: Int
    ) {
        activity?.runOnUiThread {
            fragmentCameraBinding.bottomSheetLayout.inferenceTimeVal.text =
                String.format("%d ms", inferenceTime)
    
            // Pass necessary information to OverlayView for drawing on the canvas
            fragmentCameraBinding.overlay.setResults(
                results ?: LinkedList<Detection>(),
                imageHeight,
                imageWidth
            )
    
            // Force a redraw
            fragmentCameraBinding.overlay.invalidate()
        }
    }
    

Następne kroki