GenAI Image Description API

Interfejs GenAI Image Description API w ML Kit umożliwia generowanie krótkich opisów obrazów. Może to być przydatne w tych przypadkach:

  • Generowanie tytułów obrazów
  • generowanie tekstu alternatywnego, aby pomóc użytkownikom z wadą wzroku lepiej zrozumieć treść obrazów;
  • Używanie 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 prowadzenia samochodu lub słuchania podcastu;

Najważniejsze funkcje

  • Zwraca krótki opis obrazu wejściowego.

Przykładowe wyniki

Wejście Dane wyjściowe
Mały zielony robot Android o wyglądzie kaktusa siedzi na czarnej powierzchni. Mały zielony robot Android o wyglądzie kaktusa siedzi na czarnej powierzchni.
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 przez trawiaste pole z mostem w tle.

Pierwsze kroki

Aby zacząć korzystać 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 uzyskania ImageDescriber klienta. Następnie musisz sprawdzić stan niezbędnych funkcji modelu na urządzeniu i pobrać model, jeśli nie jest jeszcze dostępny na urządzeniu. Po przygotowaniu obrazu wejściowego w ImageDescriptionRequest przeprowadź wnioskowanie za pomocą klienta, aby uzyskać tekst opisu obrazu. Na koniec pamiętaj, aby zamknąć klienta i 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 GenAI Image Description API obsługuje język angielski, ale w przyszłości dodamy obsługę kolejnych języków. Interfejs API zwraca krótki opis obrazu.

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

Najbardziej niezawodnym sposobem, w jaki deweloperzy mogą się upewnić, że zamierzona funkcja interfejsu API jest obsługiwana na urządzeniu z wymaganym ImageDescriberOptions, jest wywołanie metody checkFeatureStatus(). Ta metoda podaje ostateczny stan dostępności funkcji na urządzeniu w czasie działania.

Typowe problemy z konfiguracją

Interfejsy ML Kit GenAI API korzystają z aplikacji Android AICore, aby uzyskać dostęp do Gemini Nano. Gdy urządzenie jest dopiero konfigurowane (w tym resetowane) lub aplikacja AICore jest dopiero resetowana (np. przez wyczyszczenie danych, odinstalowanie i ponowne zainstalowanie), może nie mieć wystarczająco dużo czasu na zakończenie inicjowania (w tym pobranie najnowszych konfiguracji z serwera). W związku z tym interfejsy ML Kit GenAI API mogą nie działać zgodnie z oczekiwaniami. Oto typowe komunikaty o błędach konfiguracji, które możesz zobaczyć, oraz sposoby postępowania z nimi:

Przykładowy komunikat o błędzie Jak sobie z tym poradzić
Usługa AICore nie działa z powodu błędu typu 4-CONNECTION_ERROR i kodu błędu 601-BINDING_FAILURE: nie udało się powiązać usługi AICore. Może się to zdarzyć, gdy zainstalujesz aplikację za pomocą interfejsów ML Kit GenAI API natychmiast po skonfigurowaniu urządzenia lub gdy po zainstalowaniu aplikacji odinstalujesz AICore. Zaktualizowanie aplikacji AICore, a następnie ponowne zainstalowanie aplikacji powinno rozwiązać ten problem.
Usługa AICore nie działa z powodu błędu typu 3-PREPARATION_ERROR i kodu błędu 606-FEATURE_NOT_FOUND: funkcja ... jest niedostępna. Może się tak zdarzyć, gdy AICore nie zakończyło pobierania najnowszych konfiguracji. Gdy urządzenie jest połączone z internetem, aktualizacja trwa zwykle od kilku minut do kilku godzin. Ponowne uruchomienie urządzenia może przyspieszyć aktualizację.

Pamiętaj, że ten błąd pojawi się też, jeśli program rozruchowy urządzenia jest odblokowany. Ten interfejs API nie obsługuje urządzeń z odblokowanymi programami rozruchowymi.
Usługa AICore nie działa z błędem typu 1-DOWNLOAD_ERROR i kodem błędu 0-UNKNOWN: funkcja ... nie działa ze stanem błędu 0 i błędem esz: UNAVAILABLE: nie można rozpoznać hosta ... Utrzymuj połączenie z siecią, poczekaj kilka minut i spróbuj ponownie.