راهنمای تشخیص اشیا برای اندروید

وظیفه آشکارساز شی به شما امکان می دهد حضور و مکان چندین کلاس از اشیاء را تشخیص دهید. به عنوان مثال، یک آشکارساز شی می تواند سگ ها را در یک تصویر پیدا کند. این دستورالعمل به شما نشان می دهد که چگونه از وظیفه آشکارساز شی در اندروید استفاده کنید. نمونه کد شرح داده شده در این دستورالعمل ها در GitHub موجود است. شما می توانید با مشاهده این نسخه نمایشی وب، این کار را در عمل مشاهده کنید. برای اطلاعات بیشتر در مورد قابلیت‌ها، مدل‌ها و گزینه‌های پیکربندی این کار، به نمای کلی مراجعه کنید.

نمونه کد

کد مثال MediaPipe Tasks یک پیاده سازی ساده از یک برنامه Object Detector برای اندروید است. این مثال از دوربین یک دستگاه اندروید فیزیکی برای شناسایی مداوم اشیا استفاده می‌کند و همچنین می‌تواند از تصاویر و ویدیوهای گالری دستگاه برای شناسایی استاتیک اشیا استفاده کند.

می‌توانید از برنامه به‌عنوان نقطه شروع برای برنامه اندرویدی خود استفاده کنید یا هنگام تغییر برنامه موجود به آن مراجعه کنید. کد نمونه Object Detector در GitHub میزبانی می شود.

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

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

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

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

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

اجزای کلیدی

فایل های زیر حاوی کد حیاتی برای مثال برنامه Object Detector هستند:

  • ObjectDetectorHelper.kt - آشکارساز شی را راه اندازی می کند و مدل و انتخاب نماینده را مدیریت می کند.
  • MainActivity.kt - برنامه را پیاده سازی می کند و اجزای رابط کاربری را مونتاژ می کند
  • OverlayView.kt - نتایج را کنترل و نمایش می دهد

راه اندازی

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

وابستگی ها

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

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

مدل

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

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

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

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

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

برای ایجاد کار می توانید از تابع createFromOptions استفاده کنید. تابع createFromOptions گزینه‌های پیکربندی شامل حالت اجرا، محل نام‌های نمایشی، حداکثر تعداد نتایج، آستانه اطمینان، لیست مجاز دسته‌ها و فهرست رد را می‌پذیرد. اگر یک گزینه پیکربندی مشخص نشده باشد، از مقدار پیش فرض استفاده می شود. برای اطلاعات بیشتر در مورد گزینه های پیکربندی، به نمای کلی پیکربندی مراجعه کنید.

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

تصویر

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

ویدئو

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

پخش زنده

ObjectDetectorOptions options =
  ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder().setModelAssetPath(‘model.tflite’).build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
      // Process the detection result here.
    })
    .setErrorListener((result, inputImage) -> {
      // Process the classification errors here.
    })
   .build();
objectDetector = ObjectDetector.createFromOptions(context, options);
    

اجرای کد مثالی Object Detector به کاربر اجازه می دهد تا بین حالت های پردازش جابجا شود. این رویکرد کد ایجاد کار را پیچیده‌تر می‌کند و ممکن است برای مورد استفاده شما مناسب نباشد. می توانید این کد را در تابع کلاس ObjectDetectorHelper setupObjectDetector() مشاهده کنید.

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

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

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

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

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

LIVE_STREAM: حالت پخش زنده داده های ورودی، مانند دوربین. در این حالت، resultListener باید فراخوانی شود تا شنونده ای را برای دریافت نتایج به صورت ناهمزمان تنظیم کند.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
displayNamesLocales زبان برچسب‌ها را برای استفاده برای نام‌های نمایشی ارائه شده در فراداده مدل کار، در صورت وجود، تنظیم می‌کند. پیش فرض برای انگلیسی en است. با استفاده از TensorFlow Lite Metadata Writer API می‌توانید برچسب‌های محلی را به ابرداده یک مدل سفارشی اضافه کنید. کد محلی en
maxResults حداکثر تعداد اختیاری نتایج تشخیص با امتیاز بالا را برای بازگشت تنظیم می کند. هر عدد مثبت -1 (همه نتایج برگردانده می شوند)
scoreThreshold آستانه امتیاز پیش‌بینی را تنظیم می‌کند که بر آستانه ارائه‌شده در فراداده مدل (در صورت وجود) لغو می‌شود. نتایج زیر این مقدار رد می شوند. هر شناور تنظیم نشده است
categoryAllowlist فهرست اختیاری نام‌های دسته‌بندی مجاز را تنظیم می‌کند. اگر خالی نباشد، نتایج تشخیصی که نام دسته آنها در این مجموعه نیست فیلتر می‌شوند. نام‌های دسته‌بندی تکراری یا ناشناخته نادیده گرفته می‌شوند. این گزینه با categoryDenylist منحصر به فرد است و از هر دو نتیجه در یک خطا استفاده می کند. هر رشته تنظیم نشده است
categoryDenylist فهرست اختیاری نام‌های دسته‌هایی را که مجاز نیستند را تنظیم می‌کند. اگر خالی نباشد، نتایج تشخیصی که نام دسته آنها در این مجموعه است فیلتر می‌شوند. نام‌های دسته‌بندی تکراری یا ناشناخته نادیده گرفته می‌شوند. این گزینه با categoryAllowlist منحصر به فرد است و از هر دو نتیجه در خطا استفاده می کند. هر رشته تنظیم نشده است
resultListener شنونده نتیجه را طوری تنظیم می کند که وقتی آشکارساز شی در حالت پخش زنده است، نتایج تشخیص را به صورت ناهمزمان دریافت کند. فقط زمانی می توانید از این گزینه استفاده کنید که runMode را روی LIVE_STREAM تنظیم کنید. قابل اجرا نیست تنظیم نشده است

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

قبل از ارسال آن به Object Detector باید تصویر یا قاب ورودی را به یک شی 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 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 values. Use these values
// 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()
MPImage mpImage = new MediaImageBuilder(mediaImage).build();
    

در کد نمونه Object Detector، آماده سازی داده در کلاس ObjectDetectorHelper در توابع detectImage() , detectVideoFile() , detectLivestreamFrame() انجام می شود.

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

بسته به نوع داده ای که با آن کار می کنید، از متد ObjectDetector.detect...() که مخصوص آن نوع داده است استفاده کنید. از detect() برای تصاویر جداگانه، detectForVideo() برای فریم در فایل های ویدئویی و detectAsync() برای جریان های ویدئویی استفاده کنید. هنگامی که در یک جریان ویدیویی شناسایی می‌کنید، مطمئن شوید که تشخیص‌ها را در یک رشته جداگانه اجرا می‌کنید تا از مسدود کردن رشته رابط کاربری جلوگیری کنید.

نمونه‌های کد زیر نمونه‌های ساده‌ای از نحوه اجرای Object Detector در این حالت‌های مختلف داده را نشان می‌دهند:

تصویر

ObjectDetectorResult detectionResult = objectDetector.detect(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.
ObjectDetectorResult detectionResult =
    objectDetector.detectForVideo(image, frameTimestampMs);
    

پخش زنده

// Run inference on the frame. The detection results will be available
// via the `resultListener` provided in the `ObjectDetectorOptions` when
// the object detector was created.
objectDetector.detectAsync(image, frameTimestampMs);
    

مثال کد Object Detector پیاده سازی هر یک از این حالت ها را با جزئیات بیشتر detect() ، detectVideoFile() و detectAsync() نشان می دهد. کد مثال به کاربر اجازه می دهد تا بین حالت های پردازشی که ممکن است برای مورد استفاده شما مورد نیاز نباشد جابجا شود.

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

  • هنگام اجرا در حالت ویدئو یا حالت پخش زنده، باید مهر زمانی فریم ورودی را نیز به وظیفه آشکارساز شی ارائه دهید.
  • هنگامی که در حالت تصویر یا ویدیو اجرا می شود، وظیفه آشکارساز شی، رشته فعلی را مسدود می کند تا زمانی که پردازش تصویر یا فریم ورودی به پایان برسد. برای جلوگیری از مسدود کردن رشته فعلی، پردازش را در یک موضوع پس‌زمینه اجرا کنید.
  • هنگامی که در حالت پخش زنده اجرا می شود، وظیفه آشکارساز شی موضوع فعلی را مسدود نمی کند، اما بلافاصله برمی گردد. هر بار که پردازش یک فریم ورودی را تمام کند، شنونده نتیجه خود را با نتیجه تشخیص فراخوانی می کند. اگر زمانی که وظیفه آشکارساز شی مشغول پردازش فریم دیگری است، تابع تشخیص فراخوانی شود، فریم ورودی جدید نادیده گرفته می شود.

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

پس از اجرای استنتاج، وظیفه آشکارساز شی یک شی ObjectDetectorResult را برمی گرداند که اشیایی را که در تصویر ورودی پیدا کرده است، توصیف می کند.

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

ObjectDetectorResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : dog
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : dog

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

کد مثالی Object Detector نحوه نمایش نتایج تشخیص برگشتی از کار را نشان می دهد، برای جزئیات بیشتر به کلاس OverlayView مراجعه کنید.