راهنمای تقسیم بندی تصویر برای اندروید

وظیفه MediaPipe Image Segmenter به شما امکان می دهد تصاویر را بر اساس دسته های از پیش تعریف شده برای اعمال جلوه های بصری مانند محو کردن پس زمینه به مناطق تقسیم کنید. این دستورالعمل ها به شما نشان می دهد که چگونه از Image Segmenter با برنامه های Android استفاده کنید. نمونه کد توضیح داده شده در این دستورالعمل ها در GitHub موجود است. برای اطلاعات بیشتر در مورد قابلیت‌ها، مدل‌ها و گزینه‌های پیکربندی این کار، به نمای کلی مراجعه کنید.

نمونه کد

مثال کد MediaPipe Tasks شامل دو پیاده سازی ساده از یک برنامه Image Segmenter برای اندروید است:

نمونه‌ها از دوربین یک دستگاه اندروید فیزیکی برای انجام بخش‌بندی تصویر در فید دوربین زنده استفاده می‌کنند، یا می‌توانید تصاویر و ویدیوها را از گالری دستگاه انتخاب کنید. می‌توانید از برنامه‌ها به‌عنوان نقطه شروع برای برنامه اندرویدی خود استفاده کنید یا هنگام تغییر برنامه موجود به آن‌ها مراجعه کنید. کد نمونه Image Segmenter در GitHub میزبانی می شود.

بخش‌های زیر به بخش‌بندی تصویر با برنامه ماسک دسته‌بندی اشاره دارد.

کد را دانلود کنید

دستورالعمل های زیر به شما نشان می دهد که چگونه با استفاده از ابزار خط فرمان git یک کپی محلی از کد مثال ایجاد کنید.

برای دانلود کد نمونه:

  1. با استفاده از دستور زیر مخزن git را کلون کنید:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. به صورت اختیاری، نمونه git خود را برای استفاده از پرداخت پراکنده پیکربندی کنید، بنابراین فقط فایل‌های برنامه نمونه Image Segmenter را داشته باشید:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_segmentation/android
    

پس از ایجاد یک نسخه محلی از کد نمونه، می توانید پروژه را به اندروید استودیو وارد کرده و برنامه را اجرا کنید. برای دستورالعمل‌ها، به راهنمای راه‌اندازی برای Android مراجعه کنید.

اجزای کلیدی

فایل های زیر حاوی کد حیاتی برای این برنامه نمونه تقسیم بندی تصویر هستند:

  • ImageSegmenterHelper.kt - کار Image Segmenter را راه اندازی می کند و مدل و انتخاب نماینده را مدیریت می کند.
  • CameraFragment.kt - رابط کاربری و کد کنترل دوربین را ارائه می دهد.
  • GalleryFragment.kt - رابط کاربری و کد کنترلی را برای انتخاب فایل های تصویری و ویدئویی ارائه می دهد.
  • OverlayView.kt - نتایج تقسیم‌بندی را مدیریت و قالب‌بندی می‌کند.

برپایی

این بخش مراحل کلیدی را برای راه اندازی محیط توسعه و پروژه های کد برای استفاده از Image Segmenter توضیح می دهد. برای اطلاعات کلی در مورد تنظیم محیط توسعه خود برای استفاده از وظایف MediaPipe، از جمله الزامات نسخه پلت فرم، به راهنمای راه اندازی برای Android مراجعه کنید.

وابستگی ها

Image Segmenter از کتابخانه com.google.mediapipe:tasks-vision استفاده می کند. این وابستگی را به فایل build.gradle پروژه توسعه برنامه اندروید خود اضافه کنید. وابستگی های مورد نیاز را با کد زیر وارد کنید:

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

مدل

وظیفه MediaPipe Image Segmenter به یک مدل آموزش دیده نیاز دارد که با این کار سازگار باشد. برای اطلاعات بیشتر در مورد مدل‌های آموزش‌دیده موجود برای Image Segmenter، بخش مدل‌های نمای کلی کار را ببینید.

مدل را انتخاب و دانلود کنید و سپس آن را در فهرست پروژه خود ذخیره کنید:

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

از متد BaseOptions.Builder.setModelAssetPath() برای تعیین مسیر استفاده شده توسط مدل استفاده کنید. به این روش در مثال کد در قسمت بعدی اشاره شده است.

در کد نمونه Image Segmenter، مدل در کلاس ImageSegmenterHelper.kt در تابع setupImageSegmenter() تعریف شده است.

کار را ایجاد کنید

برای ایجاد کار می توانید از تابع createFromOptions استفاده کنید. تابع createFromOptions گزینه های پیکربندی شامل انواع خروجی ماسک را می پذیرد. برای اطلاعات بیشتر در مورد پیکربندی کار، گزینه های پیکربندی را ببینید.

وظیفه Image Segmenter از انواع داده‌های ورودی زیر پشتیبانی می‌کند: تصاویر ثابت، فایل‌های ویدیویی، و جریان‌های ویدیویی زنده. هنگام ایجاد کار، باید حالت اجرای مربوط به نوع داده ورودی خود را مشخص کنید. برای مشاهده نحوه ایجاد آن کار، برگه را برای نوع داده ورودی خود انتخاب کنید.

تصویر

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)
    

اجرای کد نمونه Image Segmenter به کاربر اجازه می دهد تا بین حالت های پردازش جابجا شود. این رویکرد کد ایجاد کار را پیچیده‌تر می‌کند و ممکن است برای مورد استفاده شما مناسب نباشد. شما می توانید این کد را در کلاس ImageSegmenterHelper توسط تابع setupImageSegmenter() مشاهده کنید.

گزینه های پیکربندی

این کار دارای گزینه های پیکربندی زیر برای برنامه های Android است:

نام گزینه شرح محدوده ارزش مقدار پیش فرض
runningMode حالت اجرا را برای کار تنظیم می کند. سه حالت وجود دارد:

IMAGE: حالت برای ورودی های تک تصویر.

VIDEO: حالت برای فریم های رمزگشایی شده یک ویدیو.

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 تنظیم شده باشد N/A N/A
errorListener یک شنونده خطای اختیاری را تنظیم می کند. N/A تنظیم نشده

داده ها را آماده کنید

Image Segmenter با تصاویر، فایل ویدئویی و پخش زنده ویدئو کار می کند. این وظیفه، پیش پردازش ورودی داده، از جمله تغییر اندازه، چرخش و نرمال سازی مقدار را انجام می دهد.

شما باید تصویر یا فریم ورودی را به یک شی com.google.mediapipe.framework.image.MPImage قبل از ارسال آن به Image Segmenter تبدیل کنید.

تصویر

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

// Load an image on the user’s device as a Bitmap object using BitmapFactory.

// Convert an Android’s Bitmap object to a MediaPipe’s 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 video’s metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them
// to calculate the timestamp of each frame later.

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

// Convert the Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

پخش زنده

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

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

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

در کد نمونه Image Segmenter، آماده سازی داده در کلاس ImageSegmenterHelper توسط تابع segmentLiveStreamFrame() مدیریت می شود.

وظیفه را اجرا کنید

شما یک تابع segment متفاوت را بر اساس حالت در حال اجرا که استفاده می کنید فراخوانی می کنید. تابع Image Segmenter نواحی بخش شناسایی شده را در داخل تصویر یا قاب ورودی برمی گرداند.

تصویر

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

به موارد زیر توجه کنید:

  • هنگام اجرا در حالت ویدیو یا حالت پخش زنده، باید مُهر زمانی فریم ورودی را نیز به وظیفه Image Segmenter ارائه دهید.
  • وقتی در حالت تصویر یا ویدیو اجرا می شود، وظیفه Image Segmenter رشته فعلی را مسدود می کند تا زمانی که پردازش تصویر یا فریم ورودی به پایان برسد. برای جلوگیری از مسدود کردن رابط کاربری، پردازش را در یک رشته پس‌زمینه اجرا کنید.
  • وقتی در حالت پخش زنده اجرا می شود، وظیفه Image Segmenter رشته فعلی را مسدود نمی کند اما بلافاصله برمی گردد. هر بار که پردازش یک فریم ورودی را تمام کند، شنونده نتیجه خود را با نتیجه تشخیص فراخوانی می کند. اگر زمانی که وظیفه Image Segmenter مشغول پردازش فریم دیگری است، تابع segmentAsync فراخوانی شود، این کار فریم ورودی جدید را نادیده می گیرد.

در کد نمونه Image Segmenter، توابع segment در فایل ImageSegmenterHelper.kt تعریف شده اند.

کنترل و نمایش نتایج

پس از اجرای استنتاج، وظیفه Image Segmenter یک شی ImageSegmenterResult را برمی گرداند که حاوی نتایج کار تقسیم بندی است. محتوای خروجی به outputType بستگی دارد که هنگام پیکربندی کار تنظیم کرده اید.

بخش های زیر نمونه هایی از داده های خروجی از این کار را نشان می دهد:

اعتماد به دسته

تصاویر زیر تجسمی از خروجی کار را برای ماسک اطمینان دسته بندی نشان می دهد. خروجی ماسک اطمینان حاوی مقادیر شناور بین [0, 1] است.

خروجی ماسک اطمینان تصویر اصلی و دسته. تصویر منبع از مجموعه داده پاسکال VOC 2012 .

ارزش دسته

تصاویر زیر تصویری از خروجی کار را برای ماسک مقدار دسته نشان می دهد. محدوده ماسک دسته [0, 255] است و هر مقدار پیکسل نشان دهنده شاخص دسته برنده خروجی مدل است. شاخص دسته برنده بالاترین امتیاز را در بین دسته‌هایی دارد که مدل می‌تواند تشخیص دهد.

خروجی ماسک تصویر اصلی و دسته. تصویر منبع از مجموعه داده پاسکال VOC 2012 .