Membuat Sistem Live Object Detection di Swift 5

Cara membuat Aplikasi iOS dengan sistem Live Object Detection menggunakan YOLOv3 dan Vision di Swift 5

Auriga Aristo
Dipantry
6 min readNov 6, 2020

--

Sejak saat pertama kali dirilis, machine learning object detection menjadi perhatian dunia. Semua orang ingin mengimplementasikannya ke dalam proyek milik sendiri. Namun, banyak orang bertanya-tanya bagaimana bisa sebuah machine learning melakukan banyak image classification pada banyak obyek. Biasanya sebuah image classification akan mengeluarkan nama obyek berdasarkan nilai confidence tertinggi pada sebuah gambar.

Berbeda dengan image classification, sebuah gambar akan di-scan, lalu machine learning akan membaca setiap obyek bisa dikenali. Setelah itu, mesin akan mengembalikan nama, posisi, dan tingkat confidence. Lalu, aplikasi bisa menciptakan gambar kotak dan pemberian label.

Dalam aplikasi ini, kita akan menerapkan machine learning model yang paling terkenal, yaitu YOLO. Model ini berbasis python, namun Apple telah menyediakan dalam bentuk mlmodel pada websitenya. YOLO menyediakan 2 jenis model, yaitu YOLOv3 dan YOLOv3-Tiny. YOLOv3-Tiny berukuran lebih kecil dibanding model biasa, namun masih digunakan untuk machine learning. Sedangkan model YOLOv3 memang berukuran lebih besar, namun model tersebut bisa memprediksi benda-benda kecil secara akurat.

Download YOLOv3 di sini : Apple Developer Machine Learning Model

Berikut adalah tampilan proyek yang akan dikerjakan dengan YOLOv3:

Setup Environment

Buat project baru dan masukkan mlmodel ke dalam project kalian. Selanjutnya, kita akan mendesain aplikasi. Berbeda dengan sistem image classification yang akan memberikan hasil sebuah kata dan bisa ditampilkan melalui sebuah label, sistem object detection akan membuat kotak di posisi manapun dan warna yang berbeda. Tidak ada kepastian posisi hasil yang akan ditampilkan. Maka dari itu, kita buat 2 buah UIView yang berbeda, 1 digunakan untuk menampilkan video dan 1 lagi digunakan untuk menampilkan hasil machine learning.

Untuk pemberian warna, it’s up to you. Namun, untuk boxPreview kita beri background color berwarna “Clear color”. Apabila kamu melihat, boxPreview memiliki tipe data BoundingBoxView. Sebenarnya tipe data ini sama saja dengan UIView namun, kita akan membuat fungsi lain agar bisa rendering tampilan box berwarna-warni seperti contoh di atas.

Satu hal yang kalian tidak boleh lupa, kita akan menggunakan sistem kamera, maka kita akan memasang permission pada info.plist. Permission yang harus dipasang bernama Privacy — Camera Usage Description.

Video Handler

Selanjutnya, kita membuat sebuah sistem video pada UIView yang akan mengambil gambar dengan FPS tertentu, dimana pada setiap frame, gambar akan di-capture lalu dilemparkan kepada machine learning untuk diprediksi.

Pertama, mari kita buat sebuah class dengan nama VideoHandler yang akan mengimplentasikan NSObject agar sistem menganggap class ini sebagai sebuah object. Lalu, kita ubah import menjadi yang kita butuhkan, yaitu AVFoundation (library yang bertanggung jawab atas pengambilan video atau penggunaan kamera). Class ini akan berkomunikasi dengan ViewController menggunakan sebuah delegate yang akan kita buat, yaitu VideoHandlerDelegate yang berfungsi untuk melempar foto untuk diprediksi.

Sebelum melanjutkan, mari kita berpikir logika aplikasi ini terlebih dahulu. Contoh, pada setiap gambar diambil (50 FPS, 1 Frame = 20ms), gambar akan dilempar ke ViewController. ML Object Detection butuh waktu sekitar 40–80 ms untuk memproses gambar (YOLOv3 80ms, YOLOv3-Tiny 40ms). Apabila gambar yang diambil terlalu cepat, maka aplikasi akan terlalu sibuk untuk memprediksi tanpa henti dan proses akan bertubrukan satu sama lain. Maka dari itu, kita akan memerlukan sebuah antrian untuk menyimpan data gambar yang akan dilempar. Setiap item dalam queue akan dihapus setelah gambar masuk dalam proses ML. Queue yang akan kita gunakan adalah DispatchQueue. Silahkan untuk memberi label pada DispatchQueue sesuai dengan Bundle Identifiermu.

Selanjutnya, kita akan memasang pengaturan kamera serta method memulai dan berhenti menggunakan kamera agar bisa digunakan oleh controller utama. Pada tutorial ini, saya akan memberikan contoh pengaturannya, namun kalian boleh menggantinya sesuai dengan keinginan kalian.

Ada 2 pengaturan yang sangat mempengaruhi performa aplikasi. Pertama, pada baris 5, kalian bisa mengatur jumlah FPS, lalu yang kedua, pada baris 14, kalian bisa mengatur resolusi gambar yang digunakan. Kedua pengaturan ini merupakan pengaturan default, kamu masih bisa mengubahnya melalui viewcontroller. Perlu diketahui, Machine Learning tidak membutuhkan resolusi tinggi untuk memprediksi gambar sehingga pada contoh di atas, saya menggunakan resolusi 640 x 480 dengan orientasi potrait (baris 41). Preview layer di sini berfungsi sebagai penampil video pada tampilan utama.

Setelah membuat pengaturan utama, selanjutnya adalah apa yang harus dilakukan VideoHandler apabila berhasil atau gagal ketika mengambil video. Hal ini dipertanggungjawabkan oleh sebuah delegate yang bernama AVCaptureVideoDataOutputSampleBufferDelegate yang dilengkapi oleh 2 buah method dengan kata kunci didOutput (berhasil) dan didDrop (gagal). Untuk contoh ini kita hanya akan menggunakan method didOutput untuk melempar data menggunakan VideoHandlerDelegate.

BoundingBoxView

Setelah mengatur VideoHandler dan sebelum kita masuk ke dalam ViewController, mari kita atur BoundingBoxView atau tampilan yang akan bertanggung jawab atas kotak warna-warni.

Konsep yang biasa dimiliki pada program object detection adalah setiap obyek yang sama akan berwarna sama. Apabila kamu melihat kembali pada gambar yang pertama kali muncul di artikel ini, obyek mobil (car) akan berwarna kuning dan obyek orang (person) akan berwarna pink. Maka dari itu, kita akan membuat array untuk menyimpanan data warna berdasarkan label.

Lalu, kita akan membuat label dan box berdasarkan hasil yang dikirimkan dari ViewController (nantinya). Hasil prediksi akan bertipe data array yang berisikan VNRecognizedObjectObservation, lalu pada setiap hasil observasi, sistem akan membuat label dan box menggunakan CGRect. Tampilan tersebut akan dibuat secara programmatically karena tidak memungkinkan untuk melakukan koding karena ukuran, posisi, warna, dan isi label sangat bergantung pada hasil ML.

Pada baris 24–28, kita membuat UIView sebagai box yang akan ditampilkan, sedangkan pada baris 30–37, kita membuat UILabel sebagai teks hasil prediksi. Kamu bisa mengubah pengaturan di atas sesuai dengan keinginanmu.

Sedikit pengaturan ditambahkan sebagai extension dari VNRecognizedObjectObservation, setiap label yang diambil dari class tersebut akan selalu mengambil nilai identifier dengan confidence tertinggi.

ViewController

Setelah membuat VideoHandler dan BoundingBoxView, kita siap untuk membuat sistem machine learning dan menampilkannya kepada pengguna. Pertama, kita buat sebuah global variable dengan nama objectDetectionModel untuk bertanggung jawab atas menyimpan model. Pada contoh ini, saya menggunakan YOLOv3.

private let objectDetectionModel = try! YOLOv3(configuration: .init())

Jika kamu menggunakan mlmodel lain, kamu hanya perlu mengganti nama class-nya.

Selanjutnya kita akan mengatur sistem VideoHandler. Ketika tampilan akan muncul atau viewWillAppear, maka pengambilan video akan dimulai atau .start(). Sebaliknya, ketia tampilan akan hilang atau viewWillDisappear, maka pengambilan video akan dihentikan atau .stop(). Selain itu, kita perlu memasang pengaturan pada viewDidLoad agar kamera dapat digunakan dan memunculkan gambar pada UIView.

Di saat yang bersamaan, kita perlu mengatur model agar bisa digunakan oleh machine learning. Jangan lupa untuk import library Vision.

Jika diperhatikan pada pengaturan kamera, saya menggunakan 30 FPS dan resolusi high. Perlu diketahui sebelumnya, YOLOv3 menghasilkan 9 FPS dan YOLOv3-Tiny menghasilkan 14 FPS. Menaikkan FPS pada fungsi kamera hanya akan meningkatkan performa saja, namun tidak pada tampilan hasil ML. Resolusi high yang saya gunakan merupakan resolusi 720p dengan aspect ration sebesar layar.

Hati-hati, menaikkan resolusi setinggi mungkin akan memaksa aplikasi menggunakan proses GPU lebih banyak sehingga akan membuat iPhone mudah panas. Pengaturan di atas cukup untuk membuat iPhone panas dalam waktu 5–10 menit.

Selanjutnya, kita akan memasang VideoHandlerDelegate pada ViewController untuk mengatur apa yang akan terjadi ketika gambar dikirimkan untuk proses ML.

Terakhir, kita akan membuat sistem ML Post Processing atau proses memunculkan hasil kepada pengguna.

Pembahasan Machine Learning

Pada bagian setupModel, kita memasang mlmodel sebagai VNCoreMLModel lalu memasukkan proses ML menjadi VNCoreMLRequest. Pada bagian ini kita mengatur sebuah method yang bernama visionRequestDidComplete sebagai method yang akan dijalankan ketika proses prediksi gambar telah selesai.

Ketika video berhasil mengambil gambar dan dikirimkan melalui VideoHandlerDelegate, gambar dalam bentuk queue berisikan buffer image akan dilempar kepada method yang bernama predictUsingVision untuk diprediksi. Pada method tersebut, method akan mengecek apakah request sudah diinisiasi atau belum. Jika sudah, gambar akan dimasukkan ke dalam VNImageRequestHandler, lalu kita jalankan menggunakan method perform(). Class dan method ini merupakan milik library Vision yang bertanggung jawab akan proses Machine Learning.

Ketika gambar berhasil diprediksi, method visionRequestDidComplete akan dipanggil. Isi pengembalian data berupa array yang berisikan object VNRecognizedObjectObservation. Data yang didapatkan akan dikirim ke dalam BoundingBoxView, lalu secara otomatis, setiap data di dalam array akan dibuatkan sebuah kotak dengan label. Tidak lupa, proses memberi warna yang sama pada setiap label yang sama.

Tutorial tentang Image Classification : Live Image Classification

Kesimpulan

Penerapan sistem Object Detection dalam aplikasi iOS tidak semudah yang dipikirkan, tidak semudah sistem Image Classification. Banyak hal yang harus disiapkan dan dipikirkan sebelum menerapkan sistem machine learning dan menunjukkan hasilnya kepada pengguna.

Biasakan memahami isi dari kodingan sebelum copy-paste kodingan di atas ke dalam projectmu. Asal mengcopy-paste bisa mengakibatkan program error karena adanya perbedaan kodingan.

Selamat mencoba…

--

--

Auriga Aristo
Dipantry

4+ years in Backend Developer | PHP, Java/Kotlin, MySQL, Golang | New story every week