זיהוי אובייקטים בתמונות באמצעות מודל AutoML שאומן ב-Android

אחרי שתאמנים את המודל באמצעות AutoML Vision Edge, אפשר להשתמש בו באפליקציה כדי לזהות אובייקטים בתמונות.

יש שתי דרכים לשלב מודלים שעברו אימון מ-AutoML Vision Edge: אפשר לאגד את המודל באמצעות הצבתו בתיקיית הנכסים של האפליקציה. לחלופין, אפשר תתבצע הורדה דינמית של הקובץ מ-Firebase.

אפשרויות לחבילה של מודלים
מקובצות באפליקציה שלך
  • המודל הוא חלק מה-APK של האפליקציה
  • המודל זמין באופן מיידי, גם כשמכשיר Android במצב אופליין
  • אין צורך בפרויקט Firebase
באירוח Firebase

לפני שמתחילים

  1. אם אתם רוצים להוריד מודל, צריך לוודא מוסיפים את Firebase לפרויקט Android, אם עדיין לא עשיתם זאת. אין צורך לעשות זאת כשהמודל הוא חלק מחבילה.

  2. מוסיפים את יחסי התלות של ספריית המשימות של TensorFlow Lite קובץ GRid ברמת האפליקציה, שהוא בדרך כלל app/build.gradle:

    לשילוב מודל עם האפליקציה:

    dependencies {
      // ...
      // Object detection with a bundled Auto ML model
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT'
    }
    

    כדי להוריד מודל באופן דינמי מ-Firebase, צריך להוסיף גם את למידת המכונה של Firebase של תלות:

    dependencies {
      // ...
      // Object detection with an Auto ML model deployed to Firebase
      implementation platform('com.google.firebase:firebase-bom:26.1.1')
      implementation 'com.google.firebase:firebase-ml-model-interpreter'
    
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly'
    }
    

1. טעינת המודל

הגדרת מקור למודל מקומי

כדי לצרף את המודל לאפליקציה:

  1. יש לחלץ את המודל מארכיון ה-ZIP שהורדתם מסוף Google Cloud.
  2. כלול את המודל בחבילת האפליקציה שלך:
    1. אם אין לכם תיקיית נכסים בפרויקט, תוכלו ליצור אותה בלחיצה ימנית על התיקייה app/ ואז על New > Folder > Assets Folder.
    2. מעתיקים לנכסים את קובץ המודל tflite עם מטא-נתונים מוטמעים .
  3. כדי לוודא, צריך להוסיף את הפרטים הבאים לקובץ build.gradle של האפליקציה Gradle לא דוחסת את קובץ המודל כשמפתחים את האפליקציה:

    android {
        // ...
        aaptOptions {
            noCompress "tflite"
        }
    }
    

    קובץ המודל ייכלל בחבילת האפליקציה ויהיה זמין כנכס גולמי.

הגדרת מקור מודל שמתארח ב-Firebase

כדי להשתמש במודל שמתארח מרחוק, יוצרים אובייקט RemoteModel, שמציין את השם שהקציתם למודל כשפרסמתם אותו:

Java

// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin

// Specify the name you assigned when you deployed the model.
val remoteModel =
    FirebaseCustomRemoteModel.Builder("your_model_name").build()

לאחר מכן, מתחילים את המשימה של הורדת המודל, ומציינים את התנאים שבהם שרוצים לאפשר את ההורדה שלהם. אם הדגם לא נמצא במכשיר, או אם של המודל זמינה, המשימה תוריד באופן אסינכרוני מ-Firebase:

Java

DownloadConditions downloadConditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(@NonNull Task<Void> task) {
                // Success.
            }
        });

Kotlin

val downloadConditions = DownloadConditions.Builder()
    .requireWifi()
    .build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
    .addOnSuccessListener {
        // Success.
    }

אפליקציות רבות מתחילות את משימת ההורדה בקוד האתחול שלהן, אבל תוכלו לעשות זאת בכל שלב לפני שתצטרכו להשתמש במודל.

יצירת מזהה אובייקטים מהמודל

אחרי שמגדירים את המקורות של המודלים, צריך ליצור אובייקט ObjectDetector מאובייקט מהם.

אם יש לכם רק מודל באריזה מקומית, פשוט יוצרים מזהה אובייקטים את קובץ המודל ולהגדיר את רמת הסמך. הסף הנדרש (מידע נוסף זמין במאמר הערכת המודל):

Java

// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);

Kotlin

// Initialization
val options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)

אם יש לך מודל שמתארח מרחוק, עליך לבדוק שהוא שהורדתם לפני שהפעלתם אותו. אפשר לבדוק את סטטוס ההורדה של המודל באמצעות השיטה isModelDownloaded() של מנהל המודלים.

צריך לאשר רק לפני שמפעילים את מזהה האובייקטים, אבל יש להם גם מודל שמתארח מרחוק וגם מודל בחבילות מקומיות, זה עלול ליצור לביצוע הבדיקה הזו כשמממשים את מזהה האובייקטים: מזהה אובייקטים מהמודל המרוחק אם הוא הורד, אחרת.

Java

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
            }
        });

Kotlin

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener { success ->

        }

אם יש לך רק מודל שמתארח מרחוק, עליך להשבית את התכונה שקשורה למודלים פונקציונליות - לדוגמה, הצגה באפור או הסתרה של חלק מממשק המשתמש - עד מוודאים שבוצעה הורדה של המודל. אפשר לעשות זאת על ידי צירוף listen ל-method download() של מנהל המודלים.

אחרי שבודקים שהמודל כבר הורד, יוצרים מזהה אובייקטים קובץ מודל:

Java

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    ObjectDetectorOptions options = ObjectDetectorOptions.builder()
                            .setScoreThreshold(0)
                            .build();
                    objectDetector = ObjectDetector.createFromFileAndOptions(
                            getApplicationContext(), modelFile.getPath(), options);
                }
            }
        });

Kotlin

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnSuccessListener { modelFile ->
            val options = ObjectDetectorOptions.builder()
                    .setScoreThreshold(0f)
                    .build()
            objectDetector = ObjectDetector.createFromFileAndOptions(
                    applicationContext, modelFile.path, options)
        }

2. הכנת תמונת הקלט

לאחר מכן, לכל תמונה שרוצים לתייג, יוצרים אובייקט TensorImage מהתמונה. אפשר ליצור אובייקט TensorImage מ-Bitmap באמצעות אמצעי תשלום fromBitmap:

Java

TensorImage image = TensorImage.fromBitmap(bitmap);

Kotlin

val image = TensorImage.fromBitmap(bitmap)

אם נתוני התמונה לא נמצאים ב-Bitmap, אפשר לטעון מערך פיקסלים כמו שמוצג המסמכים של TensorFlow Lite.

3. הפעלת מזהה האובייקטים

כדי לזהות אובייקטים בתמונה, צריך להעביר את האובייקט TensorImage אל השיטה detect() של ObjectDetector.

Java

List<Detection> results = objectDetector.detect(image);

Kotlin

val results = objectDetector.detect(image)

4. אחזור מידע על אובייקטים מתויגים

אם פעולת זיהוי האובייקטים מצליחה, היא מחזירה רשימה של Detection אובייקטים. כל אובייקט Detection מייצג משהו שזוהה בתמונה. אפשר לקבל את התיבה התוחמת של כל אובייקט ואת התוויות שלה.

לדוגמה:

Java

for (Detection result : results) {
    RectF bounds = result.getBoundingBox();
    List<Category> labels = result.getCategories();
}

Kotlin

for (result in results) {
    val bounds = result.getBoundingBox()
    val labels = result.getCategories()
}

טיפים לשיפור הביצועים בזמן אמת

כדי להוסיף תווית לתמונות באפליקציה בזמן אמת, צריך לפעול לפי השלבים הבאים כדי להשיג את קצבי הפריימים הטובים ביותר:

  • ויסות קריאות למתייג התמונות. אם פריים חדש בסרטון הופך כאשר מתייג התמונות פועל, משחררים את המסגרת. VisionProcessorBase באפליקציה לדוגמה של המדריך למתחילים.
  • אם אתם משתמשים בפלט של הכלי לתיוג תמונות כדי להוסיף שכבת-על של גרפיקה לתמונה של הקלט, תחילה צריך לקבל את התוצאה, ואז לבצע עיבוד (רנדור) של התמונה ושל שכבת-העל בשלב אחד. כך תוכלו להציג את משטח המסך פעם אחת בלבד לכל מסגרת קלט. CameraSourcePreview ו GraphicOverlay כיתות באפליקציה לדוגמה של המדריך למתחילים לדוגמה.
  • אם אתם משתמשים ב-Camera2 API, כדאי לצלם תמונות בפורמט ImageFormat.YUV_420_888.

    אם משתמשים ב-Camera API הקודם, צריך לצלם תמונות בפורמט ImageFormat.NV21.