Kenapa Informatika ITB?

Tulisan ini dibuat untuk berpartisipasi dalam gerakan cerita yang ada di sini.

Sesungguhnya Saya tidak pernah membayangkan untuk menempuh studi di bidang Informatika, apalagi hingga menjadi dosen di bidang yang sama. Sejak sekolah dasar Saya sudah akrab dengan elektronika karena sering dimintai tolong untuk membeli komponen di toko oleh Paman yang hobi mengutak-atik elektronik. Bahkan ketika masuk SMP dan ada mata pelajaran Elektronika, saya sangat senang walaupun sebetulnya mata pelajaran tersebut terhitung sebagai muatan lokal.
Read More

Seamless Cloning using Poisson Image Blending in Python

Beberapa waktu lalu ketika saya sedang mempersiapkan tulisan sebelumnya tentang face tracking, Saya terdampar di sebuah situs berbahasa Jepang yang cukup membuat penasaran (sampai sekarang saya belum ketemu lagi dengan situs tsb). Judul yang saya ingat waktu itu adalah “Poisson Image Editing”. Kalau dari judulnya saja saya tidak terlalu tertarik, tapi saya justru tertarik karena melihat gambar yang ditampilkan.

image cloning

pemindahan citra kepala beruang ke citra bukit dengan panduan mask. (gambar bukan milik saya)

Singkat kata, “Poisson Image Editing” ini merupakan judul makalah yang ditulis oleh Perez et al. Isinya kurang lebih sebagai memaparkan cara menggabungkan dua buah citra (sumber + mask + target = hasil). mask merupakan citra biner yang menandakan bagian citra sumber yang boleh dipindahkan ke citra hasil. Contohnya terlihat pada gambar di atas. Pada gambar tersebut terdapat 3 citra yaitu citra sumber, mask, dan citra hasil. citra target adalah citra hasil yang sebelumnya tidak ada gambar kepala beruang yang merupakan bagian dari citra sumber yang dipindahkan menggunakan panduan dari citra mask. citra mask dapat dianggap sebagai cetakan atau penyaring bagian yang dipindahkan dan yang tidak.

Read More

Simple Face Tracking with OpenCV (Python)

Beberapa waktu yang lalu ada yang menanyakan perihal lambatnya operasi openCV yang diintegrasikan dengan wxPython. Setelah melihat kode yang dipakai, ternyata penyebabnya adalah operasi deteksi objek yang menggunakan CascadeClassifier yang dilakukan setiap frame. Walaupun konon operasi pendeteksian objek menggunakan detektor CascadeClasifier merupakan state-of-the-art mendeteksi tercepat (baik menggunakan fitur Haar, ataupun yang lebih cepat lagi dengan menggunakan Local Binary Pattern), Operasi ini sangat tidak dianjurkan dijalankan di setiap frame karena tidak efisien.

Penjejakan (tracking) objek dengan cara mendeteksi objek di tiap frame merupakan cara yang paling naif karena setiap piksel pada beberapa tingkatan skala akan diperiksa. Cara yang lebih cerdas adalah memanfaatkan informasi yang sebelumnya sudah diketahui (deteksi pada frame sebelumnya), dan memanfaatkan asumsi bahwa objek yang diikuti tidak akan bergerak jauh dalam rentang dua buah gambar yang berurutan. Pada umumnya asumsi ini dapat dimanfaatkan, dengan pengecualian jika terjadi penutupan objek selama beberapa frame ataupun jika ada lebih dari satu objek yang diikuti dalam area yang berdekatan atau bersinggungan.

Berikut ini akan dijabarkan contoh penjejakan objek secara sederhana dengan memanfaatkan informasi dari hasil deteksi dan template matching. Teknik ini sangat sederhana karena informasi yang diestimasi hanyalah posisi dua dimensi (tidak menangani perubahan skala atau rotasi). Sederhananya proses penjejakan dilakukan dalam dua tahap yaitu deteksi dan estimasi. Jika belum ada objek yang terdeteksi maka proses deteksi akan dijalankan hingga ada yang terdeteksi. Jika sudah ada objek yang terdeteksi maka sudah ada informasi sebelumnya yang dapat dimanfaatkan yaitu posisi, area, dan isi area yang mendeskripsikan objek yang diikuti. Dengan demikian posisi objek pada gambar berikutnya dapat dilakukan dengan mencari area yang paling mirip di sekitar posisi awal (posisi hasil deteksi atau estimasi di gambar sebelumnya). Ukuran kemiripan dihitung dengan menggunakan beberapa cara. Cara yang paling umum adalah menggunakan metrik euclidean yaitu selisih dua buah vektor yang kemudian tiap elemennya dikuadratkan dan dijumlahkan sehingga menghasilkan konotasi jarak.

Kode berikut dapat dicoba dan dipelajari lebih lanjut agar konsep penjejakan dapat dipahami.

import numpy as np
import cv2
import cv
 
#video_src = 0 #webcam
video_src = r"angklung\angklung.avi"
cascade_fn = "lbpcascade_frontalface.xml"
#cascade_fn = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_fn)
cam = cv2.VideoCapture(video_src)
gotface = False
 
while True:
    ret, img = cam.read()
    if not ret: break
    gray = cv2.cvtColor(img, cv.CV_BGR2GRAY)
    
    if not gotface: #detect a face
        rects = cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=2, minSize=(20, 20))
        if len(rects)>0: 
            gotface = True
            x,y,width,height = rects[0]
            #create the first template for tracking from detected area
            face = np.array([0]*width*height, dtype=np.uint8).reshape((width,height))
            face[:,:] = gray[y:y+height,x:x+width]
    else: #track that face
        #window enlargement value to be used as search area
        wnd = min(width, height)/4
        #track using squared difference measurement
        result = cv2.matchTemplate(gray[y-wnd:y+height+wnd,x-wnd:x+width+wnd], face, cv.CV_TM_SQDIFF)
        
        #alternative measurement to track object, but more prone to drifting (COEFF > CCORR) than previous approach
        #result = cv2.matchTemplate(gray[y-wnd:y+height+wnd,x-wnd:x+width+wnd], face, cv.CV_TM_CCORR)
        #result = result.max()-result #inverse the value if CCOEFF is used
        
        yy,xx = np.unravel_index(result.argmin(), result.shape)
        x,y = (x-wnd) + xx, (y-wnd) + yy
        alpha = 0.5 #blending factor for template updating
        face[:,:] = face*alpha + (1.0-alpha) * gray[y:y+height, x:x+width]
    
    if gotface: #display tracked face
        cv2.rectangle(img, (x, y), (x+width, y+height), (255,0,0), 2)
        cv2.imshow('faceregion',face)
    cv2.imshow('facedetect',img)
    
    if cv2.waitKey(20) == 27: break

Pada kode di atas, kedua tahapan diimplementasi dengan menggunakan analisa kasus terhadap variabel gotface yang menyatakan ada atau tidaknya objek yang sudah terdeteksi. Contoh di atas juga ada beberapa bagian yang dikomentari dengan tujuan sebagai percobaan mandiri misalnya pada bagian ukuran alternatif yang secara prinsip menggunakan operasi perkalian bukan pengurangan seperti pada metode SQDIFF.

Gambar berikut menunjukkan kinerja beberapa metode yang digunakan dalam Template Matching. Kotak berwarna biru adalah metode CV_TM_SQDIFF, kotak berwarna hijau adalah metode CV_TM_CCORR, dan kotak berwarna merah adalah metode CV_TM_CCOEFF. Gambar diambil dari frame terakhir yang diproses. Pada awal deteksi setiap metode berangkat dari tempat yang sama. Pada gambar tersebut terlihat metode CCOEFF paling melenceng dari objek wajah sedangkan kinerja yang hampir sama ditunjukkan oleh metode CCORR dan SQDIFF.

perbandingan beberapa metode template matching untuk tracking objek

perbandingan beberapa metode template matching untuk tracking objek. Video diambil dari youtube tentang saung angklung Udjo.

NB:Oya, saya lupa mencantumkan informasi kode tersebut dijalankan di OpenCV versi 2.3.1

Nasionalisasi Bahasa Daerah sebagai sumber kosakata Pemadanan Istilah Asing

Sebetulnya tulisan ini didorong dari kicauan di twitter kemarin pagi. Idenya muncul setelah membaca tulisan Angelina Veni tentang ‘Bahasa Indonesia dan Lokalisasi’. Isi tulisannya tentang penggunaan Bahasa Indonesia pada bahasa pengantar layanan-layanan web populer dan usaha layanan web rintisan lokal yang justru menggunakan bahasa Inggris. Kicauan-kicauan tentang hal ini juga terpicu karena teringat ketika sedang mencari nama dari kelompok riset mengenai informatika terdistribusi yang tadinya mencoba mencari padanan istilah untuk ubiquituous yang salah satu usulan padanannya adalah sarwaga yang berasal dari bahasa Sansekerta.

Tulisan berikut bukan kutipan tapi paragraf awal yang tadinya saya buat sebagai pengantar tulisan ini yang berujung pada paragraf yang terlalu panjang tapi saya kurang tega untuk menghapusnya. Jadi jika masih merasa cukup waktu untuk membaca silakan dibaca. Jika tidak silakan dilompat saja.

Bahasa merupakan kendaraan dalam menyampaikan ide. Pengetahuan yang ada di muka bumi ini pada dasarnya merupakan sebuah kumpulan ide-ide yang disusun secara sistematis. Pengetahuan yang bersifat kolektif diperkaya baik secara formal melalui institusi pendidikan tinggi maupun secara informal melalui kegiatan sehari-hari. Kumpulan pengetahuan yang ada lalu dijadikan makanan sehari-hari melalui proses yang dinamakan Pendidikan. Suatu proses yang menjanjikan kemajuan hidup seseorang dan bahkan suatu bangsa.

Perkembangan pengetahuan termasuk di dalamnya pengetahuan dalam membuat suatu karya yang dinamakan teknologi seringkali tumbuh lebih cepat dibandingkan pengetahuan yang menjelaskan tentang fenomena alam (sains). Pertumbuhan yang cepat tidak lepas dari peran kendali kebutuhan manusia yang menjalankan roda perekonomian. Perkembangan sains akan menjadi landasan bagi perkembangan teknologi, namun perkembangan teknologi tidak hanya ditujukan untuk memajukan bidang sains saja tetapi juga aspek-aspek kehidupan lain dari manusia. Walaupun demikian, batasan organisasi yang berbeda dalam hal lokasi geografis, lingkungan, dan budaya turut mempengaruhi persebaran laju perkembangan pengetahuan.

Era globalisasi mendorong terjadinya pertukaran informasi maupun benda secara cepat. Produk-produk hasil pemikiran dan buah tangan manusia yang dibuat di suatu tempat tidak jarang juga akan digunakan di tempat lain dengan budaya yang berbeda. Pengetahuan dan teknologi tentang menghubungkan antar bahasa yang berbeda kemudian menjadi suatu hal yang memiliki peran penting dalam menjaga keberlangsungan hidup banyak orang. Pihak yang menerima dan mengonsumsi produk-produk tersebut dihadapkan pada dua pilihan yaitu mempelajari bahasa asing yang dijadikan acuan konvensional, atau mengusahakan tersedianya fasilitas perantara informasi dalam bahasa yang digunakan sehari-hari.

Pendek kata, Saya merasa kurang nyaman dengan usulan padanan istilah sarwaga. Walaupun dalam deskripsi usulan sarwaga dinyatakan istilah tersebut merupakan istilah yang paling mudah diucapkan oleh lidah orang Indonesia, Saya tetap merasakan istilah ini aneh untuk diucapkan dan dimaknai. Saya lalu terpikirkan sebuah ide “apakah (padanan istilah bahasa asing/inggris ke istilah bahasa Indonesia) harus dari bahasa Sansekerta?” yang berlanjut dengan argumen “Padahal Indonesia sangat kaya dengan keanekaragaman budaya khususnya bahasa” lalu berujung dengan ide “Mengapa (padanan istilah asing tersebut) tidak menggunakan koleksi kosakata dari bahasa daerah saja?”

Kemudian saya mencari-cari alasan untuk menolak atau menerima ide ini. Satu hal yang muncul dalam benak saya adalah bahasa Indonesia merupakan bahasa pemersatu bahasa-bahasa yang ada di tiap daerah. Oleh sebab itu sudah selayaknya istilah-istilah dalam bahasa Indonesia juga bersumber dari istilah dari bahasa-bahasa daerah sehingga setiap daerah punya rasa memiliki terhadap bahasa Indonesia dan bahasa daerah tersebut tetap diingat karena istilah yang ‘dinasionalisasi’ tersebut akan digunakan di daerah lain.

Bahasa Indonesia sejak awalnya merupakan racikan yang menyerap berbagai bahasa baik pada tataran peristilahan maupun pada aturan pembentukan kata. Hal yang teringat di dalam kepala saya Bahasa Indonesia banyak mengasimilasi bahasa-bahasa asing sebagai sumber kosakata namun jarang saya ingat ada kosakata bahasa Indonesia yang berasal dari bahasa-bahasa di daerah. Saya masih bisa mengidentifikasi istilah-istilah yang dulunya berasal dari bahasa Arab, Tiongkok, Melayu, Belanda, hingga Jepang tetapi lain halnya istilah-istilah yang berasal dari bahasa daerah. Kalaupun ada istilah dalam bahasa daerah yang sempat disebut selama belajar di sekolah dasar hingga menengah, sepertinya istilah-istilah atau frasa tersebut tetap dianggap sebagai bahasa daerah.

Saya pun masih merasa sangat awam mengenai topik kebahasaan namun saya suka menggunakan bahasa Indonesia. Hal inilah yang menjadi alasan mengapa saya sebisa mungkin membuat tulisan-tulisan di blog ini dalam bahasa Indonesia walaupun topik yang dibahas banyak sekali mengandung istilah asing. Saya memiliki keyakinan bahwa bahasa Indonesia pada saatnya akan mampu menjadi bahasa pemersatu (lingua franca). Ide yang saya kemukakan di paragraf sebelumnya pun saya yakini merupakan salah satu cara mewujudkan hal tersebut.

Salah satu ide kontribusi konkretnya mungkin dengan membuat suatu aplikasi web yang memfasilitasi pengusulan pemadanan istilah asing berdasarkan konsensus pemilihan usulan-usulan istilah yang berasal dari kosakata bahasa daerah. Tujuan akhirnya adalah sistem yang mampu membuat usulan padanan istilah asing secara otomatis, namun saya akhirnya menyadari bahwa untuk menghasilkan sistem yang otomatis tersebut diperlukan pengetahuan mengenai makna tiap kata dalam tiap bahasa daerah. Pengumpulan pengetahuan tentang bahasa daerah ini merupakan pekerjaan yang luar biasa besar dan mustahil diselesaikan oleh segelintir orang dalam waktu singkat. Hipotesis saya adalah sepertinya pekerjaan ini cocok jika diupayakan menggunakan pendekatan gotong-royong (crowdsourcing, lihatlah istilah ini sudah ada di Bahasa Indonesia jauh sebelum istilah crowdsourcing populer digunakan seperti sekarang).

Towards Optimal Sample Database for Learning-based Pattern Detector

What are the optimal parameters for developing a pattern detector?

Pertanyaan itu membuka pagi saya hari ini. Asal-muasal pertanyaan itu muncul dari sebuah pertanyaan pada milis opencv perihal seberapa banyak dan seberapa variatif sampel positif dan negatif yang harus dikumpulkan untuk membuat suatu sistem pendeteksi objek visual secara umum. Hal ini cukup memancing rasa penasaran. Pertama persoalan deteksi merupakan persoalan pengenalan pola (pattern recognition) yang paling sederhana dan batasannya paling longgar jika dibandingkan dengan segmentasi (deteksi batas pola) dan klasifikasi/pengenalan banyak-objek ataupun banyak-kategori/kelas. Persoalan deteksi outputnya biner, yakni hanya ada dua jawaban: ya(ada) atau tidak jika diberikan suatu pola masukan. Sebagai contoh, mata kita sangat sensitif mendeteksi pola wajah. Bahkan mungkin untuk pola yang bukan wajah tapi tampak seperti wajah pun masih dapat dideteksi secara objektif, bukan hanya halusinasi satu orang saja.

Read More

Mudah Mengimplementasikan Fasilitas Pencarian dengan Python Whoosh

Beberapa waktu lalu saya sempat membutuhkan mekanisme pencarian terhadap kumpulan dokumen teks. Beberapa alternatif yang populer diantaranya Apache Lucene (Solr) dan Sphinx search. Lucene berlisensi Apache License, Sphinx GPL. Keduanya ditulis dalam bahasa JAVA (OK, BIG NO). Setelah kesana-kemari mencari akhirnya ketemu alternatif yang cukup menarik yaitu Whoosh. library ini ditulis dalam pure python, berlisensi BSD, cepat, dan mudah digunakan.

Whoosh is a fast, featureful full-text indexing and searching library
implemented in pure Python. Programmers can use it to easily add search
functionality to their applications and websites. Every part of how Whoosh
works can be extended or replaced to meet your needs exactly.

Read More

Mempercepat Operasi OpenCV di Python dengan scipy.weave

Tadi pagi saya mencoba menerapkan kode tentang LBP (Local Binary Pattern) dari yang tadinya hanya memroses satu citra menjadi memroses tiap frame pada video. Saya mencoba LBP lebih dahulu dibanding HOG karena berdasarkan kode yang dibuat sebelumnya, waktu eksekusi HOG memang lebih lambat dibanding LBP. Namun ternyata waktu eksekusi perhitungan fitur LBP cukup berat yang membuat frekuensi penggambarannya turun hingga 1 frame per detik! Setelah diidentifikasi ternyata perulangan bersarang (nested loop) di python sangat lambat walaupun sudah menggunakan generator function xrange. Akhirnya teringat kode yang dibuat oleh Tom Haines yang memanfaatkan modul weave dalam paket scipy yang mempermudah membuat kode inline dalam bahasa C++ yang akan dikompilasi pada saat run-time sehingga yang dijalankan adalah kode native tanpa harus membuat kode dalam file terpisah.

Di awal-awal mencoba dengan hanya bermodalkan google, sempat seringkali gagal compile. kegagalan pertama, scipy.weave akan mencari compiler MS Visual C++ sehingga saya harus memaksa untuk menggunakan gcc. Kesalahan berikutnya adalah gagal compile. Perjuangan masih berlanjut ketika kode sudah berhasil dikompilasi, tetapi Image tidak berubah padahal di dalam kode inline nilainya sudah berubah. Hal lain yang perlu dicatat adalah saya mulai menggunakan interface opencv versi 2 (cv2) yang sudah terintegrasi dengan numpy karena untuk melakukan manipulasi piksel dengan menggunakan scipy.weave lebih memudahkan untuk menggunakan representasi numpy.array dibandingkan dengan IplImage (ya iyalah, scipy kan pake numpy).

OK, Pembahasan akan saya mulai dengan penggunaan fungsi inline dari scipy.weave. Perhatikan kode berikut:

import cv, cv2
import numpy as np
from scipy.weave import inline

MASK = np.array([[0,-1],[1,-1],[1,0],[1,1],[0,1],[-1,-1],[-1,0],[-1,1]])
def calc_lbp(src, dst):
    code = r"""
        for (int y=1; y<Nsrc[0]-1; ++y){
            for (int x=1; x<Nsrc[1]-1; ++x){
                unsigned char px = SRC2(y,x);
                unsigned char n = 0;
                for(int m=0; m<8; ++m) 
                    if(SRC2(y+MASK2(m,1),x+MASK2(m,0))>px) 
                        n |= 1 << m;
                DST2(y,x) = n;
            }
        }
    """
    inline(code, ['src','dst','MASK'], compiler='gcc')
    return dst

Read More