πŸ‘¨β€πŸ’» Optical Illusion Video Object Detection

Ngoding tipis-tipis kali ini dipicu oleh gif menarik di Twitter.

Video serupa:

Menarik! Saat videonya berjalan, kita bisa melihat ada objek geometris – dedocahedron dan kubus – tapi waktu kita pause, objeknya hilang.

Bagaimana mata kita bisa melihat objek itu?

Jawaban:

Pada video pertama, latar belakang – mayoritas piksel gambar – statik, sedangkan pada beberapa daerah lain terjadi perubahan nilai piksel. Kumpulan daeran tersebut membentuk garis yang kita persepsikan sebagai rusuk dedocahedron.

Hal serupa pada video kedua. Pembedanya adalah pada video ini latar belakangnya bergerak ke arah kiri dengan nilai kecepatan tertentu. Kita dapat melihat daerah-daerah lain yang bergerak dengan arah dan kecepatan yang berbeda dengan latar belakang, dan mempersepsikannya sebagai rusuk kubus.

Oke, kalau begitu, ayo kita buat program agar komputer juga bisa ‘melihat’ objek itu!

(Object) Detection?

Kalau algoritma yang pertama kali terpikirkan olehmu adalah YOLO (atau RCNN), think again. Kita memang ingin mendeteksi objek, tetapi permasalahan object detection pada umumnya berkaitan dengan melokalisasi objek yang terlihat pada satu gambar. Sedangakan pada frame-frame individual pada video-video di atas, objek yang dimaksud tak kasat mata.

Untuk mencoba memecahkan masalah ini, kita kembali pada jawaban atas pertanyaan “Bagaimana mata kita bisa melihat objek itu?” di atas.

  1. Buat program untuk mendapatkan data gerakan piksel-piksel pada gambar.
  2. Bedakan latar belakang dengan objek berdasarkan data gerakan pada langkah pertama.
  3. ?????
  4. Profit(?)

Optical Flow

Pada dasarnya, untuk mendapatkan data gerakan piksel pada satu frame video, kita perlu bandingkan dengan frame-frame sebelumnya. Data gerakan akan berupa vektor kecepatan pada setiap piksel gambar

Algoritma seperti ini disebut optical flow, dan ada banyak jenisnya. Silakan cari-cari sendiri referensi jika tertarik mendalami lebih lanjut. Saya mau langsung pakai saja kode implementasi optical flow dalam bahasa python yang tersedia dari laman geeksforgeeks[link]. Begini outputnya jika input yang diberikan adalah video kubus:

Terlihat bagus, jadi untuk saat ini tidak perlu mengubah nilai parameter dari code yang sudah ada.

Segmentation

Pertama kita lakukan binary thresholding, teknik mengubah gambar agar nilainya menjadi biner – 0 dan 1. Binary thresholding kita aplikasikan terhadap magnitude vector, sehingga .

Dengan memilih parameter yang sesuai pada masing-masing video, didapatkan hasil yang memuaskan. Selanjutnya tinggal menandai garis tepi yang memisahkan antara daerah dengan nilai 0 dan 1, edge detection. Outputnya akan kita overlay ke gambar asli dari video. Hasilnya adalah sebagai berikut:

????

Dari dua video di bagian sebelumnya, terlihat kita sudah berhasil menampilkan objek-objek yang ingin kita lihat. Selanjutnya adalah bagian bebersih – mengubah beberapa bagian agar output lebih baik. Ada beberapa bagian yang akan kita tingkatkan di sini:

  1. Pada video pertama, terlihat kotak kuning yang melingkupi keseluruhan frame. Solusi gampang: kita batasi ukuran maksimal dari contour yang akan kita tampilkan.
  2. Pada video kedua, tampak banyak blob-blob contour kuning berukuran kecil. Solusi gampang: kita batasi juga ukuran minimal dari contour yang akan kita tampilkan.
  3. Pada video kedua, garis kuning terlihat berkelap-kelip. Ini disebabkan oleh sifat dari video sumbernya. Untuk mengatasi ini, kita bisa skip pemrosesan frame yang tidak berbeda dari frame sebelumnya. Secara teknis, kita akan mengurangi frame terbaru dengan frame sebelumnya, dan merata-ratakan nilainya. Selanjutnya catat data untuk menentukan threshold yang akan kita gunakan untuk menentukan apakah mau memproses frame atau tidak.

Beginilah hasil akhirnya:

Profit(?)

Video yang saya upload di sini sudah dikurangi bitratenya menggunakan ffmpeg agar ukurannya relatif kecil.

Kalau mau replicate, kode saya upload ke repo github. Tidak rapih, tapi bekerja.