מדריך לפילוח תמונות ב-Android

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

קוד לדוגמה

בדוגמה של הקוד של MediaPipe Tasks יש שני הטמעות פשוטות של אפליקציית 'פלח תמונות' ל-Android:

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

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

להורדת הקוד

בהוראות הבאות מוסבר איך ליצור עותק מקומי של הדוגמה באמצעות כלי שורת הפקודה git.

כדי להוריד את הקוד לדוגמה:

  1. משכפלים את מאגר ה-Git באמצעות הפקודה הבאה:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. אפשר גם להגדיר את ה-Git למכונת ה-Git לשימוש בקופה מועטה, יהיו לכם רק את הקבצים של האפליקציה לדוגמה של 'פלח התמונות':
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_segmentation/android
    

אחרי שיוצרים גרסה מקומית של הקוד לדוגמה, אפשר לייבא את הפרויקט אל Android Studio ולהריץ את האפליקציה. הוראות מופיעות מדריך ההגדרה ל-Android.

רכיבים מרכזיים

הקבצים הבאים מכילים את הקוד החשוב של התמונה הזו אפליקציה לדוגמה לפילוח:

  • ImageSegmenterHelper.kt – מאתחל את המשימה 'פילוח תמונות' ומטפל במודל ובהענקת גישה בחירה.
  • CameraFragment.kt – מספק את ממשק המשתמש וקוד הבקרה של המצלמה.
  • GalleryFragment.kt – ממשק המשתמש וקוד הבקרה לבחירת תמונה ווידאו .
  • OverlayView.kt - מטפל בתוצאות הפילוח ומעצב אותן.

הגדרה

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

יחסי תלות

'פלח התמונות' משתמש בספרייה com.google.mediapipe:tasks-vision. הוספת הפריט שתלויות בקובץ build.gradle של פרויקט של פיתוח אפליקציות ל-Android. לייבא את יחסי התלות הנדרשים באמצעות את הקוד הבא:

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

דגם

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

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

<dev-project-root>/src/main/assets

משתמשים בשיטה BaseOptions.Builder.setModelAssetPath() כדי לציין את הנתיב שבו משתמש המודל. השיטה הזו תופיע בדוגמה של הקוד .

במקטע התמונות example code, המודל מוגדר בImageSegmenterHelper.kt בפונקציה setupImageSegmenter().

יצירת המשימה

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

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

תמונה

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

וידאו

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

שידור חי

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .setResultListener((result, inputImage) -> {
         // Process the segmentation result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the segmentation errors here.
    })
    .build()
imagesegmenter = ImageSegmenter.createFromOptions(context, options)
    

הטמעת הקוד לדוגמה של 'פלח התמונות' מאפשרת למשתמש לעבור בין במצבי עיבוד שונים. הגישה הזו הופכת את הקוד ליצירת משימה למורכב יותר לא מתאים לתרחיש לדוגמה שלכם. אפשר לראות את הקוד הזה ImageSegmenterHelper המחלקה לפי הפונקציה setupImageSegmenter().

אפשרויות תצורה

המשימה הזו כוללת את אפשרויות ההגדרה הבאות לאפליקציות ל-Android:

שם האפשרות תיאור טווח ערכים ערך ברירת מחדל
runningMode מגדיר את מצב הריצה של המשימה. יש שלושה סוגים מצבים:

IMAGE: המצב לקלט של תמונה יחידה.

סרטון: המצב של פריימים מפוענחים בסרטון.

LIVE_STREAM: המצב לשידור חי של קלט נתונים ממצלמה, במצב הזה, resultListener חייב להיות נשלחה קריאה כדי להגדיר אוזן כדי לקבל תוצאות באופן אסינכרוני.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
outputCategoryMask אם המדיניות מוגדרת לערך True, הפלט כולל מסיכת פילוח כמו תמונת uint8, שבה כל ערך של פיקסל מציין את הקטגוריה המנצחת. עם ערך מסוים. {True, False} False
outputConfidenceMasks אם המדיניות מוגדרת לערך True, הפלט כולל מסיכת פילוח כתמונה עם ערך צף, שבו כל ערך צף מייצג את מהימנות מפת הניקוד של הקטגוריה. {True, False} True
displayNamesLocale מגדיר את השפה של תוויות שישמשו לשמות לתצוגה שסופקו של מודל המשימה, אם יש כאלה. ברירת המחדל היא en עבור אנגלית. אפשר להוסיף תוויות שמותאמות לשוק המקומי למטא-נתונים של מודל מותאם אישית באמצעות TensorFlow Lite Metadata Writer API קוד שפה en
resultListener מגדיר את אוזן התוצאות לקבל את תוצאות הפילוח באופן אסינכרוני כאשר פילוח התמונות נמצא במצב LIVE_STREAM. אפשר להשתמש באפשרות הזו רק כשמצב הריצה מוגדר ל-LIVE_STREAM לא רלוונטי לא רלוונטי
errorListener הגדרת האזנה לשגיאות אופציונלית. לא רלוונטי לא מוגדר

הכנת נתונים

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

צריך להמיר את קלט התמונה או המסגרת אובייקט com.google.mediapipe.framework.image.MPImage לפני העברה שלו פילוח תמונות.

תמונה

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the users device as a Bitmap object using BitmapFactory.

// Convert an Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

וידאו

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the videos metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. Youll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

שידור חי

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraXs ImageAnalysis to continuously receive frames
// from the devices camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Androids ImageProxy object received from the ImageAnalysis,
// extract the encapsulated Androids Image object and convert it to
// a MediaPipes Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

בקוד לדוגמה של 'פלח התמונות', הכנת הנתונים מתבצעת ImageSegmenterHelper המחלקה לפי הפונקציה segmentLiveStreamFrame().

הרצת המשימה

מפעילים פונקציה אחרת של segment בהתאם למצב ההפעלה שבו אתם משתמשים. הפונקציה 'פלח של תמונות' מחזירה את אזורי הפלח שזוהו קלט תמונה או מסגרת.

תמונה

ImageSegmenterResult segmenterResult = imagesegmenter.segment(image);
    

וידאו

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageSegmenterResult segmenterResult =
    imagesegmenter.segmentForVideo(image, frameTimestampMs);
    

שידור חי

// Run inference on the frame. The segmentations results will be available via
// the `resultListener` provided in the `ImageSegmenterOptions` when the image
// segmenter was created.
imagesegmenter.segmentAsync(image, frameTimestampMs);
    

שימו לב לנקודות הבאות:

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

בקוד לדוגמה של פילוח התמונות, הפונקציות segment מוגדרות ImageSegmenterHelper.kt חדש.

טיפול בתוצאות והצגתן

כשמריצים את ההסקה, המשימה 'פילוח תמונות' מחזירה ImageSegmenterResult שמכיל את התוצאות של משימת הפילוח. התוכן של הפלט תלוי ב-outputType שמגדירים המשימה הוגדרה.

בחלקים הבאים מוצגות דוגמאות לנתוני הפלט מהמשימה:

ודאות הקטגוריה

בתמונות הבאות מוצג תרשים של פלט המשימה של קטגוריה מסכת ביטחון. הפלט של מסכת הסמך מכיל ערכים צפים בין [0, 1]

פלט של מסכת מהימנות לתמונה ולקטגוריה. תמונת המקור מ- פסקל VOC 2012 של הכיתובים.

ערך הקטגוריה

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

פלט של התממה של התמונה והקטגוריה המקורית. תמונת המקור מ- פסקל VOC 2012 של הכיתובים.