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

این آموزش به شما نشان می دهد که چگونه با استفاده از TensorFlow Lite یک برنامه اندروید بسازید تا به طور مداوم اشیا را در فریم های گرفته شده توسط دوربین دستگاه شناسایی کنید. این اپلیکیشن برای یک دستگاه اندروید فیزیکی طراحی شده است. اگر یک پروژه موجود را به روز می کنید، می توانید از نمونه کد به عنوان مرجع استفاده کنید و به دستورالعمل های اصلاح پروژه خود بروید.

دمو متحرک تشخیص شی

نمای کلی تشخیص شی

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

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

مدل ها و مجموعه داده ها

این آموزش از مدل هایی استفاده می کند که با استفاده از مجموعه داده COCO آموزش داده شده اند. COCO یک مجموعه داده تشخیص اشیا در مقیاس بزرگ است که شامل 330 هزار تصویر، 1.5 میلیون نمونه شی و 80 دسته شی است.

شما می توانید از یکی از مدل های از پیش آموزش دیده زیر استفاده کنید:

  • EfficientDet-Lite0 [توصیه می شود] - یک مدل تشخیص شی سبک وزن با استخراج کننده ویژگی BiFPN، پیش بینی جعبه مشترک و از دست دادن کانونی. mAP (میانگین دقت متوسط) برای مجموعه داده اعتبارسنجی COCO 2017 25.69٪ است.

  • EfficientDet-Lite1 - یک مدل تشخیص شیء EfficientDet با اندازه متوسط. mAP برای مجموعه داده اعتبارسنجی COCO 2017 30.55٪ است.

  • EfficientDet-Lite2 - یک مدل تشخیص اشیاء EfficientDet بزرگتر. mAP برای مجموعه داده اعتبارسنجی COCO 2017 33.97٪ است.

  • MobileNetV1-SSD - یک مدل بسیار سبک وزن که برای کار با TensorFlow Lite برای تشخیص اشیا بهینه شده است. mAP برای مجموعه داده اعتبارسنجی COCO 2017 21٪ است.

برای این آموزش، مدل EfficientDet-Lite0 تعادل خوبی بین اندازه و دقت ایجاد می کند.

دانلود، استخراج و قرار دادن مدل ها در پوشه دارایی ها به طور خودکار توسط فایل download.gradle مدیریت می شود که در زمان ساخت اجرا می شود. شما نیازی به دانلود دستی مدل های TFLite در پروژه ندارید.

راه اندازی و اجرای مثال

برای راه اندازی برنامه تشخیص اشیا، نمونه را از GitHub دانلود کرده و با استفاده از Android Studio اجرا کنید. بخش‌های بعدی این آموزش بخش‌های مربوطه از نمونه کد را بررسی می‌کند، بنابراین می‌توانید آن‌ها را در برنامه‌های اندرویدی خود اعمال کنید.

سیستم مورد نیاز

  • Android Studio نسخه 2021.1.1 (Bumblebee) یا بالاتر.
  • Android SDK نسخه 31 یا بالاتر
  • دستگاه Android با حداقل نسخه سیستم عامل SDK 24 (Android 7.0 - Nougat) با حالت توسعه دهنده فعال است.

کد نمونه را دریافت کنید

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

برای شبیه سازی و تنظیم کد مثال:

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

پروژه را وارد و اجرا کنید

یک پروژه از کد نمونه دانلود شده ایجاد کنید، پروژه را بسازید و سپس آن را اجرا کنید.

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

  1. Android Studio را راه اندازی کنید.
  2. از Android Studio، File > New > Import Project را انتخاب کنید.
  3. به فهرست کد نمونه حاوی فایل build.gradle ( .../examples/lite/examples/object_detection/android/build.gradle ) بروید و آن دایرکتوری را انتخاب کنید.
  4. اگر Android Studio درخواست Gradle Sync کرد، OK را انتخاب کنید.
  5. مطمئن شوید که دستگاه اندرویدی شما به رایانه شما متصل است و حالت توسعه دهنده فعال است. روی فلش سبز Run کلیک کنید.

اگر دایرکتوری صحیح را انتخاب کنید، Android Studio یک پروژه جدید ایجاد می کند و آن را می سازد. این فرآیند بسته به سرعت کامپیوتر شما و اگر از اندروید استودیو برای پروژه های دیگر استفاده کرده اید، ممکن است چند دقیقه طول بکشد. پس از اتمام ساخت، Android Studio یک پیام BUILD SUCCESSFUL را در پانل وضعیت Build Output نمایش می دهد.

اختیاری: برای رفع خطاهای ساخت با به روز رسانی نسخه افزونه اندروید:

  1. فایل build.gradle را در دایرکتوری پروژه باز کنید.
  2. نسخه ابزار اندروید را به صورت زیر تغییر دهید:

    // from: classpath
    'com.android.tools.build:gradle:4.2.2'
    // to: classpath
    'com.android.tools.build:gradle:4.1.2'
    
  3. پروژه را با انتخاب: File > Sync Project with Gradle Files همگام سازی کنید.

برای اجرای پروژه:

  1. از Android Studio، پروژه را با انتخاب Run > Run… اجرا کنید.
  2. برای آزمایش برنامه، یک دستگاه Android متصل با دوربین را انتخاب کنید.

بخش های بعدی تغییراتی را که باید در پروژه موجود خود انجام دهید تا این قابلیت را به برنامه خود اضافه کنید، با استفاده از این برنامه مثال به عنوان نقطه مرجع به شما نشان می دهد.

وابستگی های پروژه را اضافه کنید

در برنامه خود، باید وابستگی‌های پروژه خاصی را برای اجرای مدل‌های یادگیری ماشینی TensorFlow Lite اضافه کنید و به توابع ابزاری دسترسی داشته باشید که داده‌هایی مانند تصاویر را به یک قالب داده تانسور تبدیل می‌کنند که می‌تواند توسط مدلی که استفاده می‌کنید پردازش شود.

برنامه نمونه از کتابخانه وظیفه TensorFlow Lite برای بینایی استفاده می کند تا اجرای مدل یادگیری ماشینی تشخیص اشیا را فعال کند. دستورالعمل‌های زیر نحوه افزودن وابستگی‌های کتابخانه مورد نیاز را به پروژه برنامه Android خود توضیح می‌دهند.

دستورالعمل‌های زیر نحوه افزودن وابستگی‌های پروژه و ماژول مورد نیاز را به پروژه برنامه Android خود توضیح می‌دهند.

برای افزودن وابستگی های ماژول:

  1. در ماژولی که از TensorFlow Lite استفاده می کند، فایل build.gradle ماژول را به روز کنید تا وابستگی های زیر را شامل شود. در کد مثال، این فایل در اینجا قرار دارد: ...examples/lite/examples/object_detection/android/app/build.gradle ( مرجع کد )

    dependencies {
      ...
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.0'
      // Import the GPU delegate plugin Library for GPU inference
      implementation 'org.tensorflow:tensorflow-lite-gpu-delegate-plugin:0.4.0'
      implementation 'org.tensorflow:tensorflow-lite-gpu:2.9.0'
    }
    

    پروژه باید شامل کتابخانه وظایف ویژن ( tensorflow-lite-task-vision ) باشد. کتابخانه واحد پردازش گرافیکی (GPU) ( tensorflow-lite-gpu-delegate-plugin ) زیرساختی را برای اجرای برنامه در GPU فراهم می کند و Delegate ( tensorflow-lite-gpu ) لیست سازگاری را ارائه می دهد.

  2. در Android Studio، وابستگی‌های پروژه را با انتخاب: File > Sync Project with Gradle Files همگام‌سازی کنید.

مدل ML را راه اندازی کنید

در برنامه اندروید خود، باید قبل از اجرای پیش‌بینی‌ها با مدل، مدل یادگیری ماشینی TensorFlow Lite را با پارامترها مقداردهی کنید. این پارامترهای مقداردهی اولیه در بین مدل‌های تشخیص شی سازگار هستند و می‌توانند شامل تنظیماتی مانند حداقل آستانه‌های دقت برای پیش‌بینی‌ها باشند.

یک مدل TensorFlow Lite شامل یک فایل .tflite حاوی کد مدل و اغلب شامل یک فایل برچسب حاوی نام کلاس‌های پیش‌بینی‌شده توسط مدل است. در مورد تشخیص اشیا، کلاس ها اشیایی مانند شخص، سگ، گربه یا ماشین هستند.

این مثال چندین مدل را دانلود می کند که در download_models.gradle مشخص شده اند و کلاس ObjectDetectorHelper یک انتخابگر برای مدل ها ارائه می دهد:

val modelName =
  when (currentModel) {
    MODEL_MOBILENETV1 -> "mobilenetv1.tflite"
    MODEL_EFFICIENTDETV0 -> "efficientdet-lite0.tflite"
    MODEL_EFFICIENTDETV1 -> "efficientdet-lite1.tflite"
    MODEL_EFFICIENTDETV2 -> "efficientdet-lite2.tflite"
    else -> "mobilenetv1.tflite"
  }

برای مقداردهی اولیه مدل در برنامه خود:

  1. یک فایل مدل .tflite به دایرکتوری src/main/assets پروژه توسعه خود اضافه کنید، مانند: EfficientDet-Lite0 .
  2. یک متغیر ثابت برای نام فایل مدل خود تنظیم کنید. در برنامه مثال، برای استفاده از مدل تشخیص EfficientDet-Lite0، متغیر modelName را روی MODEL_EFFICIENTDETV0 تنظیم می کنید.
  3. گزینه‌هایی را برای مدل تنظیم کنید، مانند آستانه پیش‌بینی، اندازه مجموعه نتایج، و در صورت تمایل، نمایندگی‌های شتاب سخت‌افزار:

    val optionsBuilder =
      ObjectDetector.ObjectDetectorOptions.builder()
        .setScoreThreshold(threshold)
        .setMaxResults(maxResults)
    
  4. از تنظیمات این آبجکت برای ساختن یک شیء TensorFlow Lite ObjectDetector استفاده کنید که حاوی مدل است:

    objectDetector =
      ObjectDetector.createFromFileAndOptions(
        context, modelName, optionsBuilder.build())
    

setupObjectDetector پارامترهای مدل زیر را تنظیم می کند:

  • آستانه تشخیص
  • حداکثر تعداد نتایج تشخیص
  • تعداد رشته‌های پردازشی برای استفاده ( BaseOptions.builder().setNumThreads(numThreads) )
  • مدل واقعی ( modelName )
  • ObjectDetector شی ( objectDetector )

پیکربندی شتاب دهنده سخت افزاری

هنگام راه اندازی یک مدل TensorFlow Lite در برنامه خود، می توانید از ویژگی های شتاب سخت افزاری برای سرعت بخشیدن به محاسبات پیش بینی مدل استفاده کنید.

نمایندگان TensorFlow Lite ماژول‌های نرم‌افزاری هستند که اجرای مدل‌های یادگیری ماشین را با استفاده از سخت‌افزار پردازش تخصصی روی یک دستگاه تلفن همراه، مانند واحدهای پردازش گرافیکی (GPU)، واحدهای پردازش تنسور (TPU) و پردازنده‌های سیگنال دیجیتال (DSP) سرعت می‌بخشند. استفاده از نمایندگان برای اجرای مدل‌های TensorFlow Lite توصیه می‌شود، اما الزامی نیست.

آشکارساز شی با استفاده از تنظیمات فعلی روی رشته ای که از آن استفاده می کند مقداردهی اولیه می شود. می‌توانید از نمایندگی‌های CPU و NNAPI با آشکارسازهایی استفاده کنید که روی رشته اصلی ایجاد می‌شوند و در یک رشته پس‌زمینه استفاده می‌شوند، اما رشته‌ای که آشکارساز را مقداردهی اولیه می‌کند باید از نماینده GPU استفاده کند.

نمایندگان در تابع ObjectDetectionHelper.setupObjectDetector() تنظیم می شوند:

when (currentDelegate) {
    DELEGATE_CPU -> {
        // Default
    }
    DELEGATE_GPU -> {
        if (CompatibilityList().isDelegateSupportedOnThisDevice) {
            baseOptionsBuilder.useGpu()
        } else {
            objectDetectorListener?.onError("GPU is not supported on this device")
        }
    }
    DELEGATE_NNAPI -> {
        baseOptionsBuilder.useNnapi()
    }
}

برای اطلاعات بیشتر در مورد استفاده از نمایندگی‌های شتاب سخت‌افزار با TensorFlow Lite، به TensorFlow Lite Delegates مراجعه کنید.

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

در برنامه Android شما، کد شما با تبدیل داده‌های موجود مانند فریم‌های تصویر به قالب داده‌های Tensor که می‌تواند توسط مدل شما پردازش شود، داده‌ها را برای تفسیر در اختیار مدل قرار می‌دهد. داده‌های یک Tensor که به یک مدل منتقل می‌کنید باید ابعاد یا شکل خاصی داشته باشند که با قالب داده‌های مورد استفاده برای آموزش مدل مطابقت داشته باشد.

مدل EfficientDet-Lite0 مورد استفاده در این مثال کد، تانسورهایی را می‌پذیرد که تصاویری با ابعاد 320×320 را با سه کانال (قرمز، آبی و سبز) در هر پیکسل نشان می‌دهند. هر مقدار در تانسور یک بایت بین 0 تا 255 است. بنابراین، برای اجرای پیش‌بینی‌ها روی تصاویر جدید، برنامه شما باید داده‌های تصویر را به اشیاء داده‌های Tensor با آن اندازه و شکل تبدیل کند. TensorFlow Lite Task Library Vision API تغییر داده را برای شما انجام می دهد.

این برنامه از یک شی ImageAnalysis برای بیرون کشیدن تصاویر از دوربین استفاده می کند. این شی تابع detectObject را با bitmap از دوربین فراخوانی می کند. اندازه داده ها به طور خودکار توسط ImageProcessor تغییر اندازه و چرخش می شود تا نیازهای داده تصویر مدل را برآورده کند. سپس تصویر به یک شی TensorImage ترجمه می شود.

برای تهیه داده ها از زیر سیستم دوربین برای پردازش توسط مدل ML:

  1. یک شی ImageAnalysis بسازید تا تصاویر را با فرمت مورد نیاز استخراج کنید:

    imageAnalyzer =
        ImageAnalysis.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            .setTargetRotation(fragmentCameraBinding.viewFinder.display.rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .setOutputImageFormat(OUTPUT_IMAGE_FORMAT_RGBA_8888)
            .build()
            ...
    
  2. تحلیلگر را به زیرسیستم دوربین وصل کنید و یک بافر بیت مپ ایجاد کنید تا حاوی داده های دریافتی از دوربین باشد:

    .also {
      it.setAnalyzer(cameraExecutor) {
        image -> if (!::bitmapBuffer.isInitialized)
        { bitmapBuffer = Bitmap.createBitmap( image.width, image.height,
        Bitmap.Config.ARGB_8888 ) } detectObjects(image)
        }
      }
    
  3. داده های تصویر خاص مورد نیاز مدل را استخراج کنید و اطلاعات چرخش تصویر را ارسال کنید:

    private fun detectObjects(image: ImageProxy) {
      //Copy out RGB bits to the shared bitmap buffer
      image.use {bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer) }
        val imageRotation = image.imageInfo.rotationDegrees
        objectDetectorHelper.detect(bitmapBuffer, imageRotation)
      }
    
  4. همانطور که در روش ObjectDetectorHelper.detect() در برنامه مثال نشان داده شده است، هرگونه تبدیل داده نهایی را تکمیل کنید و داده های تصویر را به یک شی TensorImage اضافه کنید:

    val imageProcessor = ImageProcessor.Builder().add(Rot90Op(-imageRotation / 90)).build()
    // Preprocess the image and convert it into a TensorImage for detection.
    val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
    

پیش بینی ها را اجرا کنید

در برنامه Android خود، هنگامی که یک شی TensorImage با داده‌های تصویر در قالب درست ایجاد کردید، می‌توانید مدل را با آن داده‌ها اجرا کنید تا یک پیش‌بینی یا استنتاج ایجاد کنید.

در کلاس fragments/CameraFragment.kt برنامه مثال، شی imageAnalyzer در تابع bindCameraUseCases به طور خودکار داده‌ها را برای پیش‌بینی به مدل ارسال می‌کند که برنامه به دوربین متصل می‌شود.

این برنامه از روش cameraProvider.bindToLifecycle() برای مدیریت انتخابگر دوربین، پنجره پیش نمایش و پردازش مدل ML استفاده می کند. کلاس ObjectDetectorHelper.kt انتقال داده های تصویر به مدل را کنترل می کند. برای اجرای مدل و ایجاد پیش‌بینی از داده‌های تصویر:

  • پیش بینی را با ارسال داده های تصویر به تابع پیش بینی خود اجرا کنید:

    val results = objectDetector?.detect(tensorImage)
    

شئ TensorFlow Lite Interpreter این داده ها را دریافت می کند، آن را بر اساس مدل اجرا می کند و فهرستی از پیش بینی ها را تولید می کند. برای پردازش مداوم داده ها توسط مدل، از متد runForMultipleInputsOutputs() استفاده کنید تا اشیای Interpreter ایجاد و سپس توسط سیستم برای هر اجرای پیش بینی حذف نشود.

خروجی مدل دسته

در برنامه Android شما، پس از اجرای داده‌های تصویر در برابر مدل تشخیص شی، فهرستی از پیش‌بینی‌ها را تولید می‌کند که کد برنامه شما باید با اجرای منطق تجاری اضافی، نمایش نتایج به کاربر یا انجام اقدامات دیگر انجام دهد.

خروجی هر مدل TensorFlow Lite از نظر تعداد پیش‌بینی‌هایی که تولید می‌کند (یک یا چند)، و اطلاعات توصیفی برای هر پیش‌بینی متفاوت است. در مورد یک مدل تشخیص شی، پیش‌بینی‌ها معمولاً شامل داده‌هایی برای یک کادر محدود می‌شوند که نشان می‌دهد یک شی در کجای تصویر شناسایی شده است. در کد مثال، نتایج به تابع onResults در CameraFragment.kt ارسال می شود که به عنوان DetectorListener در فرآیند تشخیص شی عمل می کند.

interface DetectorListener {
  fun onError(error: String)
  fun onResults(
    results: MutableList<Detection>?,
    inferenceTime: Long,
    imageHeight: Int,
    imageWidth: Int
  )
}

برای مدل مورد استفاده در این مثال، هر پیش‌بینی شامل یک مکان جعبه مرزی برای شی، یک برچسب برای شی، و یک امتیاز پیش‌بینی بین 0 تا 1 به‌عنوان یک شناور است که نشان‌دهنده اطمینان پیش‌بینی است، که 1 بالاترین رتبه اطمینان است. . به طور کلی، پیش‌بینی‌هایی با امتیاز زیر 50 درصد (0.5) غیرقطعی در نظر گرفته می‌شوند. با این حال، نحوه مدیریت نتایج پیش‌بینی کم ارزش به شما و نیازهای برنامه شما بستگی دارد.

برای رسیدگی به نتایج پیش‌بینی مدل:

  1. از یک الگوی شنونده برای ارسال نتایج به کد برنامه یا اشیاء رابط کاربری خود استفاده کنید. برنامه نمونه از این الگو برای ارسال نتایج تشخیص از شی ObjectDetectorHelper به شی CameraFragment استفاده می کند:

    objectDetectorListener.onResults(
    // instance of CameraFragment
        results,
        inferenceTime,
        tensorImage.height,
        tensorImage.width)
    
  2. بر روی نتایج عمل کنید، مانند نمایش پیش بینی به کاربر. مثال برای نمایش نتیجه یک پوشش روی شی CameraPreview می کشد:

    override fun onResults(
      results: MutableList<Detection>?,
      inferenceTime: Long,
      imageHeight: Int,
      imageWidth: Int
    ) {
        activity?.runOnUiThread {
            fragmentCameraBinding.bottomSheetLayout.inferenceTimeVal.text =
                String.format("%d ms", inferenceTime)
    
            // Pass necessary information to OverlayView for drawing on the canvas
            fragmentCameraBinding.overlay.setResults(
                results ?: LinkedList<Detection>(),
                imageHeight,
                imageWidth
            )
    
            // Force a redraw
            fragmentCameraBinding.overlay.invalidate()
        }
    }
    

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

مراحل بعدی

  • کاربردهای مختلف TensorFlow Lite را در مثال‌ها کاوش کنید.
  • در مورد استفاده از مدل‌های یادگیری ماشین با TensorFlow Lite در بخش Models بیشتر بیاموزید.
  • در راهنمای برنامه‌نویس TensorFlow Lite درباره پیاده‌سازی یادگیری ماشین در برنامه تلفن همراه خود بیشتر بیاموزید.