GenAI Image Description API

Dzięki interfejsowi GenAI Image Description API w ML Kit możesz generować krótkie opisy treści dla obrazów. Może to być przydatne w tych sytuacjach:

  • Generowanie tytułów obrazów
  • generowanie tekstu alternatywnego, aby ułatwić użytkownikom niedowidzącym zrozumienie treści obrazów;
  • Korzystanie z wygenerowanych opisów jako metadanych, aby ułatwić użytkownikom wyszukiwanie i porządkowanie obrazów
  • Korzystanie z krótkich opisów obrazów, gdy użytkownik nie może patrzeć na ekran, np. podczas jazdy samochodem lub słuchania podcastu.

Najważniejsze funkcje

  • zwraca krótki opis obrazu wejściowego;

Przykładowe wyniki

Wejście Dane wyjściowe
Zielony robot Android w postaci kaktusa stoi na czarnej powierzchni. Zielony robot Android w postaci kaktusa na czarnym tle.
Mały, biały pies z czarnym nosem i różowym językiem biegnie po trawiastym polu z mostem w tle. Mały, biały pies z czarnym nosem i różowym językiem biegnie po trawiastym polu z mostem w tle.

Pierwsze kroki

Aby rozpocząć korzystanie z interfejsu GenAI Image Description API, dodaj tę zależność do pliku kompilacji projektu.

implementation("com.google.mlkit:genai-image-description:1.0.0-beta1")

Aby zintegrować interfejs Image Description API z aplikacją, zacznij od pobrania klienta ImageDescriber. Następnie sprawdź stan niezbędnych funkcji modelu na urządzeniu i pobierz model, jeśli nie jest jeszcze na urządzeniu. Po przygotowaniu danych wejściowych w formacie ImageDescriptionRequest wykonaj wnioskowanie za pomocą klienta, aby uzyskać tekst opisu obrazu. Pamiętaj, aby zamknąć klienta, aby zwolnić zasoby.

Kotlin

// Create an image describer
val options = ImageDescriberOptions.builder(context).build()
val imageDescriber = ImageDescription.getClient(options)

suspend fun prepareAndStartImageDescription(
    bitmap: Bitmap
) {
  // Check feature availability, status will be one of the following:
  // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
  val featureStatus = imageDescriber.checkFeatureStatus().await()

  if (featureStatus == FeatureStatus.DOWNLOADABLE) {
      // Download feature if necessary.
      // If downloadFeature is not called, the first inference request
      // will also trigger the feature to be downloaded if it's not
      // already downloaded.
      imageDescriber.downloadFeature(object : DownloadCallback {
          override fun onDownloadStarted(bytesToDownload: Long) { }

          override fun onDownloadFailed(e: GenAiException) { }

          override fun onDownloadProgress(totalBytesDownloaded: Long) {}

          override fun onDownloadCompleted() {
              startImageDescriptionRequest(bitmap, imageDescriber)
          }
      })
  } else if (featureStatus == FeatureStatus.DOWNLOADING) {
      // Inference request will automatically run once feature is
      // downloaded.
      // If Gemini Nano is already downloaded on the device, the
      // feature-specific LoRA adapter model will be downloaded
      // very quickly. However, if Gemini Nano is not already
      // downloaded, the download process may take longer.
      startImageDescriptionRequest(bitmap, imageDescriber)
  } else if (featureStatus == FeatureStatus.AVAILABLE) {
      startImageDescriptionRequest(bitmap, imageDescriber)
  }
}

fun startImageDescriptionRequest(
    bitmap: Bitmap,
    imageDescriber: ImageDescriber
) {
    // Create task request
    val imageDescriptionRequest = ImageDescriptionRequest
        .builder(bitmap)
        .build()
}

  // Run inference with a streaming callback
  val imageDescriptionResultStreaming =
      imageDescriber.runInference(imageDescriptionRequest) { outputText ->
          // Append new output text to show in UI
          // This callback is called incrementally as the description
          // is generated
      }

  // You can also get a non-streaming response from the request
  // val imageDescription = imageDescriber.runInference(
  //        imageDescriptionRequest).await().description
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
imageDescriber.close()

Java

// Create an image describer
ImageDescriberOptions options = ImageDescriberOptions.builder(context).build();
ImageDescriber imageDescriber = ImageDescription.getClient(options);

void prepareAndStartImageDescription(
      Bitmap bitmap
) throws ExecutionException, InterruptedException {
  // Check feature availability, status will be one of the following:
  // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
  try {
      int featureStatus = imageDescriber.checkFeatureStatus().get();
      if (featureStatus == FeatureStatus.DOWNLOADABLE) {
          // Download feature if necessary.
          // If downloadFeature is not called, the first inference request
          // will also trigger the feature to be downloaded if it's not
          // already downloaded.
          imageDescriber.downloadFeature(new DownloadCallback() {
              @Override
              public void onDownloadCompleted() {
                  startImageDescriptionRequest(bitmap, imageDescriber);
              }

              @Override
              public void onDownloadFailed(GenAIException e) {}

              @Override
              public void onDownloadProgress(long totalBytesDownloaded) {}

              @Override
              public void onDownloadStarted(long bytesDownloaded) {}
          });
      } else if (featureStatus == FeatureStatus.DOWNLOADING) {
          // Inference request will automatically run once feature is
          // downloaded.
          // If Gemini Nano is already downloaded on the device, the
          // feature-specific LoRA adapter model will be downloaded
          // very quickly. However, if Gemini Nano is not already
          // downloaded, the download process may take longer.
          startImageDescriptionRequest(bitmap, imageDescriber);
      } else if (featureStatus == FeatureStatus.AVAILABLE) {
          startImageDescriptionRequest(bitmap, imageDescriber);
      }
  } catch (ExecutionException | InterruptedException e) {
      e.printStackTrace();
  }
}

void startImageDescriptionRequest(
     Bitmap bitmap,
     ImageDescriber imageDescriber
) {
  // Create task request
  ImageDescriptionRequest imageDescriptionRequest =
          ImageDescriptionRequest.builder(bitmap).build();

  // Start image description request with streaming response
  imageDescriber.runInference(imageDescriptionRequest, newText -> {
      // Append new output text to show in UI
      // This callback is called incrementally as the description
      // is generated
  });

  // You can also get a non-streaming response from the request
  // String imageDescription = imageDescriber.runInference(
  //        imageDescriptionRequest).get().getDescription();
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
imageDescriber.close();

Obsługiwane funkcje i ograniczenia

Interfejs API GenAI Image Description obsługuje język angielski, a w przyszłości dodamy obsługę kolejnych języków. Interfejs API zwraca 1 krótki opis obrazu.

Dostępność określonej konfiguracji funkcji (określonej przez ImageDescriberOptions) może się różnić w zależności od konfiguracji konkretnego urządzenia i modeli pobranych na to urządzenie.

Najbardziej niezawodnym sposobem na sprawdzenie przez deweloperów, czy dana funkcja interfejsu API jest obsługiwana na urządzeniu z żądanym ImageDescriberOptions, jest wywołanie metody checkFeatureStatus(). Ta metoda zapewnia ostateczny stan dostępności funkcji na urządzeniu w czasie wykonywania.

Typowe problemy z konfiguracją

Interfejsy API generatywnej AI w ML Kit korzystają z aplikacji Android AICore, aby uzyskać dostęp do Gemini Nano. Gdy urządzenie zostanie dopiero skonfigurowane (w tym zresetowane) lub aplikacja AICore zostanie dopiero zresetowana (np. przez wyczyszczenie danych, odinstalowanie i ponowne zainstalowanie), może ona nie mieć wystarczająco dużo czasu na zakończenie inicjalizacji (w tym pobrania najnowszych konfiguracji z serwera). W związku z tym interfejsy API ML Kit GenAI mogą nie działać zgodnie z oczekiwaniami. Oto typowe komunikaty o błędach konfiguracji, które mogą się pojawić, oraz sposoby ich rozwiązywania:

Przykładowy komunikat o błędzie Jak postępować
Nie udało się uruchomić AICore. Wystąpił błąd typu 4-CONNECTION_ERROR i kod błędu 601-BINDING_FAILURE: nie udało się połączyć usługi AICore. Może się tak zdarzyć, gdy zainstalujesz aplikację za pomocą interfejsów ML Kit GenAI bezpośrednio po skonfigurowaniu urządzenia lub gdy po zainstalowaniu aplikacji odinstalujesz AICore. Problem powinien rozwiązać zaktualizowanie aplikacji AICore, a następnie ponowne zainstalowanie aplikacji.
Nie udało się uruchomić AICore. Wystąpił błąd typu 3-PREPARATION_ERROR i kod błędu 606-FEATURE_NOT_FOUND: Funkcja … jest niedostępna. Może się tak zdarzyć, gdy AICore nie skończyło pobierania najnowszych konfiguracji. Nie przerywaj połączenia z internetem i zaczekaj kilka minut lub godzin.

Uwaga: jeśli bootloader urządzenia jest odblokowany, zobaczysz ten sam błąd – ten interfejs API nie obsługuje urządzeń ze zwykłym bootloaderem.
AICore nie powiodło się: błąd typu 1-DOWNLOAD_ERROR i kod błędu 0-UNKNOWN: funkcja ... nie powiodła się ze stanem błędu 0 i błędem esz: UNAVAILABLE: nie można rozpoznać hosta ... Nie rozłączaj się z siecią, zaczekaj kilka minut i spróbuj ponownie.