זיהוי אובייקטים בתמונות באמצעות ערכת למידת מכונה: Android

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

ML Kit היא ערכת SDK לנייד שמשלבת את המומחיות של Google בלמידת מכונה במכשיר לאפליקציות ל-Android ול-iOS. אתם יכולים להשתמש בממשקי ה-API המתקדמים, אבל גם פשוטים לשימוש, כדי לפתור אתגרים נפוצים באפליקציות או כדי ליצור חוויות משתמש חדשות לגמרי. כל המודלים מבוססים על המודלים הטובים ביותר של Google ללמידת מכונה (ML) ומוצעים ללא עלות.

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

ה-Codelab הזה ידריך אותך בשלבים פשוטים להוספת זיהוי ומעקב של אובייקטים (ODT) לתמונה נתונה לאפליקציה הקיימת שלך ל-Android. שימו לב שב-Codelab הזה נדרשים כמה קיצורי דרך כדי להדגיש את השימוש ב-ML Kit ODT.

מה תפַתחו

ב-Codelab הזה, אתם עומדים לפתח אפליקציה ל-Android עם ML Kit. האפליקציה תשתמש ב-ML Kit Object Detection and Tracking API כדי לזהות אובייקטים בתמונה נתונה.בסיום, אמור להופיע משהו שדומה לתמונה שמשמאל.

מה תלמדו

  • איך לשלב את ML Kit SDK באפליקציה ל-Android
  • ממשק API לזיהוי אובייקטים ולמעקב של ML Kit

מה צריך להכין

  • גרסה עדכנית של Android Studio (גרסה 4.1.2 ואילך)
  • אמולטור Android Studio או מכשיר Android פיזי
  • הקוד לדוגמה
  • ידע בסיסי בפיתוח Android ב-Kotlin

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

2. להגדרה

להורדת הקוד

כדי להוריד את כל הקוד עבור Codelab זה, יש ללחוץ על הקישור הבא:

פורקים את קובץ ה-ZIP שהורדתם. הפעולה הזו תגרום לפתיחת תיקיית בסיס (mlkit-android-main) עם כל המשאבים הדרושים. בשביל ה-Codelab הזה, צריך רק את המקורות בספריית המשנה object-detection.

ספריית המשנה לזיהוי אובייקטים במאגר mlkit-android מכילה שתי ספריות:

  • android_studio_folder.pngסימן לתחילת פעולה – קוד התחלה שעליו יוצרים ב-Codelab הזה.
  • android_studio_folder.pngסופי – הקוד שהושלם לאפליקציה לדוגמה המוגמר.

3. הוספה של ממשק API לזיהוי אובייקטים ומעקב של ML Kit לפרויקט

ייבוא האפליקציה אל Android Studio

כדי להתחיל, צריך לייבא את האפליקציה לתחילת הפעולה אל Android Studio.

פותחים את Android Studio, בוחרים באפשרות ייבוא פרויקט (Gradle, Eclipse ADT וכו') ובוחרים את התיקייה starter מקוד המקור שהורדתם קודם.

7c0f27882a2698ac.png

להוסיף את יחסי התלות לזיהוי ולמעקב של אובייקטים של ML Kit

יחסי התלות של ML Kit מאפשרים לשלב את ML Kit ODT SDK באפליקציה שלכם. מוסיפים את השורות הבאות בסוף הקובץ app/build.gradle של הפרויקט:

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

סנכרון הפרויקט עם קובצי gradle

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

בסרגל הכלים של Android Studio, בוחרים באפשרות Sync Project with Gradle Files ( b451ab2d04d835f9.png).

(אם הלחצן הזה מושבת, צריך לייבא רק את starter/app/build.gradle ולא את כל המאגר).

4. הפעלת האפליקציה לתחילת פעולה

עכשיו, אחרי שייבאת את הפרויקט ל-Android Studio והוספת את התלות לזיהוי ולמעקב של אובייקטים של ML Kit, אפשר להפעיל את האפליקציה בפעם הראשונה.

מחברים את מכשיר Android באמצעות USB למארח, או מפעילים את האמולטור Android Studio ולוחצים על הפעלה ( execute.png) בסרגל הכלים של Android Studio.

איך מפעילים את האפליקציה וחוקרים אותה

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

קודם כול, יש לחצן ( c6d965d639c3646.png) בתחתית המסך כדי:

  • הצגת אפליקציית המצלמה שמשולבת במכשיר/באמולטור
  • מצלמים תמונה בתוך אפליקציית המצלמה
  • לקבל את התמונה שצולמה באפליקציה למתחילים
  • הצגת התמונה

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

חוזרים כמה פעמים כדי לראות איך זה עובד:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

שנית, יש 3 תמונות מוגדרות מראש שאפשר לבחור מתוכן. אפשר להשתמש בתמונות האלה בשלב מאוחר יותר כדי לבדוק את הקוד לזיהוי אובייקטים, אם משתמשים באמולטור Android.

בוחרים תמונה מתוך 3 התמונות שהוגדרו מראש. התמונה מוצגת בתצוגה גדולה יותר:

1dd41b3ec978f1d9.png

5. הוספת זיהוי אובייקטים במכשיר

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

אחרי שבוחרים תמונה מהתמונות שנקבעו מראש או מצלמים תמונה באמצעות אפליקציית המצלמה, הקוד הסטנדרטי מפענח את התמונה למופע של Bitmap, מציג אותה במסך ומפעיל את השיטה runObjectDetection עם התמונה.

בשלב הזה, יתווסף קוד ל-method runObjectDetection כדי לבצע זיהוי אובייקטים!

הגדרה והפעלה של זיהוי אובייקטים בתמונה במכשיר

כדי להגדיר ML Kit ODT יש רק 3 שלבים פשוטים עם 3 ממשקי API:

  • הכנת תמונה: InputImage
  • יצירת אובייקט מזהה: ObjectDetection.getClient(options)
  • מחברים את שני האובייקטים שלמעלה: process(image)

אפשר להשיג אותם בתוך הפונקציה runObjectDetection(bitmap: Bitmap) בקובץ MainActivity.kt.

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

כרגע הפונקציה ריקה. כדי להטמיע ML Kit ODT, צריך להמשיך לשלבים הבאים. בדרך, תופיע בקשה מ-Android Studio להוסיף את פעולות הייבוא הנדרשות:

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

שלב 1: יצירת קלטתמונה

ML Kit מספק API פשוט ליצירת InputImage מ-Bitmap. לאחר מכן אפשר להזין InputImage בממשקי ה-API של ML Kit.

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

צריך להוסיף את הקוד שלמעלה בחלק העליון של runObjectDetection(bitmap:Bitmap).

שלב 2: יצירת מופע של מזהה

ערכת ML Kit פועלת לפי Builder Design Template. תעבירו את ההגדרות ל-builder ואז תשיגו גלאי. יש 3 אפשרויות להגדרה (ב-Codelab הזה נעשה שימוש באפשרויות שמופיעות בגופן מודגש):

  • מצב מזהה (תמונה יחידה או סטרימינג)
  • מצב זיהוי (זיהוי אובייקט יחיד או מספר)
  • מצב סיווג (מופעל או מושבת)

ה-Codelab הזה מיועד לתמונה יחידה – זיהוי אובייקטים מרובים של משפטים יחידים, אפשר להוסיף את זה עכשיו:

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

שלב 3: פיד תמונות למזהה

זיהוי וסיווג של אובייקטים עוברים עיבוד אסינכרוני:

  • שולחים תמונה למזהה (דרך process()).
  • הגלאי משקיע לא מעט.
  • המזהה מדווח על התוצאה בחזרה באמצעות התקשרות חזרה.

הקוד הבא עושה בדיוק את זה (מעתיק ומצרפים אותו לקוד הקיים בתוך fun runObjectDetection(bitmap:Bitmap)):

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

בסיום התהליך, המזהה יודיע לכם באמצעות:

  • המספר הכולל של האובייקטים שזוהו. כל אובייקט שזוהה מתואר עם:
  • trackingId: מספר שלם שמשמש למעקב אחרי פריימים שונים (לא נעשה בו שימוש ב-Codelab הזה).
  • boundingBox: התיבה התוחמת של האובייקט.
  • labels: רשימה של תוויות לאובייקט שזוהה (רק כשמופעל סיווג):
  • index (קבלת האינדקס של התווית הזו)
  • text (קבלת הטקסט של התווית הזו, כולל "מוצרי אופנה", "אוכל", "מוצרים לבית", "מקום", "צמח")
  • confidence ( מספר צף בין 0.0 ל-1.0 עם 1.0 פירושו 100%)

בטח שמת לב שהקוד מבצע עיבוד Printf לתוצאה שזוהתה באמצעות debugPrint().

כדי להוסיף אותו לכיתה אחת (MainActivity):

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

עכשיו הכול מוכן לקבלת תמונות לצורך זיהוי!

כדי להריץ את Codelab, לוחצים על Run ( execute.png) בסרגל הכלים של Android Studio. כדאי לבחור תמונה שהוגדרה מראש או לצלם תמונה, ולאחר מכן להסתכל בחלון Logcat ( 16bd6ea224cf8cf1.png) שבתוך סביבת הפיתוח המשולבת (IDE).

אתם אמורים לראות משהו כזה:

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Food
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

...כלומר, הגלאי ראה 3 אובייקטים:

  • הקטגוריות הן אוכל ומוצרי בית.
  • לא הוחזרה קטגוריה השנייה כי היא לא ידועה.
  • לא trackingId (כי זהו מצב זיהוי תמונה יחידה).
  • המיקום שבתוך המלבן boundingBox (למשל: (481, 2021) – (2426, 3376))
  • הגלאי די בטוח שהמקום הראשון הוא אוכל (90% סבירות גבוהה – זה היה סלט).

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

בצד של ממשק המשתמש, אתם עדיין בשלב שבו התחלתם, אבל אפשר להשתמש בתוצאות שזוהו בממשק המשתמש, כמו שרטוט של תיבה תוחמת (bounding box) כדי ליצור חוויה טובה יותר. בואו נעבור לשלב הבא – אחרי העיבוד של התוצאות שזוהו!

6. לאחר עיבוד תוצאות הזיהוי

בשלבים הקודמים, מדפיסים את התוצאה שזוהתה ב-logcat: פשוט ומהיר.

בקטע הזה תשתמשו בתוצאה כדי ליצור את התמונה:

  • ציירו את התיבה התוחמת בתמונה
  • שרטטו את שם הקטגוריה ואת רמת הסמך בתוך תיבה תוחמת (bounding box).

הסבר על הכלים להמחשה

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

  • data class BoxWithText(val box: Rect, val text: String) זהו סיווג נתונים לאחסון תוצאה של זיהוי אובייקטים לצורך הצגה חזותית. box היא התיבה התוחמת שבה האובייקט נמצא, ו-text היא מחרוזת תוצאת הזיהוי שצריך להציג יחד עם התיבה התוחמת של האובייקט.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap השיטה הזו מציירת את התוצאה של זיהוי האובייקטים ב-detectionResults על הקלט bitmap ומחזירה את העותק המתוקן שלו.

הנה דוגמה לפלט של שיטת השירות drawDetectionResult:

58c6f1d4ddb00dfa.png

הצגה חזותית של תוצאת הזיהוי של ML Kit

להשתמש בכלים להמחשה חזותית כדי לשרטט את תוצאת זיהוי האובייקטים של ML Kit על תמונת הקלט.

עוברים למקום שבו קוראים לפונקציה debugPrint() ומוסיפים מתחתיו את קטע הקוד הבא:

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • בשלב הראשון צריך לנתח את DetectedObject של ערכת למידת המכונה וליצור רשימה של BoxWithText אובייקטים כדי להציג את תוצאת ההצגה החזותית.
  • לאחר מכן משרטטים את תוצאת הזיהוי על תמונת הקלט, באמצעות שיטת השירות drawDetectionResult, ומציגים אותה על המסך.

הפעלה

עכשיו לוחצים על הפעלה ( execute.png) בסרגל הכלים של Android Studio.

אחרי שהאפליקציה נטענת, לוחצים על הלחצן עם סמל המצלמה, מכוונים את המצלמה לאובייקט, מצלמים תמונה, מאשרים את התמונה (באפליקציית המצלמה) או מקישים בקלות על תמונות שהוגדרו מראש. תוצאות הזיהוי אמורות להופיע. לוחצים שוב על הלחצן או בוחרים תמונה אחרת כדי לחזור כמה פעמים כדי ליהנות מהגרסה העדכנית ביותר של ML Kit ODT!

a03109cb30d5014d.png

7. מעולה!

השתמשת ב-ML Kit כדי להוסיף לאפליקציה יכולות של זיהוי אובייקטים:

  • 3 שלבים עם 3 ממשקי API
  • יצירת קלט תמונה
  • יצירת מזהה
  • שליחת תמונה למזהה

זה כל מה שצריך כדי להפעיל את הכלי.

ככל שממשיכים, ייתכן שתרצו לשפר את המודל: כפי שניתן לראות שמודל ברירת המחדל יכול לזהות רק 5 קטגוריות — המודל אפילו לא יודע סכין, מזלג ובקבוק. אתם מוזמנים לצפות בשיעור ה-Codelab השני במסלול הלמידה של למידת מכונה במכשיר – זיהוי אובייקטים כדי ללמוד איך אפשר לאמן מודל מותאם אישית.

אילו נושאים דיברנו?

  • איך מוסיפים זיהוי ומעקב של אובייקטים של ML Kit לאפליקציה ל-Android
  • איך משתמשים בזיהוי אובייקטים במכשיר ובמעקב שלהם ב-ML Kit כדי לזהות אובייקטים בתמונות

השלבים הבאים

  • מגלים יותר אפשרויות עם ML Kit ODT עם עוד תמונות וסרטונים בשידור חי, וכך לזהות הדיוק והביצועים של הסיווג
  • כדאי לעיין במאמר בנושא למידת מכונה במכשיר – מסלול הלמידה לזיהוי אובייקטים כדי ללמוד איך לאמן מודל מותאם אישית
  • החלת ML Kit ODT באפליקציה שלכם ל-Android

מידע נוסף