GenAI Image Description API

בעזרת GenAI Image Description API של ML Kit, אתם יכולים ליצור תיאורי תוכן קצרים לתמונות. האפשרות הזו יכולה להיות שימושית במקרים הבאים:

  • יצירת שמות של תמונות
  • יצירת טקסט חלופי (alt text) כדי לעזור למשתמשים עם ליקויי ראייה להבין טוב יותר את תוכן התמונות
  • שימוש בתיאורים שנוצרו כמטא-נתונים כדי לעזור למשתמשים לחפש או לארגן תמונות
  • שימוש בתיאורים קצרים של תמונות כשהמשתמש לא יכול להסתכל על המסך, למשל כשהוא נוהג או מאזין לפודקאסט

יכולות עיקריות

  • החזרת תיאור קצר של תמונה שהוזנה

תוצאות לדוגמה

קלט פלט
רובוט אנדרואיד קטן וירוק עם עיצוב דמוי קקטוס יושב על משטח שחור. רובוט אנדרואיד קטן וירוק עם עיצוב דמוי קקטוס יושב על משטח שחור.
כלב קטן ולבן עם אף שחור ולשון ורודה רץ בשדה דשא עם גשר ברקע. כלב קטן ולבן עם אף שחור ולשון ורודה רץ בשדה דשא עם גשר ברקע.

תחילת העבודה

כדי להתחיל להשתמש ב-GenAI Image Description API, מוסיפים את התלות הזו לקובץ ה-build של הפרויקט.

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

כדי לשלב את Image Description API באפליקציה, צריך קודם לקבל לקוח ImageDescriber. לאחר מכן צריך לבדוק את הסטטוס של התכונות הדרושות של המודל במכשיר ולהוריד את המודל אם הוא עדיין לא נמצא במכשיר. אחרי שמכינים את קלט התמונה ב-ImageDescriptionRequest, מריצים את ההסקה באמצעות הלקוח כדי לקבל את טקסט תיאור התמונה, ובסיום, לא שוכחים לסגור את הלקוח כדי לשחרר משאבים.

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();

תכונות נתמכות ומגבלות

ה-API של תיאור תמונות מבוסס-AI גנרטיבי תומך באנגלית, ובעתיד נוסיף תמיכה בשפות נוספות. ה-API מחזיר תיאור קצר אחד של התמונה.

הזמינות של הגדרת התכונה הספציפית (שמצוינת על ידי ImageDescriberOptions) עשויה להשתנות בהתאם לתצורה של המכשיר הספציפי ולמודלים שהורדו למכשיר.

הדרך הכי אמינה למפתחים לוודא שתכונת ה-API הרצויה נתמכת במכשיר עם ImageDescriberOptions המבוקש היא לבצע קריאה ל-method‏ checkFeatureStatus(). השיטה הזו מספקת את הסטטוס הסופי של זמינות התכונה במכשיר בזמן הריצה.

בעיות נפוצות בהגדרה

ממשקי GenAI API של ML Kit מסתמכים על אפליקציית Android AICore כדי לגשת ל-Gemini Nano. כשמגדירים מכשיר חדש (כולל איפוס), או כשמאפסים את אפליקציית AICore (למשל, מוחקים את הנתונים, מסירים את ההתקנה ואז מתקינים מחדש), יכול להיות שלאפליקציית AICore לא יהיה מספיק זמן לסיים את האתחול (כולל הורדת ההגדרות האחרונות מהשרת). כתוצאה מכך, יכול להיות שממשקי ה-API של ML Kit GenAI לא יפעלו כמצופה. ריכזנו כאן את הודעות השגיאה הנפוצות שמוצגות במהלך ההגדרה, והסבר איך לטפל בהן:

דוגמה להודעת שגיאה איך לטפל בבעיה
הפעולה של AICore נכשלה עם סוג השגיאה 4-CONNECTION_ERROR וקוד השגיאה 601-BINDING_FAILURE: שירות AICore נכשל בקישור. זה יכול לקרות כשמתקינים את האפליקציה באמצעות ממשקי ה-API של ML Kit GenAI מיד אחרי הגדרת המכשיר, או כשמסירים את ההתקנה של AICore אחרי התקנת האפליקציה. עדכון של אפליקציית AICore ואז התקנה מחדש של האפליקציה אמורים לפתור את הבעיה.
הפעולה של AICore נכשלה עם סוג השגיאה 3-PREPARATION_ERROR וקוד השגיאה 606-FEATURE_NOT_FOUND: התכונה ... לא זמינה. מצב כזה יכול לקרות כש-AICore לא סיים להוריד את ההגדרות האחרונות. כשהמכשיר מחובר לאינטרנט, העדכון מתבצע בדרך כלל תוך כמה דקות עד כמה שעות. הפעלה מחדש של המכשיר יכולה לזרז את העדכון.

שימו לב שאם טוען האתחול של המכשיר לא נעול, תוצג גם השגיאה הזו – ה-API הזה לא תומך במכשירים עם טועני אתחול לא נעולים.
הייתה שגיאה ב-AICore מסוג 1-DOWNLOAD_ERROR וקוד שגיאה 0-UNKNOWN: התכונה ... נכשלה עם סטטוס כשל 0 ושגיאה esz: UNAVAILABLE: לא ניתן לפתור את המארח ... משאירים את החיבור לרשת, מחכים כמה דקות ומנסים שוב.