Deteksi objek dengan Android

Tutorial ini menunjukkan cara membuat aplikasi Android menggunakan TensorFlow Lite untuk terus mendeteksi objek dalam bingkai yang diambil oleh kamera perangkat. Aplikasi ini dirancang untuk perangkat Android fisik. Jika Anda memperbarui proyek yang sudah ada, Anda dapat menggunakan contoh kode sebagai referensi dan langsung beralih ke petunjuk untuk memodifikasi proyek Anda .

Demo animasi deteksi objek

Ikhtisar deteksi objek

Deteksi objek adalah tugas pembelajaran mesin untuk mengidentifikasi keberadaan dan lokasi beberapa kelas objek dalam suatu gambar. Model deteksi objek dilatih pada kumpulan data yang berisi sekumpulan objek yang diketahui.

Model yang dilatih menerima bingkai gambar sebagai masukan dan mencoba mengkategorikan item dalam gambar dari kumpulan kelas yang diketahui yang telah dilatih untuk dikenali. Untuk setiap bingkai gambar, model deteksi objek mengeluarkan daftar objek yang dideteksinya, lokasi kotak pembatas untuk setiap objek, dan skor yang menunjukkan keyakinan objek tersebut diklasifikasikan dengan benar.

Model dan kumpulan data

Tutorial ini menggunakan model yang dilatih menggunakan dataset COCO . COCO adalah kumpulan data deteksi objek berskala besar yang berisi 330 ribu gambar, 1,5 juta instance objek, dan 80 kategori objek.

Anda memiliki opsi untuk menggunakan salah satu model terlatih berikut:

  • EfficientDet-Lite0 [Direkomendasikan] - model deteksi objek ringan dengan ekstraktor fitur BiFPN, prediktor kotak bersama, dan kehilangan fokus. MAP (mean Average Precision) dataset validasi COCO 2017 adalah 25,69%.

  • EfficientDet-Lite1 - model deteksi objek EfficientDet berukuran sedang. MAP dataset validasi COCO 2017 adalah 30,55%.

  • EfficientDet-Lite2 - model deteksi objek EfficientDet yang lebih besar. MAP dataset validasi COCO 2017 adalah 33,97%.

  • MobileNetV1-SSD - model sangat ringan yang dioptimalkan agar berfungsi dengan TensorFlow Lite untuk deteksi objek. MAP dataset validasi COCO 2017 adalah 21%.

Untuk tutorial ini, model EfficientDet-Lite0 memberikan keseimbangan yang baik antara ukuran dan akurasi.

Pengunduhan, ekstraksi, dan penempatan model ke dalam folder aset dikelola secara otomatis oleh file download.gradle , yang dijalankan pada waktu pembuatan. Anda tidak perlu mengunduh model TFLite secara manual ke dalam proyek.

Siapkan dan jalankan contoh

Untuk menyiapkan aplikasi pendeteksi objek, unduh sampel dari GitHub dan jalankan menggunakan Android Studio . Bagian berikut dari tutorial ini mengeksplorasi bagian contoh kode yang relevan, sehingga Anda dapat menerapkannya ke aplikasi Android Anda sendiri.

Persyaratan sistem

  • Android Studio versi 2021.1.1 (Bumblebee) atau lebih tinggi.
  • Android SDK versi 31 atau lebih tinggi
  • Perangkat Android dengan versi OS minimum SDK 24 (Android 7.0 - Nougat) dengan mode pengembang diaktifkan.

Dapatkan kode contoh

Buat salinan lokal dari kode contoh. Anda akan menggunakan kode ini untuk membuat proyek di Android Studio dan menjalankan aplikasi contoh.

Untuk mengkloning dan mengatur kode contoh:

  1. Kloning repositori git
    git clone https://github.com/tensorflow/examples.git
    
  2. Secara opsional, konfigurasikan instance git Anda untuk menggunakan checkout jarang, sehingga Anda hanya memiliki file untuk aplikasi contoh deteksi objek:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/object_detection/android
    

Impor dan jalankan proyek

Buat proyek dari kode contoh yang diunduh, buat proyek, lalu jalankan.

Untuk mengimpor dan membuat proyek kode contoh:

  1. Mulai Android Studio .
  2. Dari Android Studio, pilih File > New > Import Project .
  3. Navigasikan ke direktori kode contoh yang berisi file build.gradle ( .../examples/lite/examples/object_detection/android/build.gradle ) dan pilih direktori tersebut.
  4. Jika Android Studio meminta Sinkronisasi Gradle, pilih OK.
  5. Pastikan perangkat Android Anda terhubung ke komputer dan mode pengembang diaktifkan. Klik panah Run yang berwarna hijau.

Jika Anda memilih direktori yang benar, Android Studio akan membuat proyek baru dan membangunnya. Proses ini dapat memakan waktu beberapa menit, bergantung pada kecepatan komputer Anda dan apakah Anda pernah menggunakan Android Studio untuk proyek lain. Saat build selesai, Android Studio menampilkan pesan BUILD SUCCESSFUL di panel status Build Output .

Opsional: Untuk memperbaiki error build dengan memperbarui versi plugin Android:

  1. Buka file build.gradle di direktori proyek.
  2. Ubah versi alat Android sebagai berikut:

    // from: classpath
    'com.android.tools.build:gradle:4.2.2'
    // to: classpath
    'com.android.tools.build:gradle:4.1.2'
    
  3. Sinkronkan proyek dengan memilih: File > Sync Project with Gradle Files .

Untuk menjalankan proyek:

  1. Dari Android Studio, jalankan proyek dengan memilih Run > Run… .
  2. Pilih perangkat Android yang terpasang dengan kamera untuk menguji aplikasi.

Bagian selanjutnya menunjukkan modifikasi yang perlu Anda lakukan pada proyek yang ada untuk menambahkan fungsi ini ke aplikasi Anda sendiri, menggunakan contoh aplikasi ini sebagai titik referensi.

Tambahkan dependensi proyek

Dalam aplikasi Anda sendiri, Anda harus menambahkan dependensi proyek tertentu untuk menjalankan model pembelajaran mesin TensorFlow Lite, dan mengakses fungsi utilitas yang mengonversi data seperti gambar, menjadi format data tensor yang dapat diproses oleh model yang Anda gunakan.

Aplikasi contoh menggunakan pustaka Tugas TensorFlow Lite untuk vision guna mengaktifkan eksekusi model pembelajaran mesin deteksi objek. Petunjuk berikut menjelaskan cara menambahkan dependensi perpustakaan yang diperlukan ke proyek aplikasi Android Anda sendiri.

Petunjuk berikut menjelaskan cara menambahkan dependensi proyek dan modul yang diperlukan ke proyek aplikasi Android Anda sendiri.

Untuk menambahkan dependensi modul:

  1. Pada modul yang menggunakan TensorFlow Lite, perbarui file build.gradle modul untuk menyertakan dependensi berikut. Dalam kode contoh, file ini terletak di sini: ...examples/lite/examples/object_detection/android/app/build.gradle ( referensi kode )

    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'
    }
    

    Proyek harus menyertakan pustaka tugas Vision ( tensorflow-lite-task-vision ). Pustaka unit pemrosesan grafis (GPU) ( tensorflow-lite-gpu-delegate-plugin ) menyediakan infrastruktur untuk menjalankan aplikasi di GPU, dan Delegate ( tensorflow-lite-gpu ) menyediakan daftar kompatibilitas.

  2. Di Android Studio, sinkronkan dependensi proyek dengan memilih: File > Sync Project with Gradle Files .

Inisialisasi model ML

Di aplikasi Android, Anda harus menginisialisasi model machine learning TensorFlow Lite dengan parameter sebelum menjalankan prediksi dengan model tersebut. Parameter inisialisasi ini konsisten di seluruh model deteksi objek dan dapat mencakup pengaturan seperti ambang akurasi minimum untuk prediksi.

Model TensorFlow Lite menyertakan file .tflite yang berisi kode model dan sering kali menyertakan file label yang berisi nama kelas yang diprediksi oleh model. Dalam kasus deteksi objek, kelas adalah objek seperti orang, anjing, kucing, atau mobil.

Contoh ini mengunduh beberapa model yang ditentukan dalam download_models.gradle , dan kelas ObjectDetectorHelper menyediakan pemilih untuk model tersebut:

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"
  }

Untuk menginisialisasi model di aplikasi Anda:

  1. Tambahkan file model .tflite ke direktori src/main/assets proyek pengembangan Anda, seperti: EfficientDet-Lite0 .
  2. Tetapkan variabel statis untuk nama file model Anda. Di aplikasi contoh, Anda menyetel variabel modelName ke MODEL_EFFICIENTDETV0 untuk menggunakan model deteksi EfficientDet-Lite0.
  3. Tetapkan opsi untuk model, seperti ambang batas prediksi, ukuran kumpulan hasil, dan opsional, delegasi akselerasi perangkat keras:

    val optionsBuilder =
      ObjectDetector.ObjectDetectorOptions.builder()
        .setScoreThreshold(threshold)
        .setMaxResults(maxResults)
    
  4. Gunakan pengaturan dari objek ini untuk membuat objek TensorFlow Lite ObjectDetector yang berisi model:

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

setupObjectDetector menyiapkan parameter model berikut:

  • Ambang batas deteksi
  • Jumlah maksimum hasil deteksi
  • Jumlah thread pemrosesan yang akan digunakan ( BaseOptions.builder().setNumThreads(numThreads) )
  • Model sebenarnya ( modelName )
  • Objek ObjectDetector ( objectDetector )

Konfigurasikan akselerator perangkat keras

Saat menginisialisasi model TensorFlow Lite di aplikasi, Anda dapat menggunakan fitur akselerasi perangkat keras untuk mempercepat penghitungan prediksi model.

Delegasi TensorFlow Lite adalah modul perangkat lunak yang mempercepat eksekusi model pembelajaran mesin menggunakan perangkat keras pemrosesan khusus pada perangkat seluler, seperti Graphics Processing Units (GPUs), Tensor Processing Units (TPUs), dan Digital Signal Processors (DSPs). Disarankan untuk menggunakan delegasi untuk menjalankan model TensorFlow Lite, tetapi tidak wajib.

Detektor objek diinisialisasi menggunakan pengaturan saat ini pada thread yang menggunakannya. Anda dapat menggunakan delegasi CPU dan NNAPI dengan detektor yang dibuat pada thread utama dan digunakan pada thread latar belakang, namun thread yang menginisialisasi detektor harus menggunakan delegasi GPU.

Delegasi diatur dalam fungsi 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()
    }
}

Untuk informasi selengkapnya tentang penggunaan delegasi akselerasi perangkat keras dengan TensorFlow Lite, lihat Delegasi TensorFlow Lite .

Siapkan data untuk model

Di aplikasi Android, kode Anda menyediakan data ke model untuk diinterpretasikan dengan mengubah data yang ada seperti bingkai gambar menjadi format data Tensor yang dapat diproses oleh model Anda. Data di Tensor yang Anda teruskan ke model harus memiliki dimensi atau bentuk tertentu yang cocok dengan format data yang digunakan untuk melatih model.

Model EfficientDet-Lite0 yang digunakan dalam contoh kode ini menerima Tensor yang mewakili gambar dengan dimensi 320 x 320, dengan tiga saluran (merah, biru, dan hijau) per piksel. Setiap nilai dalam tensor adalah satu byte antara 0 dan 255. Jadi, untuk menjalankan prediksi pada gambar baru, aplikasi Anda harus mengubah data gambar tersebut menjadi objek data Tensor dengan ukuran dan bentuk tersebut. TensorFlow Lite Task Library Vision API menangani transformasi data untuk Anda.

Aplikasi ini menggunakan objek ImageAnalysis untuk mengambil gambar dari kamera. Objek ini memanggil fungsi detectObject dengan bitmap dari kamera. Data secara otomatis diubah ukurannya dan diputar oleh ImageProcessor sehingga memenuhi persyaratan data gambar model. Gambar tersebut kemudian diterjemahkan ke dalam objek TensorImage .

Untuk menyiapkan data dari subsistem kamera untuk diproses oleh model ML:

  1. Bangun objek ImageAnalysis untuk mengekstrak gambar dalam format yang diperlukan:

    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. Hubungkan penganalisis ke subsistem kamera dan buat buffer bitmap untuk menampung data yang diterima dari kamera:

    .also {
      it.setAnalyzer(cameraExecutor) {
        image -> if (!::bitmapBuffer.isInitialized)
        { bitmapBuffer = Bitmap.createBitmap( image.width, image.height,
        Bitmap.Config.ARGB_8888 ) } detectObjects(image)
        }
      }
    
  3. Ekstrak data gambar spesifik yang diperlukan oleh model, dan teruskan informasi rotasi gambar:

    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. Selesaikan semua transformasi data akhir dan tambahkan data gambar ke objek TensorImage , seperti yang ditunjukkan dalam metode ObjectDetectorHelper.detect() pada aplikasi contoh:

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

Jalankan prediksi

Di aplikasi Android, setelah membuat objek TensorImage dengan data gambar dalam format yang benar, Anda dapat menjalankan model terhadap data tersebut untuk menghasilkan prediksi atau inferensi .

Di kelas fragments/CameraFragment.kt aplikasi contoh, objek imageAnalyzer dalam fungsi bindCameraUseCases secara otomatis meneruskan data ke model untuk prediksi ketika aplikasi terhubung ke kamera.

Aplikasi ini menggunakan metode cameraProvider.bindToLifecycle() untuk menangani pemilih kamera, jendela pratinjau, dan pemrosesan model ML. Kelas ObjectDetectorHelper.kt menangani penerusan data gambar ke dalam model. Untuk menjalankan model dan menghasilkan prediksi dari data gambar:

  • Jalankan prediksi dengan meneruskan data gambar ke fungsi prediksi Anda:

    val results = objectDetector?.detect(tensorImage)
    

Objek TensorFlow Lite Interpreter menerima data ini, menjalankannya terhadap model, dan menghasilkan daftar prediksi. Untuk pemrosesan data yang berkelanjutan oleh model, gunakan metode runForMultipleInputsOutputs() sehingga objek Interpreter tidak dibuat dan kemudian dihapus oleh sistem untuk setiap prediksi yang dijalankan.

Menangani keluaran model

Di aplikasi Android, setelah Anda menjalankan data gambar terhadap model deteksi objek, ini akan menghasilkan daftar prediksi yang harus ditangani oleh kode aplikasi Anda dengan menjalankan logika bisnis tambahan, menampilkan hasil kepada pengguna, atau mengambil tindakan lainnya.

Output dari setiap model TensorFlow Lite bervariasi dalam hal jumlah prediksi yang dihasilkan (satu atau banyak), dan informasi deskriptif untuk setiap prediksi. Dalam kasus model deteksi objek, prediksi biasanya menyertakan data untuk kotak pembatas yang menunjukkan lokasi objek terdeteksi dalam gambar. Dalam kode contoh, hasilnya diteruskan ke fungsi onResults di CameraFragment.kt , yang bertindak sebagai DetectorListener pada proses pendeteksian objek.

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

Untuk model yang digunakan dalam contoh ini, setiap prediksi mencakup lokasi kotak pembatas objek, label objek, dan skor prediksi antara 0 dan 1 sebagai Float yang mewakili keyakinan prediksi, dengan 1 sebagai peringkat keyakinan tertinggi . Secara umum, prediksi dengan skor di bawah 50% (0,5) dianggap tidak meyakinkan. Namun, cara Anda menangani hasil prediksi bernilai rendah terserah Anda dan kebutuhan aplikasi Anda.

Untuk menangani hasil prediksi model:

  1. Gunakan pola pendengar untuk meneruskan hasil ke kode aplikasi atau objek antarmuka pengguna Anda. Contoh aplikasi menggunakan pola ini untuk meneruskan hasil deteksi dari objek ObjectDetectorHelper ke objek CameraFragment :

    objectDetectorListener.onResults(
    // instance of CameraFragment
        results,
        inferenceTime,
        tensorImage.height,
        tensorImage.width)
    
  2. Bertindak berdasarkan hasilnya, seperti menampilkan prediksi kepada pengguna. Contoh menggambar overlay pada objek CameraPreview untuk memperlihatkan hasilnya:

    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()
        }
    }
    

Setelah model mengembalikan hasil prediksi, aplikasi Anda dapat bertindak berdasarkan prediksi tersebut dengan menyajikan hasilnya kepada pengguna atau mengeksekusi logika tambahan. Dalam kasus kode contoh, aplikasi menggambar kotak pembatas di sekitar objek yang diidentifikasi dan menampilkan nama kelas di layar.

Langkah selanjutnya

  • Jelajahi berbagai kegunaan TensorFlow Lite dalam contoh .
  • Pelajari lebih lanjut cara menggunakan model machine learning dengan TensorFlow Lite di bagian Model .
  • Pelajari lebih lanjut cara menerapkan pembelajaran mesin di aplikasi seluler Anda di Panduan Pengembang TensorFlow Lite .