You are on page 1of 200

PROYEK AKHIR

PENGENDALIAN MODEL 3 DIMENSI WAJAH


MELALUI PENDETEKSIAN DAN TRACKING TITIK
FITUR WAJAH
Sub Judul :
TRAKING TITIK FITUR WAJAH BERDASARKAN
TEMPLATE MATCHING PADA GAMBAR SEKUEN

BITARIA CITRA DEWI


NRP. 7203.030.042

Dosen Pembimbing:
SRITRUSTA SUKARIDHOTO, ST
NIP. 132 300 372

Ir. DADET PRAMADIHANTO, M.Eng, Ph.D


NIP. 131 803 696

JURUSAN TEKNIK TELEKOMUNIKASI


POLITEKNIK ELEKTRONIKA NEGERI SURABAYA
SURABAYA 2006
PENGENDALIAN MODEL 3 DIMENSI WAJAH MELALUI
PENDETEKSIAN DAN TRACKING TITIK FITUR WAJAH
Sub Judul :
TRAKING TITIK FITUR WAJAH BERDASARKAN TEMPLATE
MATCHING PADA GAMBAR SEKUEN

Oleh :
BITARIA CITRA DEWI
7203 030 042

Proyek Akhir ini digunakan Sebagai Salah Satu Syarat Untuk


Memperoleh Gelar Ahli Madya (A.Md)
di
Politeknik Elektronika Negeri Surabaya
Institut Teknologi Sepuluh Nopember Surabaya

Disetujui oleh
Tim Penguji Proyek Akhir Dosen Pembimbing
1. 1.

Tri Budi Santoso, ST, MT Sritrusta Sukaridhoto, ST


NIP. 132 128 464 NIP. 132.300.372
2. 2.

Drs. Miftahul Huda, MT Ir. Dadet P, M.Eng,Ph.D


NIP. 132 055 257 NIP. 131.803.696
3.

Reni Soelistijorini, B.Eng, MT


NIP. 132 243 734
Mengetahui :
Ketua Jurusan

Drs. Miftahul Huda, MT


NIP. 132 055 257

ii
ABSTRAK

Pada Proyek Akhir ini diimplementasikan penambahan modul pada


software Galatea untuk membangun sebuah Life-like characters
(karakter hidup). Modul tersebut adalah Facial Fitur Tracking based
template matching on image sequence.
Tracking atau sistem penjejakan wajah merupakan salah satu
pengembangan dari pengolahan citra (image processing) dimana metode
ini dapat digunakan untuk melacak posisi wajah seseorang sekaligus
mengenali pergerakan wajah beserta fitur-fiturnya. Dalam proyek akhir
ini, batasan masalah difokuskan pada permasalahan yaitu apabila ada
beberapa titik fitur wajah pada frame pertama dari suatu video,
bagaimana untuk mencari perpindahan titik-titik fitur tersebut pada
frame kedua dan seterusnya. Metode yang digunakan untuk melakukan
tracking titik fitur wajah tersebut adalah Template Matching yaitu
dengan pendekatan titik-titik yang memiliki korelasi yang hampir sama
dengan template, dimana akan dicari nilai kedekatan antara template
dengan image untuk menghasilkan nilai korelasi terbesar pada daerah
tertentu yang akan dijadikan sebagai kandidat posisi untuk tracking
selanjutnya.
Dari hasil implementasi metode ini didapatkan tracking
berhasil dilakukan dengan batasan nilai selisih standart deviasi
kecerahan antara template dengan image sebesar 103 dan rata-rata
kecepatan tracking 2 sampai 6 detik.

Kata kunci : Life like character, Tracking, Template Matching

iii
ABSTRACT

This Final Project implemented modul that added on Galatea


software to build a life like character. The modul is Facial Fitur
Tracking based template matching on image sequence.
Tracking represent one of development from image processing
where this method can be used to track somebody’s face position all it
one recognize face movement include features. In this final project, the
problem limitation focused on problems that if there are some feature
on the first frame on the video, how to looking for movement this feature
points on the second video and so on. Method that is used for the
synchronization of model the face with the result detect the point of face
feature is Template Matching with the Correlation approach . Assess the
Correlation obtained to be used to process the tracking usher the frame
at one particular image.
From implementation result of this modul obtained that
tracking success with limitation value from different brightness of
deviation standart between template and image is 103 and average
speed tracking is 2 until 6 second.

Key word : Life like character, Tracking, Template Matching

iv
KATA PENGANTAR

Alangkah nikmat dan indahnya kehidupan ini jika kita mampu


mensyukuri nikmat dan karunia yang diberikan Allah kepada kita
semua. Dia yang menciptakan kita, menyediakan kebutuhan kita dan
membantu kita dalam kesulitan serta mencintai dan menyayangi kita
dalam pangkuan kasih dan karunia-Nya. Oleh karena itu, dengan
persaksian bahwa tiada sesembahan yang haq melainkan Allah dan
bahwa Muhammad adalah hamba dan utusan-Nya penulis panjatkan
syukur ke hadirat ILAHI ROBBI yang dengan berkah dan dengan
pertolongan-Nya penulis dapat menyelesaikan proyek akhir yang
berjudul :
Pengendalian Model 3 Dimensi Wajah Melalui Pendeteksian dan
Traking Titik Fitur Wajah
Pada Proyek Akhir ini dimaksudkan untuk memenuhi salah satu
persyaratan guna menyelesaikan studi di Politeknik Elektonika Negeri
Surabaya – Institut Teknologi Sepuluh Nopember.
Dalam menyelesaikan Proyek Akhir, kami melaksanakan
berdasarkan teori-teori yang telah kami peroleh dalam perkuliahan,
literatur dan bimbingan dari dosen pembimbing serta pihak-pihak lain
yang telah banyak memberikan semangat dan bantuan.
Penulis sadar bahwasanya masih banyak kesalahan-kesalahan dan
kekurangan dalam penyusunan buku laporan Proyek Akhir ini, untuk itu
penulis mohon maaf dan mengharapkan kritik dan saran dari pembaca.
Selain itu juga diharapkan pembaca dapat mengembangkan Proyek
Akhir ini. Semoga buku ini memberikan manfaat dalam menghasilkan
sumber daya manusia yang berkualitas. Amien…

Surabaya , 15 Agustus 2006

Penulis

v
UCAPAN TERIMA KASIH

Segala puji dan rasa syukur kepada Allah SWT yang telah
memberikan hidayahnya sehingga buku proyek akhir ini dapat selesai
tepat pada waktunya. Selain itu berkat bimbingan, bantuan dan
dukungan dari berbagai pihak, oleh karena itu dengan tulus dan ikhlas
kami ingin mengucapkan terima kasih kepada
1. Bapak dan Ibuku tercinta yang telah memberikan semangat,
dukungan dan doa yang tiada hentinya, aku mencintai kalian.... !!!
2. Bapak Dr. Ir. Titon Dutono, M.Eng, selaku Direktur Politeknik
Elektronika Negeri Surabaya.
3. Drs. Miftahul Huda selaku ketua jurusan Teknik Telekomunikasi
4. Bapak Sritrusta Sukaridhoto, ST selaku dosen pembimbing dan
kepala lab jarkom. Terima kasih buat bimbingan dan seluruh
fasilitas yang diberikan.
5. Bapak Ir. Dadet Pramadihanto, M.Eng,Ph.D selaku dosen
pembimbing. Terima kasih telah membimbing dengan penuh
kesabaran meskipun anak didiknya terkadang sulit untuk mengerti.
6. Seluruh Dosen Penguji maupun Dosen bukan Penguji yang telah
melontarkan pertanyaan dan sarannya yang sangat membantu dalam
penyempurnaan Tugas Akhir ini.
7. Bapak Edy Basuki (Alm) dan ibu yang sudah menganggap seperti
anak sendiri, terima kasih buat doa dan sarapannya Buk!
8. Mbakku Ari ratna juwita dan adekku tercinta Cahya Mustika
Narendri, serta tak lupa buat keponakan kecilku Brilyan Yanuar
Anggara, terima kasih buat cinta dan segalanya.
9. Wingga Latuayu Hidayat, terima kasih buat doa, cinta dan
kesabarannya.
10. “Galatea Group” merangkap Goodle 2006 Charie Chan (Sari),
Dinasaurus (Dina), Jupeng (Zulfan), Pak Ichik (Taufik), Bolot
(wahyudin) dan Puthut, yang telah berbagi ilmu, Sukses selalu buat
kalian....
11. Mas Bejo sebagai pembimbing bayangan, terima kasih buat
bimbingan, doa dan semua-muanya.
12. “Goodle 2006” ada Hohoman (Hasbi), makasih buat semuanya,
Dino (sebagai model), Awal, I’in Anis (temen mentoring), Rodli,
Tholib, Romy yang turut meramaikan suasana Lab Jarkom, tak lupa
pula makasih juga buat Pak Hero dan Mas Qiqi.

vi
13. Arek-arek TB angkatan 2003, “gak akan bisa nglupain kalian
semua”
14. “Gebang Wetan 38” Group, ada mbak kecil, mbak erika, ayunda,
ajeng, ridha, reni, erma, makasih buat semangatnya.....makasih juga
buat Mbak Frida yang sudah seperti kakak sendiri.
15. Mas Sragen, pak Agus (ASDIR 5), plus temen2 robot (Mas
cheking, komeng, doni, moedy, dll yg belom disebutin namanya)
makasih telah ngasi support+menemani begadang lewat chating
16. Semua temen2 dari dunia maya termasuk mbak phiera yang
ternyata adalah sodara sekampuang nan jauh di mato.
17. Warga PENS-ITS tercinta semuanya ...
18. Dan kepada pihak yang telah membantu saya dalam menyelesaikan
Proyek Akhir ini yang tidak bisa saya sebutkan satu-persatu.
Segala ucapan terimakasih dari kami tentunya belum cukup,
semoga Allah SWT membalas kebaikan-nya. Akhir kata, penulis
berharap semoga proyek akhir ini dapat memberikan manfaat dan
tambahan pengetahuan bagi pembaca.

vii
DAFTAR ISI
Halaman Judul ............................................................................. i
Halaman pengesahan.................................................................... ii
Abstrak ......................................................................................... iii
Abstract ........................................................................................ iv
Kata Pengantar .............................................................................. v
Ucapan Terima kasih .................................................................... vi
Daftar Isi ...................................................................................... viii
Daftar Gambar .............................................................................. x
Daftar Tabel .....................................................................................xii
Daftar Kode........................................................................................xiii

BAB I PENDAHULUAN............................................................ 1
1.1 Latar belakang........................................................................ 1
1.2. Tujuan .................................................................................... 2
1.3. Batasan masalah..................................................................... 2
1.4 Permasalahan ......................................................................... 3
1.5 Sistematika pembahasan ........................................................ 3

BAB II TEORI PENUNJANG................................................... 7


2.1. Galatea ................................................................................... 7
2.2. Image Processing ................................................................... 8
2.3. Konsep dasar DIP .................................................................. 9
2.4 Model Citra ........................................................................... 10
2.5 Bitmap................................................................................... 11
2.6 Perbaikan citra....................................................................... 12
2.6.1 Filter rata-rata............................................................... 13
2.6.2 Filter median ................................................................ 14
2.6.3 Filter Gaussian ............................................................. 15
2.7 Segmentasi citra .................................................................... 17
2.7.1 Treshold ....................................................................... 17
2.8 Pengolahan warna Red Green Blue....................................... 19
2.9 Greyscale............................................................................... 21
2.10 Edge detection...................................................................... 22
2.10.1 Operator sobel ............................................................ 22
2.11 Tracking dengan template matching ..................................... 25
2.11.1 Template matching..................................................... 25
2.11.2 korelasi ....................................................................... 25
2.12 Komputer grafik menggunakan opengl................................. 26

viii
2.13 Pemrograman Glut ................................................................ 28
2.14 PLIB .................................................................................... 33
2.15 Video for Linux ................................................................... 41

BAB III PERENCANAAN DAN PEMBUATAN..................... 51


3.1. Pendahuluan........................................................................ 51
3.2. Penangkapan dan pemrosesan gambar video ...................... 53
3.2.1. Linux video.............................................................. 53
3.2.2. Video capture........................................................... 55
3.2.3. Video to frame image sequence converter............... 60
3.3 Implementasi algoritma....................................................... 62
3.3.1 Image processing ...................................................... 64
3.3.2 Pembuatan template .................................................. 65
3.3.3 Perhitungan tingkat intensitas template .................... 69
3.3.4 Komputasi korelasi ................................................... 69
3.4 Sistem GUI.......................................................................... 74
3.4.1 Window utama .......................................................... 74
3.4.2 Fitur menu................................................................. 77
3.5 Arsitektur perangkat lunak.................................................. 78
3.5.1 Struktur file ............................................................... 78

BAB IV PENGUJIAN DAN ANALISA SOFTWARE............ 81


4.1. Pendahuluan ....................................................................... 81
4.2. Pengujian fungsionalitas..................................................... 82
4.2.1 Fungsi pembuatan template....................................... 82
4.2.2 Fungsi penangkapan gambar video ........................... 83
4.2.3 Fungsi Perhitungan SSD ...................................................... 84
4.2.4 Perhitungan korelasi.................................................. 85
4.3. Pengujian performa ............................................................ 85
4.3.1 Pengujian faktor brightness....................................... 86
4.3.2 Pengujian tracking untuk template persegi empat..... 87
4.3.3 Pengujian tracking untuk template titik..................... 96
4.4. Analisa................................................................................ 103

BAB V PENUTUP ..................................................................... 111


5.1. Kesimpulan ........................................................................... 111
5.2. Saran...................................................................................... 111

DAFTAR PUSTAKA ................................................................. 113


PROFILE PENULIS................................................................... 187

ix
DAFTAR GAMBAR
Gambar 2.1 Blok diagram galatea............................................... 7
Gambar 2.2 Konvensi Sistem koordinat citra diskrit ................. 10
Gambar 2.3 Perbaikan citra dengan mean filter .......................... 14
Gambar 2.4 Perbaikan citra dengan median filter ...................... 15
Gambar 2.5 Perbaikan citra dengan gaussian filter .................... 17
Gambar 2.6 Proses segmentasi citra dengan threshold ............... 19
Gambar 2.7 Ruang warna RGB dan CMY ................................. 20
Gambar 2.8 Hasil pengubahan citra menjadi greyscale .............. 21
Gambar2.9 Kernel konvolusi sobel ........................................... 23
Gambar 2.10 Kernel pseudo-convolution agar mempercepat
komputasi ............................................................... 24
Gambar 2.11 Salah satu input gambar yang diproses................... 24
Gambar 2.12 Gambar kiri adalah hasil dari operator sobel,
sebelah kanan menggunakan operator robert cross 24
Gambar 2.13 Susunan argument pada verteks ............................. 27
Gambar 2.14 Obyek kubus mempunyai 8 titik dan 6 face ........... 27

Gambar 3.1 Blok diagram sistem face tracking ......................... 51


Gambar 3.2 Blok diagram face tracking sistem ......................... 52
Gambar 3.3 Mini PenCam .......................................................... 54
Gambar 3.4 Diagram alir proses penangkapan gambar video ... 55
Gambar 3.5 Diagram alir video to frame image sequence
converter.................................................................. 60
Gambar 3.6 Algoritma face tracking........................................... 63
Gambar 3.7 Algoritma korelasi................................................... 71
Gambar 3.8 Window utama ....................................................... 77
Gambar 3.9 Arsitektur perangkat lunak ...................................... 78

Gambar 4.1 Hasil pembuatan template ....................................... 83


Gambar 4.2 Hasil template titik .................................................. 83
Gambar 4.3 Hasil penangkapan gambar dari kamera.................. 84
Gambar 4.4 Hasil tracking dengan perhitungan SSD.................. 84
Gambar 4.5 Hasil tracking gagal pada tingkat brightness ke 8 ... 87
Gambar 4.6 Frame-frame Dino untuk data pengujian................. 87
Gambar 4.7 Template mata kanan ukuran 58x44 piksel ............. 88
Gambar 4.8 Template alis ukuran 68x32 piksel.......................... 89
Gambar 4.9 Template mata kanan ukuran 66x36 piksel ............. 90
Gambar 4.10 Template mulut ukuran 96x42 piksel ..................... 91

x
Gambar 4.11 Frame-frame sari untuk data pengujian .................. 93
Gambar 4.12 Template wajah ukuran 116 x 112 piksel............... 93
Gambar 4.13 Template mata kanan ukuran 42x34 piksel ............ 93
Gambar 4.14 Template mata kiri ukuran 46x36 piksel ................ 94
Gambar 4.15 Template mulut ukuran 56x22 piksel ..................... 95
Gambar 4.16 Frame-frame Puthut untuk data pengujian ............. 96
Gambar 4.17 Grafik intensitas piksel frame 5 pada saat tracking
berhasil ditemukan ................................................. 104
Gambar 4.18 Grafik intensitas piksel frame 6 pada saat tracking
berhasil ditemukan ................................................. 104
Gambar 4.19 Grafik intensitas piksel frame 7 pada saat tracking
berhasil ditemukan ................................................. 105
Gambar 4.20 Grafik intensitas piksel frame 8 pada saat tracking
berhasil ditemukan ................................................. 106
Gambar 4.21 Grafik nilai korelasi masing-masing template........ 107
Gambar 4.22 Grafik nilai kecepatan masing-masing template..... 107

xi
DAFTAR TABEL
Tabel 3.1 Spesifikasi teknis perangkat lunak face tracking
sistem .......................................................................... 52
Tabel 3.2 Spesifikasi teknis kamera digital................................. 53

Tabel 4.1 Spesifikasi perangkat keras pengujian ........................ 82


Tabel 4.2 Perbandingan Korelasi dan SSD ................................. 85
Tabel 4.3 Hasil pengujian tracking dengan variabel faktor
brightness ................................................................... 86
Tabel 4.4 Hasil tracking template mata kanan ............................ 88
Tabel 4.5 Hasil tracking template alis......................................... 89
Tabel 4.6 Hasil pengujian template mata kiri.............................. 90
Tabel 4.7 Hasil pengujian tracking template mulut. ................... 92
Tabel 4.8 Hasil pengujian tracking wajah................................... 94
Tabel 4.9 Hasil tracking mata kanan........................................... 94
Tabel 4.10 Hasil tracking mata kiri............................................... 95
Tabel 4.11 Hasil tracking mulut.................................................... 95
Tabel 4.12 Koordinat hasil tracking titik fitur untuk frame
1 s/d 4 .......................................................................... 97
Tabel 4.13 Koordinat hasil tracking titik fitur untuk frame
5 s/d 8 .......................................................................... 98
Tabel 4.14 Koordinat hasil tracking titik fitur untuk frame
9 s/d 12 ........................................................................ 98
Tabel 4.15 Koordinat hasil tracking titik fitur untuk frame
13 s/d 16 ...................................................................... 98
Tabel 4.16 Koordinat hasil tracking titik fitur untuk frame
17 s/d 20 ...................................................................... 98
Tabel 4.17 Data grafik frame 5 ..................................................... 104
Tabel 4.18 Data grafik frame 6 ..................................................... 105
Tabel 4.19 Data grafik frame 8 ..................................................... 106
Tabel 4.20 Data rata-rata kecepatan dan korelasi hasil
pengujian tracking frame-frame Dino ......................... 107
Tabel 4.20 Data rata-rata kecepatan dan korelasi hasil
pengujian tracking frame-frame Sari........................... 105

xii
DAFTAR KODE
Kode 3.1 Program open/dev/video.............................................. 56
Kode 3.2 Inisialisasi video4linux ................................................ 57
Kode 3.3 Program penangkapan gambar video .......................... 59
Kode 3.4 Video to frame converter............................................. 61
Kode 3.5 Filter dan Treshold ...................................................... 64
Kode 3.6 Proses pembuatan template ........................................ 66
Kode 3.7 Program penyimpanan file template ........................... 68
Kode 3.8 Perhitungan algoritma korelasi.................................... 71
Kode 3.9 Inisialisasi GUI............................................................ 74

xiii
BAB I
PENDAHULUAN
1.1 LATAR BELAKANG
Dalam era perkembangan teknologi ini, manusia membutuhkan
komputer untuk membantu pekerjaan mereka. Selama ini interaksi
dengan komputer selalu menggunakan keyboard. Manusia harus
mengetikkan semua perintah yang diberikan pada komputer. Pada
Proyek Akhir ini kita mencoba membuat komunikasi antara manusia
dan komputer berdasarkan suara. Untuk itu diimplementasikan
penambahan modul pada software Galatea untuk membangun sebuah
Life-like characters (karakter hidup). Modul tersebut adalah Facial
Fitur Tracking based template matching on image sequence.

Life-like characters [7] (karakter hidup) adalah suatu pola yang


bertujuan mendukung kecenderungan manusia untuk berinteraksi dengn
komputer sebagai aktor sosial. Sebuah karakteristik umum yang
mendasari tampilan yang seperti hidup (logis) sebagai lawan bicara
adalah model komputasi yang menyediakan fungsi secara efektif seperti
sintesa emosi dan kepribadian serta mengimplementasikan tingkah laku
manusia secara interaktif atau merepresentasikan keterampilan.

Tracking atau sistem penjejakan wajah merupakan salah satu


pengembangan dari pengolahan citra (image processing) dimana metode
ini telah diaplikasikan dalam banyak sistem, sebagai contohnya aplikasi
ini dapat digunakan untuk melacak posisi wajah seseorang sekaligus
mengenali pergerakan wajah beserta fitur-fiturnya. Sehingga dengan
dikenali wajah tersebut dapat diaplikasikan pula untuk pengenalan
ekspresi wajah seseorang.
Pengenalan ekspresi adalah salah satu riset yang menarik dalam
hal mengenali tingkah laku manusia. Sejumlah eksperimen akan
dilakukan dengan tujuan menentukan emosi manusia, sehingga
komputerpun mampu mengenali ekspresi manusia seperti manusia
mampu memahami manusia lainnya saat melakukan interaksi. Seakan-
akan komputer dapat merasakan juga apa yang dirasakan oleh manusia
dan nantinya dimungkinkan akan membentuk suatu aksi dan interaksi
antara keduanya.

1
2

Dalam hal ini akan dilakukan pemrosesan video yang diambil


dari kamera. Video tersebut akan diproses tiap framenya, yaitu dengan
langkah awal membuat template menggunakan frame pertama. Template
inilah yang nantinya akan ditracking, sehingga akhirnya dapat diketahui
perpindahan titik-titik fitur tersebut pada frame kedua dan seterusnya .

1.2 TUJUAN

Proyek Akhir dengan judul “Pengendalian Model 3 Dimensi


Wajah Melalui Pendeteksian dan Tracking Titik Fitur Wajah”
bertujuan untuk
• Mengembangkan aplikasi pengolahan citra digital untuk
melakukan proses tracking titik-titik fitur wajah hingga
didapat node-node perpindahan masing-masing titik fitur
tersebut pada tiap-tiap frame.
• Membuat perangkat lunak dari proses pengambilan dan
pengolahan data gambar wajah dengan bahasa pemrograman
C dan OpenGL.
• Menghasilkan output berupa node-node perpindahan titik-
titik fitur yang nantinya bisa diintegrasikan dengan sistem
yang lain.

1.3 BATASAN MASALAH

Dalam proyek akhir ini, batasan masalah hanya difokuskan


pada permasalahan yaitu apabila ada beberapa titik fitur wajah pada
frame pertama dari suatu video, bagaimana untuk mencari perpindahan
titik-titik fitur tersebut pada frame kedua dan seterusnya menggunakan
template matching.
Dalam hal ini ,wajah model yang akan diidentifikasi :
• Pengidentifikasian hanya terfokus pada wajah dan hanya
dengan tanpa atau sedikit pergerakan
• Hanya satu wajah yang dicapture tiap prosesnya
• Pada wajah tidak ada kacamata,kumis dan jenggot
3

• Hanya melakukan pengambilan video wajah dalam ruangan


dengan keadaan pencahayaan yang baik.

1.4 PERMASALAHAN

Perumusan masalah yang dapat disimpulkan dari pembuatan


proyek akhir ini adalah :

• Bagimana melakukan pengambilan gambar bergerak dari suatu


wajah.
• Bagaimana mengkonversi file yang berupa video tersebut
menjadi file frame atau static image.
• Bagaimana membuat template yang nantinya akan dicari
pergeserannya dengan frame selanjutnya dari frame pertama.
• Bagaimana melakukan tracking pada titik-titik fitur wajah yaitu
dengan menghitung korelasi diantara keduanya yaitu antara
template dan current frame.

1.5 SISTEMATIKA PEMBAHASAN


Sistematika pembahasan yang akan diuraikan dalam buku
laporan proyek akhir ini terbagi dalam bab-bab yang akan dibahas
sebagai berikut :

BAB I PENDAHULUAN

Bab ini membahas tentang latar belakang, permasalahan,


tujuan, batasan masalah, dan sistematika pembahasan yang digunakan
dalam pembuatan proyek akhir ini.

BAB II TEORI PENUNJANG

Dalam Bab ini akan dibahas teori-teori yang digunakan dalam


penyelesaian proyek akhir yaitu meliputi:
• Image Processing
4

• Konsep Dasar DIP


• Model Citra
• Bitmap (bmp)
• Perbaikan citra
- Sistem Linier
- Filter rata-rata (Mean Filter)
- Filter median
- Filter Gaussian
• Segmentasi citra
- Treshold
• Pengolahan warna Red Green Blue (RGB)
• Grayscale
• Deteksi Tepi
- Operator sobel
• Tracking dengan Template Matching
• Komputer grafik menggunakan OpenGL
• Pemrograman Glut : Window dan Animasi
• PLIB (Portable Game Library)
• Video For Linux

BAB III PERENCANAAN DAN PEMBUATAN


Berisi tentang perencanaan dan pembuatan sistem. Terdiri dari
seluruh proses pengambilan video wajah bergerak sampai proses
tracking wajah menggunakan aplikasi pengolahan citra dan algoritma
penjejakan (Tracking) dengan perangkat lunak yang digunakan adalah C
dan OpenGL.
5

BAB IV PENGUJIAN DAN ANALISA


Berisi hasil, pengujian dan analisa dari sistem, metode dan
program yang ada, kemudian dibandingkan dengan perencanaan awal
serta teori-teori dari proyek akhir, dan mencari alternatif lain apabila
hasil yang ada tidak sesuai.

BAB V. KESIMPULAN
Bab ini berisi kesimpulan dari pembahasan pada perancangan
awal serta analisa yang diperoleh. Untuk lebih meningkatkan mutu dari
sistem yang telah dibuat maka kami memberikan saran-saran untuk
perbaikan dan penyempurnaan sistem.
6

-----Halaman ini sengaja dikosongkan-----


BAB II
TEORI PENUNJANG

2.1 GALATEA
Galatea adalah suatu software toolkit yang dikembangkan dengan
metode Human like spoken dialog dengan berdasarkan pada teknologi Life
like character. Sistem galatea dibagi menjadi beberapa bagian sub modul
yang mempunyai fungsi yang berbeda-beda, modul-modul tersebut adalah
modul face sinthesizer, speech sinthesizer, speech recognition, dan
communication manager yang keseluruhan modul dibuat sebagai sebuah
virtual machine yang keseluruhanyya dihubungkan dengan menggunakan
communication manager. Software ini dapat berjalan pada sistem operasi
UNIX maupun windows.

Gambar 2.1 Blok diagram galatea

Anthropomorphic Spoken Dialog Agent (ASDA) adalah suatu


sistem yang dapat berinterakasi dan berdialog dengan manusia yang
memanfaatkan teknologi Facial Animation dan Gesture. ASDA
merupakan salah satu teknologi masa depan dalam hubungannya dengan
Human Interface. Walaupun beberapa versi dari ASDA telah
dikembangkan, komunikasi antara ASDA dengan user masih jauh dari
natural dan masih menjadi suatu tantangan. Sistem ASDA dikembangkan
dengan prinsip easy-to-use dan easy-to-customize dengan harapan suatu
saat nanti dapat dicapai suatu sistem yang mendekati sempurna dengan

7
8

bantuan orang-orang yang ingin memanfaatkan sistem ini dengan bebas


dan gratis.
Sistem ASDA dengan toolkit yang bernama galatea telah
dikembangkan sejak tahun 2000 di Jepang. Beberapa fitur dari sistem
galatea adalah sebagai berikut:
1. Dapat dengan mudah dikustomisasi untuk sistem text to speech
sinthesis, animasi realistis sinthesis dan juga untuk modul speech
recognition.
2. Disediakan fungsi dasar untuk meningkatkan kualitas dari modul
speech recognition.
3. Mekanisme dari sinkronisasi antara suara dengan pergerakan
bibir agen.
4. Arsitektur Virtual Machine untuk transparansi komunikasi antar
modul.
Jika dibandingkan dengan proyek yang sama seperti CSLU toolkit 1
dan juga DARPA Communication program 2 , galatea masih memimpin,
namun walaupun sistem galatea lebih sederhana, mudah dipahami dan
masih dapat dikembangkan untuk tujuan penelitian sistem ini masih
terbatas dalam penggunaan bahasa jepang. Salah satu yang menjadi
keunggulan galatea adalah dapat menganimasikan suatu gambar 2 dimendi
dari seseorang menjadi gambar 3 dimensi yang dapat berekspresi
kemudian juga dapat mensinthesis agen yang tidak terbatas dengan wajah
agen yang berbeda. Pada saat ini sistem ASDA telah behasil
dikembangkan pada sistem UNIX/LINUX dan Windows.

2.2 IMAGE PROCESSING


Image processing atau pengolahan citra adalah bidang tersendiri
yang sudah cukup berkembang sejak orang mengerti bahwa komputer
tidak hanya dapat menangani data teks, tetapi juga data citra. Teknik-
teknik pengolahan citra biasanya digunakan untuk melakukan transformasi
dari satu citra kepada citra yang lain, sementara tugas perbaikan informasi
terletak pada manusia melalui penyusunan algoritmanya. Bidang ini
meliputi penajaman citra, penonjolan fitur tertentu dari suatu citra,
kompresi citra dan koreksi citra yang tidak fokus atau kabur.

1
Sutton, S., Cole, R.: Universal speech tools: the cslu toolkit, Proceedings of the
International Conference on Spoken Language Processing(ICSLP), pp. 3221–
3224 (1998)

2
DARPA, : DARPA Communicator Program (1998). http://fofoca.mitre.org/.
9

Untuk dapat mengerti dan melakukan operasi pengolahan citra,


pertama kali kita harus memahami dengan baik apa dan bagaimana sifat-
sifat citra itu sendiri. Ada dua hal penting dan sangat mendasar pada
proses pembentukan citra yang harus dipahami dan selanjutnya sangat
perlu untuk terus diingat, yaitu:
- Geometri formasi citra yang menentukan lokasi suatu titik dalam
pemandangan yang diproyeksikan pada bidang citra, dan
- Fisik cahaya, yang menentukan kecerahan suatu titik pada bidang
citra sebagai fungsi pencahayaan pemandangan dan sifat-sifat
permukaan.

Keuntungan menggunakan DIP (Digital Image Processing)


adalah presisi, yaitu pada masing-masing proses fotografi, disini terdapat
penurunan kualitas gambar dan sinyal elektrik yang terdegradasi akibat
keterbatasan komponen elektrik, dalam kondisi ini DIP dapat menjaga
hasil gambar tetap presisi. Keuntungan yang lain adalah fleksibilitas, yaitu
penggunaan yang lebih besar, sebuah gambar dapat dimagnified, reduced
atau rotated, kontras, brightness dapat diubah.

Selain keuntungan, DIP (Digital Image Processing) juga


memiliki kekurangan yaitu kecepatan dan mahal. Banyak operasi yang
digunakan oleh DIP lebih lambat dan lebih mahal dibandingkan operasi
optik atau elektrikal lainnya dan resources untuk menghitung bisa mahal.

2.3 KONSEP DASAR DIP


Citra atau image adalah angka (image is just a number), dari segi
estetika, citra atau gambar adalah kumpulan warna yang bisa terlihat indah,
memiliki pola, berbentuk abstrak dan lain sebagainya. Citra dapat berupa
foto udara, penampang lintang (cross section) dari suatu benda, gambar
wajah, hasil tomografi otak dan lain sebagainya. Dari segi ilmiah, citra
adalah gambar 3-dimensi (3D) dari suatu fungsi, biasanya intensitas warna
sebagai fungsi spatial x dan y. Di komputer, warna dapat dinyatakan,
misalnya sebagai angka dalam bentuk skala RGB. Karena citra adalah
angka, maka citra dapat diproses secara digital.

Image adalah sebuah gambar, foto yang ditampilkan atau bentuk


lain yang memberikan representasi visual tentang sebuah obyek atau
pemandangan. Pada DIP sebuah gambar bilangan array 2 dimensi, yang
10

setiap barisnya adalah representasi piksel pada gambar setiap barisnya.


Ukuran gambar biasanya 256X256, 512 X 512, 1024 X 1024. Minimum
nilai piksel = 0 (hitam), maksimum = 255 (putih) dan bilangan antara 0 s/d
255 merepresentasikan derajat keabuan. Gambar berwarna dapat
direpresentasikan dengan array 2D red, green dan blue Æ 3D. Komputer
membutuhkan memori lebih banyak untuk data ini rata-rata 3 kali data
storage.

Cara untuk menyimpan piksel, yaitu sebagai 1 bit (0/1) yang lebih
umum sebagai 1 byte = 8 bit (maksimum nilai piksel 255). Pada format byte
hanya menggunakan integer. Dasar-dasar piksel yaitu neighboors of piksel
(piksel ketetanggaan), keterkaitan, hubungan, persamaan dan penutup
transitip, ukuran jarak dan ALU operation (operasi aritmatik/logic).

Sebuah gambar didigitasi untuk mengkonversinya dalam bentuk


yang dapat disimpan dalam memori komputer atau beberapa bentuk media
penyimpan. Proses digitasi gambar dapat dilakukan dengan scanner, kamera
digital, video recorder. Sekali gambar sudah didigitasi, dia dapat
dioperasikan dengan bermacam-macam teknik image processing.

2.4 MODEL CITRA


Oleh karena citra merupakan matrik dua dimensi dari fungsi
intensitas cahaya, maka referensi citra menggunakan dua variabel yang
menunjuk posisi pada bidang dengan sebuah fungsi intensitas cahaya yang
dapat dituliskan sebagai f(x,y) dimana f adalah nilai amplitudo pada
koordinat spasial (x,y). Karena cahaya merupakan salah satu bentuk
energi, f(x,y) tidak berharga nol atau negatif dan merupakan bilangan
berhingga.
Konvensi sistem koordinat citra diskrit ditunjukkan oleh gambar
berikut,
(0,0)
y
Citra
f(x,y)

Gambar 2.2 Konvensi Sistem Koordinat Citra Diskrit


11

Citra yang tidak berwarna atau hitam putih dikenal juga sebagai
citra dengan derajat keabuan (citra gray level). Derajat keabuan yang
dimiliki ini bisa beragam mulai dari 2 derajat keabuan (yaitu 0 dan 1) yang
dikenal juga sebagai citra monochrome, 16 derajat keabuan dan 256
derajat keabuan. Semakin besar jumlah derajat keabuan yang dimiliki
maka semakin halus citra tersebut.

Dalam sebuah citra monochrome, sebuah piksel diwakili oleh 1


bit data yang berisikan data tentang derajat keabuan yang dimiliki piksel
tersebut. Data akan berisi 1 bila piksel tersebut berwarna putih dan data
akan berisi nilai 0 bila piksel tersebut berwarna hitam.

Citra yang memiliki 16 derajat keabuan (mulai dari 0 yang


mewakili warna hitam sampai dengan 15 yang mewakili warna putih)
direpresentasikan oleh 4 bit data, sedangkan citra dengan 256 derajat
keabuan (nilai dari 0 yang mewakili warna hitam sampai dengan 255 yang
mewakili warna putih) direpresentasikan oleh 8 bit data.

Dalam citra berwarna, jumlah warna bisa beragam mulai dari 16,
256, 65536 atau 16 juta warna, yang masing-masing direpresentasikan
oleh 4, 8, 16, atau 24 bit data untuk setiap pikselnya. Warna yang ada
terdiri dari 3 komponen utama yaitu nilai merah (red), nilai hijau (green),
dan nilai biru (blue). Paduan ketiga komponen utama pembentuk warna ini
dikenal sebagai RGB color.

2.5 BITMAP (bmp)


Bitmap adalah representasi atau gambaran yang terdiri dari baris
dan kolom pada titik image graphics di komputer. Nilai dari titik disimpan
dalam satu atau lebih data bit.

Tampilan dari bitmap atau raster, menggunakan titik-titik


berwarna yang dikenal dengan sebutan piksel. Piksel-piksel tersebut
ditempatkan pada lokasi-lokasi tertentu dengan nilai-nilai warna tersendiri,
yang secara keseluruhan akan membentuk sebuah tampilan gambar.
Tampilan bitmap mampu menunjukkan kehalusan gradasi bayangan dan
warna dari sebuah gambar, karena itu bitmap merupakan media elektronik
yang paling tepat untuk gambar-gambar dengan perpaduan gradasi warna
yang rumit seperti foto dan lukisan digital.
12

Struktur bitmap terdiri dari Header, Info Header dan Color Tabel.
Header adalah bagian dari file bitmap yang berisi informasi header dari
file gambar bitmap. Ukuran dari header ini 14 byte, masing-masing terdiri
dari signature 2 byte (berisi “BM” sebagai tanda gambar mempunyai
format bmp), FileSize 4 byte (besarnya ukuran gambar mempunyai satuan
byte), Reserved 4 byte (tidak digunakan atau sama diisi dengan nilai nol)
dan DataOffset 4 byte (file offset untuk raster data).

Info header adalah bagian dari header yang berisi informasi lebih
detail dari file gambar bitmap. Letaknya setelah bagian header. Info
header mempunyai besar 40 byte, terdiri dari size 4 byte (ukuran
infoheader dan isinya adalah nilai 40), width 4 byte (lebar gambar bitmap
dalam satu piksel), Height 4 byte (tinggi gambar bitmap dalam satuan
piksel), planes 2 byte (jumlah warna dalam plane, isinya selalu sama
dengan satu), BitCount 2 byte (Bits per piksel, jika bernilai 1=
monochome palette, banyaknya warna =2, jika bernilai 4= 4 bit palette,
banyaknya warna = 16, jika bernilai 8 = 8 bit palette, banyaknya warna =
256, jika bernilai 16 = 16 bit RGB, banyaknya warna = 65536, jika
bernilai 24 = 24 bit RGB, banyaknya warna = 16M), Compression 4 byte
(jenis kompresi yang digunakan, jika bernilai 0, gambar tidak terkompresi,
jika bernilai 1 gambar terkompresi 8 bit RLE-run length encoding, jika
bernilai 2, gambar terkompresi 4 bit RLE encoding), ImageSize 4 byte
(ukuran gambar dalam byte atas perkalian dari width dikalikan dengan
height), XpikselPerM 4 byte (resolusi horizontal dalam satuan piksel),
YpikselxPerM 4 byte (resolusi vertikal dalam satuan piksel), ColorUsed 4
byte (banyaknya warna dalam color table), ColorImportant 4 byte
(banyaknya warna utama).

Color table adalah tabel yang berisi warna-warna yang ada pada
gambar bitmap. Ukurannya adalah 4 dikalikan dengan ukuran banyaknya
warna. Color table berisi RGB-red green blue. Strukturnya terdiri dari 1
byte untuk bagian Rgbblue yang berisi intensitas warna biru 0...255, 1
byte untuk bagian RgbGreen yang berisi intensitas warna hijau 0...255, 1
byte untuk bagian RgbRed yang berisi intensitas warna merah 0...255, 1
byte untuk bagian RgbReserved yang selalu di set sama dengan 0.

2.6 PERBAIKAN CITRA


Ketika kamera menangkap sebuah citra, seringkali tidak dapat
langsung digunakan seperti yang diinginkan karena kualitasnya yang
13

belum tentu memenuhi standar pengolahan. Sebagai contoh citra disertai


oleh variasi intensitas yang kurang seragam akibat dari pencahayaan yang
tidak merata, atau lemah dalam hal kontras sehingga obyek sulit untuk
dipisahkan dari latar belakangnya melalui operasi binerisasi karena terlalu
banyak noise (gangguan atau distorsi dalam citra) dan lain sebagainya.
Citra dengan kualitas seperti ini memerlukan langkah-langkah perbaikan
atau kualitasnya perlu ditingkatkan untuk memfasilitasi pengolahan yang
akan dilakukan. Semua ini memerlukan pengolahan awal dari sebuah
sistem visual yang bertujuan meningkatkan kualitas citra secara umum,
sebelum melangkah kepada pengolahan inti dengan tujuan yang lebih
spesifik. Diantara teknik-teknik pengolahan awal untuk meningkatkan
kualitas citra ini adalah penggunaan filter.

2.5.1 FILTER RATA-RATA (MEAN FILTER)


Salah satu filter yang paling sederhana adalah filter rata-rata
intensitas pada beberapa piksel lokal dimana setiap piksel akan digantikan
nilainya dengan rata-rata dari nilai intensitas piksel tersebut dengan piksel-
piksel tetangganya, dan jumlah piksel tetangga yang dilibatkan tergantung
pada filter yang dirancang. Secara matematis, hal ini dapat dinyatakan
dengan persamaan berikut :

1
h(x,y) =
M
∑ f (k , l )
( k ,l )∈N
(2.3)

Dimana M adalah jumlah piksel-piksel pada jendela sebesar NxN. Sebagai


contoh, pada daerah 3x3 (N=3, M=9) pada tetangga (x,y), perhitungan
melibatkan 8 piksel-piksel tetangga dan menghasilkan:

x +1 y +1
1
h(x,y) =
9
∑ ∑ f (k , l )
k = x −1 l = y −1
(2.4)

Bila dibandingkan dengan persamaan h(x,y) = f(x,y)*g(x,y) ,


maka sekarang g(x,y) bernilai 1/9 dalam jendela atau cetakan konvolusi.
Operasi konvolusi pada persamaan (2.3) berubah menjadi perhitungan
rata-rata intensitas piksel-piksel local seperti diperlihatkan pada
persamaan berikut :
14

AP1 + BP2 + CP3 + DP4 + EP5 + FP6 + GP7 + HP8 + IP9


h(x,y)= (2.5)
9

Hal ini memperlihatkan bahwa filter rata-rata dapat


diimplementasikan sebagai operasi konvolusi dengan pembobotan yang
sama dalam jendela konvolusi atau cetakan konvolusi.

Gambar 2.3 Perbaikan citra dengan mean filter

2.5.3 FILTER MEDIAN


Masalah utama pada filter rata-rata lokal adalah filter tersebut
cenderung mengaburkan batas-batas perbedaan nilai intensitas pada citra.
Sebagai alternatif dari filter rata-rata adalah dengan menggantikan nilai
piksel dengan nilai median atau nilai tengah dari piksel – piksel
tetangganya dan piksel itu sendiri. Filter seperti ini disebut filter median
dan sangat efektif untuk menghilangkan noise jenis salt dan peper, juga
impulse sementara mencerahkan detail citra karena tidak tergantung pada
nilai-nilai yang berbeda dengan nilai-nilai yang umum dalam
lingkungannya. Cara kerja filter median dalam jendela tertentu mirip
dengan filter linear namun prosesnya bukan lagi dengan pembobotan.
Misalnya untuk jendela berukuran 3x3, cara mencari nilai median adalah:
1. baca nilai piksel yang akan diproses beserta piksel-piksel
tetangganya
2. urutkan nilai-nilai piksel dari yang paling kecil hingga yang
paling besar
3. pilih nilai pada bagian tengah untuk nilai yang baru bagi piksel
(x,y)
Umumnya ukuran jendela sedemikian rupa sehingga jumlah
piksel dalam jendela ganjil. Bila jumlah piksel genap, nilai median harus
diambil dari rata-rata dua nilai piksel ditengah, namun hal ini jarang
dilakukan.
15

Gambar 2.4 Perbaikan citra dengan median filter

2.5.4 FILTER GAUSSIAN


Filter Gaussian adalah salah satu filter linear dengan nilai
pembobotan untuk setiap anggotanya dipilih berdasarkan bentuk fungsi
Gaussian. Filter ini sangat baik untuk menghilangkan noise yang bersifat
sebaran normal, yang banyak dijumpai pada citra hasil proses digitasi
menggunakan kamera karena merupakan fenomena alamiah akibat sifat
pantulan cahaya dan kepekaan sensor cahaya pada kamera itu sendiri.
Adalah suatu ketidaksengajaan bahwa noise secara alamiah juga
mempunyai sebaran Gaussian, sehingga secara teoritis akan menjadi netral
manakala dilawan dengan fungsi lain yang juga mempunyai sebaran
Gaussian. Zero mean dari fungsi Gaussian dalam satu dimensi adalah
sebagai berikut:

X2

2σ 2
g(x) = e (2.6)

Dalam persamaan diatas, parameter sebaran σ adalah lebar dari


fungsi Gaussian, yang akan mempengaruhi bentuk grafis tiga dimensi
hasil plot titik-titik hasil perhitungannya. Untuk pengolahan citra digital
yang merupakan bidang dua dimensi, zero mean Gaussian yang digunakan
juga harus dalam dua dimensi, sehingga sama-sama mengandung dua
variabel bebas. Zero mean Gaussian dengan dua variabel untuk bidang
dinyatakan dalam bentuk persamaan dengan dua variabel bebas yang
bersifat diskrit, sebagai berikut:

( x2 + y2 )

2σ 2
g(x,y) = e (2.7)
16

persamaan ini selanjutnya digunakan sebagai formula untuk menghitung


atau menentukan nilai-nilai setiap elemen dalam filter penghalus Gaussian
yang akan dibentuk.

Merancang Filter Gaussian :


Satu cara yang baik sebagai pendekatan untuk membuat filter
Gaussian disediakan oleh koefisien ekspansi binomial sebagai berikut :

⎡n⎤ ⎡n ⎤ ⎡n ⎤ ⎡n ⎤
(1+ x ) = ⎢ ⎥ + ⎢ ⎥ x + ⎢ ⎥ x + ... + ⎢ ⎥ x
n 1 2 n
(2.8)
⎣0⎦ ⎣1 ⎦ ⎣2⎦ ⎣0 ⎦
Ini berarti penggunaan baris ke-n dari segitiga pascal sebagai
pendekatan n titik untuk filter Gaussian satu dimensi dapat dilakukan
dengan mengambil nilai koefisien ekspansi binomial seperti diperlihatkan
diatas. Misalnya pendekatan untuk lima titik dengan teknik ini
menghasilkan deretan bilangan sebagai berikut:

1 4 6 4 1

Deretan bilangan ini bersesuaian dengan baris ke-5 dari segitiga


pascal. Pola ini dapat digunakan untuk menghaluskan citra dalam satu
arah karena berbentuk satu dimensi, yaitu arah horizontal saja, tidak dalam
arah vertikal. Namun demikian filter Gaussian dua dimensi dapat
dijalankan dengan menerapkan filter satu dimensi ini dalam dua kali
konvolusi, sekali dalam arah horizontal dan sekali dalam arah vertikal.

Pendekatan lain dalam merancang filter Gaussian adalah dengan


menghitung nilai pembobotan langsung dari distribusi diskrit Gaussian,

( x2 + y2 )
− 2
g(x,y) = ce 2σ (2.9)
dimana c adalah konstanta normalisasi.
Dengan menentukan nilai untuk σ , nilai-nilai pembobot untuk
2

jendela nxn dapat dihitung untuk mendapatkan matrik dimana nilai pada
(0,0) sama dengan satu.
Ketika filter Gaussian ini digunakan untuk melakukan konvolusi
terhadap suatu citra yang mengandung noise, nilai piksel hasil perhitungan
harus dinormalkan dengan cara membaginya dengan jumlah semua
17

elemen nilai pembobot pada filter agar selang nilai intensitas tetap seperti
semula.

Gambar 2.5 Perbaikan citra dengan gaussian filter

2.7 SEGMENTASI CITRA


Segmentasi (klasifikasi piksel) pada prinsipnya terbagi atas tiga,
yaitu segmentasi terhadap warna, bentuk, dan tekstur. Segmentasi yang
dilakukan dalam proyek akhir ini adalah segmentasi terhadap warna yang
merupakan proses untuk memisahkan obyek yang kita ambil dengan latar
belakang obyeknya dimana pendekatan yang diambil adalah dengan
pengelompokan (clustering) warna. Segmentasi terhadap warna dapat
dilakukan melalui proses threshold. Sedangkan pada clustering warna-
warna yang mendekati bagian warna sejenis nantinya akan diproses agar
hanya memperoleh dua jenis warna yang menonjol yaitu hitam dan putih

2.6.1 THRESHOLD
Threshold digunakan untuk mengatur jumlah derajat keabuan
yang ada pada citra. Dengan menggunakan threshold maka derajat
keabuan bisa diubah sesuai keinginan, misalkan diinginkan menggunakan
derajat keabuan dengan 16.
Ambang batas (threshold) merupakan salah satu pendekatan yang
paling penting dalam segmentasi citra. Teknik ini didasarkan pada konsep
yang sederhana yaitu membandingkan data citra setiap piksel dengan
parameter ambang ( Tr ). Parameter ambang dipilih dan diberikan pada
suatu citra F[x,y] adalah sebagai berikut:

If F[x,y] ≥ Tr
F[x,y] = obyek = 1
Else
F[x,y] = background = 0
18

Untuk algoritma diatas diasumsikan bahwa obyek diberi warna


putih dan background diberi warna hitam. Namun jika menginginkan
obyek diberi warna hitam dan background diberi warna putih maka
algoritma yang digunakan adalah sebagai berikut :

If F[x,y] < Tr
F[x,y] = obyek = 1
Else
F[x,y] = background = 0

Nilai keluaran dari proses ambang batas yang diberi nama


obyek dengan background dapat diwakili dengan variable Boolean ‘1’
dan ‘0’ .
Proses threshold ini pada dasarnya adalah proses pengubahan
kuantisasi pada citra, sehingga untuk melakukan threshold dengan derajat
keabuan dapat digunakan rumus

x = b int (w/b) (2.10)


Dimana;
x adalah nilai derajat keabuan sebelum threshold
w adalah nilai derajat keabuan setelah threshold

b = int (256/a) (2.11)

Untuk menentukan nilai threshold harus sesuai dengan model dan


obyek yang akan ditentukan, sehingga penentuan nilai threshold berasal
dari nilai latar belakang dari obyek itu sendiri. Proses ini tetap akan
bekerja dengan baik untuk semua citra. Alternatif yang dapat digunakan
untuk menentukan nilai threshold adalah:
1. Nilai Threshold selalu tetap (fixed threshold)
Memilih nilai threshold secara bebas dari data citra. Hal ini
diberikan dengan mengacu pada suatu ketetapan, misalnya suatu
citra memiliki perbedaan yang sangat tinggi dan obyek yang
diamati dalam citra tersebut adalah gelap dengan backgroud dari
citra yang sangat terang. Dan kemudian konstanta ambang batas
dipilih 128 pada skala 0 sampai 255. Hal ini mungkin akan
memberikan hasil yang cukup akurat. Maksud akurat disini
adalah meminimumkan piksel yang salah dalam
19

pengelompokannya. Dalam banyak kasus fixed threshold tidak


memberi hasil segmentasi yang bagus. Jika menggunakan fixed
threshold hasil yang diperoleh adalah pada salah satu sisi gambar,
obyek dan backgroundnya akan tampak terang sedang sisi lain
akan tampak gelap dan hasil yang bagus pada suatu gambar
belum tentu bagus untuk gambar yang lain.
2. Nilai Threshold tidak tetap (Variable threshold)
Pada fixed threshold nilai thresholdnya kita tentukan secara pasti
sedangkan pada variabel threshold kita menentukan nilai treshold
berdasarkan kombinasi dari nilai RGB dari gambar, maka hasil
yang kita peroleh akan lebih baik untuk dapat memisahkan antara
obyek dengan backgroundnya melalui proses variabel threshold.

Gambar 2.6 Proses segmentasi citra ke threshold

2.8 PENGOLAHAN WARNA RED GREEN BLUE (RGB)


Model warna RGB (red, green, blue) mendeskripsikan warna
sebagai kombinasi positif dari 3 warna, yaitu merah, hijau, dan biru
sehingga membentuk sebuah warna C dengan rumusan sebagai berikut,
C rR gG bB (2.12)
Jika skalar r, g, b kita beri harga antara 0 dan 1, maka semua
definisi warna akan memiliki nilai yang berbeda-beda.

Sebagai perumpamaan nilai-nilai tersebut berada dalam kubus


seperti berikut,
20

Gambar 2.7 Ruang Warna RGB dan CMY

Ruang warna ini adalah dasar warna dari display monitor


komputer. Garis sepanjang titik hitam (0,0,0) RGB hingga titik abu (1,1,1)
RGB disebut dengan titik keabuan atau gray level. Sehingga kita dapatkan
hubungan antara RGB dengan gray level yaitu,

(a)GL (a, a, a)RGB (2.13)

Sementara hubungan antara RGB dengan CMY diberikan oleh


rumusan,

(r, g, b)RGB = (1,1,1) – (c, m, y)CMY (2.14)

sehingga apabila nilai dari b diturunkan akan menyebabkan warna


bergeser menjadi kekuningan.

Pada proses penjumlahan warna, warna yang dideskripsikan


dengan RGB adalah pemetaan yang mengacu pada panjang gelombang
dari RGB. Pemetaan tersebut menghasilkan nuansa warna sekitar 16 juta
(2563 = 16. 777. 216) yaitu 256 (8 bit) untuk masing-masing R, G, dan B.

Masing-masing R, G dan B didiskritkan dalam skala 256,


sehingga RGB akan memiliki indeks antara 0 sampai 255.

Penjumlahan warna RGB ini adalah,

C = C1 + C2 = (rC1, gC1, bC1) + (rC2, gC2, bC2 (2.15)


2
21

Penjumlahan ini menghasilkan nilai RGB yang tidak bulat,


sehingga kita harus membulatkan nilainya, yaitu dengan metode bulat
kebawah atau keatas. Misalkan dua warna yaitu hitam (0, 0, 0) kita
jumlahkan dengan warna putih (255, 255, 255) akan menghasilkan warna
abu-abu antara hitam dan putih (127, 127, 127). Hasil akhir dibulatkan
kebawah. Contoh lain misalkan menjumlahkan warna merah (255, 0, 0)
dengan warna hijau (0, 255, 0) akan menghasilkan warna kuning
(127,127,0).

2.9 GREYSCALE
Proses permulaan yang banyak dilakukan dalam image
processing adalah mengubah citra berwarna menjadi citra grayscale, hal
ini digunakan untuk menyederhanakan model citra. Citra berwarna terdiri
dari 3 layer matrik yaitu R-layer, G-layer, dan B-layer. Sehingga untuk
melakukan proses-proses selanjutnya tetap diperhatikan tiga layer diatas.
Bila setiap proses perhitungan dilakukan menggunakan tiga layer, berarti
dilakukan tiga perhitungan yang sama. Sehingga konsep itu diganti
dengan mengubah 3 layer diatas menjadi 1 layer matrik grayscale. Dalam
citra ini tidak ada lagi warna, yang ada adalah derajat keabuan.

Untuk mengubah citra berwarna yang mempunyai nilai matrik


masing – masing r, g dan b menjadi citra grayscale dengan nilai s,maka
konversi dapat dilakukan dengan mengambil rata-rata dari nilai r, g dan b
sehingga dapat dituliskan menjadi:

r + g +b
s= (2.16)
3

Gambar 2.8 Hasil pengubahan citra menjadi greyscale


22

2.10 EDGE DETECTION


Edge detection atau deteksi tepi adalah proses yang sering
digunakan saat pengolahan image. Edge detection dapat diartikan sebagai
pelacakan atau pendeteksian sudut-sudut suatu obyek dalam sebuah image
dimana sudut-sudut tersebut dibedakan berdsarkan perbedaan nilai R, G
dan B masing-masing piksel. Tujuan dari deteksi ini adalah untuk
mengurangi kompleksitas gambar dengan menampilkan bagian gambar
yang memiliki frekuensi tinggi.

Disini kita gunakan proses konvolusi jadi tergantung dengan


kernel yang kita gunakan. Untuk proses ini kita gunakan kernel dengan
Sobel operator. Image kita proses dengan mengalikan convolv kernel
maka daerah tepi tiap obyek pada gambar akan terlihat jelas, karena pada
intinya proses edge detection ini akan mendeteksi tiap daerah yang
memilki intensitas perbedaan warna atau pencahayaan. Maka daerah
obyek atau gambar dari background dengan tulisan memilki perbedaan
intensitas makanya dapat dideteksi dengan jelas, jadi kelihatan tiap terjadi
perbedaan. Dalam proyek akhir ini dilakukan pengurangan warna, yaitu
hanya warna greyscale saja. Oleh karena itu sebelum dilakukan proses
gambar digreyscale dulu.

2.9.1 OPERATOR SOBEL


Operator sobel melakukan perhitungan secara 2D terhadap suatu
ruang di dalam sebuah gambar dengan harapan nantinya akan nampak
daerah-daerah bernilai tinggi pada gambar tersebut yang merupakan
deteksi tepi dari suatu gambaran. Operator ini biasanya digunakan untuk
mencari gradient dari masing-masing piksel gambar input yang telah di
grayscale sebelumnya.

Secara teori, diperlukan matrik setidaknya berukuran 3x3 sebagai


kernelnya. Seperti gambar dibawah ini menunjukkan kernel 3x3 dari sobel
:
23

Gambar 2.9 Kernel Konvolusi Sobel

Kernel ini dirancang untuk menyelesaikan permasalahan deteksi


tepi baik secara vertikal maupun horisontal. Penggunaan kernel-kernel ini
dapat digunakan bersamaan ataupun secara terpisah. Apabila digunakan
kernel vertikal dan kernel horisontal secara bersamaan, maka gradient
dapat diukur dengan formula sbb:

G = Gx 2 + Gy 2 (2.17)

Nilai magnitude dari gradient juga dapat dihitung lebih cepat lagi
dengan menggunakan formula sbb:

G = Gx + Gy (2.18)

Gradient tersebut pasti mempunyai derajat kemiringan tertentu.


Untuk dapat mengetahui sudut dari gradient tersebut dapat dihitung
dengan menggunakan rumus sbb:

ϑ = arctan(Gy / Gx ) (2.19)

Dalam kasus ini, orientasi 0 untuk menentukan nilai kontras


maksimum dari hitam ke putih dihitung dari kiri menuju kanan dan
berjalan terus sampai ke bagian paling atas dari suatu gambaran.
Sedangkan sudutnya diukur berlawanan arah jarum jam.

Yang sering terjadi dalam filter ini adalah nilai absolut dari
magnitude hanya sebatas penglihatan mata kita saja, apabila terdapat dua
24

komponen gradient maka akan digabungkan menggunakan operator


pseudo-convolution sbb:

Gambar 2.10 Kernel pseudo-convolution agar mempercepat


komputasi

Dengan menggunakan kernel pseudo-convolution seperti diatas


maka perhitungan yang terjadi adalah:

G = (P1 + 2 × P2 + P3 ) − (P7 + 2 × P8 + P9 ) +
(2.20)
(P3 + 2 × P6 + P9 ) − (P1 + 2 × P4 + P7 )

Pada kenyataannya operator Sobel memerlukan proses


perhitungan yang lebih lama dibandingkan dengan operator Robert Cross.
Akan tetapi, bila nantinya dalam proses digunakan kernel berukuran besar,
maka akan memperhalus gambar input sehingga nantinya akan mereduksi
noise. Keunggulan lain dari operator Sobel dibandingkan dengan Robert
Cross adalah nilai-nilai output dari proses konvolusi dengan Sobel lebih
akurat dan presisi. Hal ini dapat dibuktikan pada gambar dibawah ini:

Gambar 2.11 Salah satu input gambar yang diproses

Gambar 2.12 Gambar kiri adalah hasil dari operator Sobel,


sebelah kanan menggunakan operator Robert Cross
25

2.11 TRACKING DENGAN TEMPLATE MATCHING


2.10.1TEMPLATE MATCHING
Template matching adalah metode pemfilteran yang sederhana
dari pendeteksian fitur tertentu dalam sebuah gambar. Disediakan
tampilan dari fitur dalam gambar yang diketahui secara tepat, salah
satunya untuk mencoba mendeteksi dengan sebuah operator yang disebut
template. Template ini pengaruhnya yaitu subgambar yang terlihat seperti
gambar obyek. Menghitung kemiripan diperhitungkan bagaimana supaya
data gambar cocok dengan template untuk masing-masing lokasi template
yang memungkinkan. Titik maksimal yang dicocokkan dapat diseleksi
sebagai lokasi dari fitur.
2.10.2 KORELASI
Salah satu standart untuk pengukuran kemiripan antara fungsi
f(x) dan template t(x) adalah jarak Euclidean d(y) yang dikuadratkan,
dijelaskan dengan persamaan sebagai berikut ;

d(y) =
2

x
[ f(x) - t(x-y)]
2
(2.21)

M
dengan ∑x
artinya ∑
x=− M
, untuk beberapa M, N didefinisikan ukuran

dari luas template. Jika gambar pada titik y cocok maka d(y)=0, jika tidak
2
maka d(y)>0. Perluasan ekspresi untuk d dapat dilihat dengan
persamaan;
2
d (y) = ∑
x
2
[ f (x) – 2f(x)t(x-y) + t (x-y) ]
2
(2.22)

sebagai catatan bahwa ∑x


2
t (x-y) adalah konstan dan dapat diabaikan .

Ketika ∑x
2
f (x) kurang lebih konstan ini juga dapat dipotong, hal ini

disebut sebagai cross corelation antara f dan t.

R ft (y) = ∑ x
f (x) t (x-y) (2.23)
26

Hal ini dimaksudkan ketika porsi gambar berada dibawah t identik dengan
t.
Salah satu penggambaran template matching yaitu dihitung
dengan menggeser template melewati gambar untuk offset-offset yang
berbeda, kemudian nilainya dikalikan bersama-sama dan hasilnya
ditambahkan. Hasil penjumlahan ini akan membentuk pintu masuk
kedalam larik korelasi yang koordinatnya dicapai dari pusat template.
Jika template diberi keleluasaan untuk mengambil semua offset
ke gambar, sebagai contoh misalnya pengambilan lokasi yang tumpang
tindih, larik korelasi lebih besar daripada template atau gambar. Sebuah n
x n gambar dengan m x m template menghasilkan sebuah larik korelasi (n
+ m - 1x n + m -1), untuk m < n bentuk-bentuk lain hasil korelasi dari
perhitungan offset modulo ukuran gambar atau dengan kata lain template
mengelilingi gambar. Setelah digeser ke kanan selesai kemudian porsinya
yang benar ditampilkan kembali pada sisi kiri gambar. Korelasi yang
pendek ini disebut korelasi periodik dan jika tanpa properti- properti yang
mengelilingi disebut aperiodik. Salah satunya selalu dapat memodifikasi
input ke algoritma korelasi periodik dengan padding sisi luar dengan nol
sehingga outputnya adalah korelasi aperiodik. Banyak keuntungan dan
kerugian dari sistem pengukuran ini. Keuntungan dari penyederhanaan ini
utamanya untuk dikerjakan dengan adanya algoritma- algoritma untuk
melakukan penghitungan secara efisien untuk semua offset. Kerugiannya
yaitu metriknya sensitif untuk properti dari gambar yang berbeda-beda
dengan offset, contohnya rata-rata brightness sedikit mengalami
perubahan bentuk dari obyek, ukurannya, orientasi atau intensitas nilainya
juga dapat mengganggu pencocokan.

2.12 KOMPUTER GRAFIK MENGGUNAKAN OPENGL


OpenGL menyediakan banyak fungsi untuk kebanyakan grafik
primitif termasuk titik, garis, dan lingkaran. Masing-masing perintah atau
fungsi dalam OpenGL mempunyai struktur dan format yang sama. Hal ini
memudahkan untuk menebak bagaimana jalannya fungsi, dan bagaimana
argument dibutuhkan untuk melakukannya dan format tipe datanya.
27

glVertex2i(…..)

kepustakaan gl perintah dasar jumlah argument tipe


argument

Gambar 2.13 Susunan argument pada verteks

Contoh :
Perintah glVertex2i(100 , 25); berarti lokasi titik berada di (100,25)
Perintah glVertex2i(150,125); berarti lokasi titik berada di
(150,125)

Obyek 3 Dimensi
Obyek tiga dimensi adalah sebuah model struktur data yang
menyatakan suatu gambar 3D dibentuk dan disusun. Objek 3D
didefinisikan dengan :
a. Obyek 3D adalah sekumpulan titik-titik 3D (x,y,z) yang
membentuk luasan-luasan (face) yang digabungkan menjadi
satu kesatuan

b. Face adalah gabungan titik-titik yang membentuk luasan


tertentu atau sering dinamakan dengan sisi.

Dari definisi ini, dapat dikatakan bahwa objek 3D merupakan


kumpulan titik-titik dan kumpulan face yang merupakan susunan dari
titik-titik yang ditentukan. Seperti gambar kubus, kubus terdiri dari 8 titik
dan 6 sisi/face. Dimana face merupakan polygon atau kumpulan titik-titik
yang disusun urutannya. Dalam kubus, facenya semua berupa
bujursangkar dengan 4 titik.

Gambar 2.14 Obyek kubus mempunyai 8 titik dan 6 face


28

2.13 PEMROGRAMAN GLUT : Window dan Animasi


GLUT adalah kepanjangan dari GL utility toolkit, yang dibangun
oleh Mark Kilgard. Pada prinsipnya GLUT ini digunakan untuk
membangun aplikasi grafik, dan oleh karena itu GLUT banyak digunakan
untuk menangani windows dan proses animasi pada sebuah aplikasi yang
dibangun.
Perlu diketahui bahwa dasar dari pembuatan openGL adalah
untuk memisahkan ketergantungan dari beberapa sistem window yang
ada. Fungsi-fungsi yang ada pada openGL merupakan fungsi yang berada
pada domain 2D dan 3D namun tidak mengalami ketergantungan pada
sistem window yang dipakai. Pustaka openGL berkomunikasi dengan
sebuah native system melalui pustaka tambahan, sebagai contoh GLX
merupakan pustaka yang menangani interaksi antara openGL dengan
sistem X-window.
Fungsi-fungsi GLUT dapat diklasifikasikan menjadi beberapa
sub-API berdasarkan fungsionalitasnya yaitu :
1. Inisialisasi
2. Awal Event Processing
3. Window Management
4. Overlay Management
5. Menu Management
6. Callback Registration
7. Color Index Colormap Management
8. State Retrieval
9. Font Rendering
10. Geometric Shape Rendering

1. Inisialisasi

Setiap pemrograman yang menggunakan openGL harus dimulai


dengan inisialisasi GLUT state machine. Awalan inisialisasi glut adalah
“glutInit-”. Routine dari main inisialisasi glut adalah glutInit :
Contoh :

#include <GL/glut.h>

Void main(int argcp, char **argv){


glutInitWindowSize(640,480);
glutInitWindowPosition(0,0);
glutInitDisplayMode(GLUT_RGBA |
29

GLUT_SINGLE);
glutInit(&argcp,argv);
……. More code

};

Proses inisialisasi sebelumnya digunakan jika program yang akan


dibangun bukan sebuah aplikasi. Hal ini dikarenakan definisi inisialisasi
displaymode adalah GLUT_SINGLE yang berarti memori display
diinisialisasikan sebagai single buffer.
Konstanta Mode display inisialisasi GLUT.

GLUT_RGBA Memilih mode window RGBA. Hal ini


gagal jika kedua-duanya GLUT_RGBA
atau GLUT_INDEX tidak ditentukan.
GLUT_RGB Sama seperti GLUT_RGBA.
GLUT_INDEX Memilih mode window index warna.
Disini mengesampingkan GLUT_RGBA.
GLUT_SINGLE Memilih buffered window tunggal.
GLUT_DOUBLE Memilih buffered window ganda. Disini
mengesampingkan GLUT_SINGLE
GLUT_ACCUM Memilih window dengan mengumpulkan
buffer.
GLUT_ALPHA Memilih window dengan komponen alfa
menuju ke buffer warna.
GLUT_DEPTH Memilih window dengan sebuah depth
buffer.
GLUT_STENCIL Memilih window dengan sebuah stencil
buffer.
GLUT_MULTISAMPLE Memilih window dengan didukung proses
seleksi banyak sample.
GLUT_STEREO Memilih stereo window.
GLUT_LUMINANCE Memilih stereo window dengan model
warna luminance.

Contoh inisialisasi untuk sistem animasi


#include <GL/glut.h>
30

Void main(int **argcp, char **argv){

glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_RGBA |
GLUT_DOUBLE);
glutInit(&argcp,argv);

…..more code

};

Dua contoh proses sebelumnya pada dasarnya sama, namun


untuk yang kedua lebih ideal jika dipakai untuk penanganan aplikasi
animasi, dimana mode display double buffer berfungsi untuk menangani
flicker pada saat sekuen animasi berjalan.

2. Event Processing

Pada dasarnya GLUT itu sendiri adalah sebuah “state machine”,


sehingga dalam membangun program yang memanfaatkan GLUT perlu
dipertimbangkan sebuah konsep bahwa yang dijalankan adalah sebuah
event yang terjadi pada sebuah mesin. Ini berarti ada proses perulangan
yang terjadi berdasarkan pewaktu atau juga secara kontinyu apabila
sebuah proses inisialisasi sudah dilakukan dengan baik. Satu persatu
proses dijalankan sesuai dengan event yang diinisialisasikan ketika GLUT
diinisialisasi. Event-event tersebut seperti “mouse clicked”, “window
closed”, “window rhesape”, “cursor moved”, “keyboard keypresed”, dan
event yang paling aneh yaitu “idle” yang berarti saat tidak terjadi apa-apa.
Salah satu dari sekian event tersebut harus dideklarasikan pada saat GLUT
diinisialisasikan, baik secara waktu atau kontinyu, yang nantinya akan di
cek kebenaran kondisi event tersebut setelah mendapat trigger oleh
pengguna aplikasi oleh GLUT event processing.
Sebagai contoh untuk mendefinisikan event mouse “clicked
mouse button”, perlu dideklarasikan event dengan menggunakan
glut[events]Func(). Pada kasus ini berarti harus didefinisikan dengan
glutMouseFunc(fungsi routine mouse). Callback(pemanggilan ulang)
event ini berarti mengarahkan kepada sebuah fungsi atau subprogram pada
saat event mouse terjadi atau ditrigger oleh pengguna, sehingga jika fungsi
31

routine mouse yang kita bangun benama “mikimouse” maka definisi dari
callback fungsi mouse adalah glutMouseFuc(&mikimouse).
Salah satu dari fungsi callback yang ada di GLUT adalah
glutMainLoop(). Fungsi ini berarti proses yang ada di main program akan
diulangi secara terus menerus, sampai ada trigger untuk menghentikan
dengan paksa atau normal.

Contoh program
#include <GL/glut.h>

void main(int argcp, char **argv){

/* Initialize GLUT state */


glutInit(&argcp, argv);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);

/* Open a window */
glutCreateWindow("My OpenGL
Application");

/* Select type of Display mode:


Double buffer & RGBA color */
glutInitDisplayMode(GLUT_RGBA |
GLUT_DOUBLE);

/* Register Callback Functions */


.....

/* Start Event Processing Engine */


glutMainLoop();
};

Pada contoh tersebut terdapat sebuah fungsi callback yang belum


sempat dijelaskan yaitu glutCreateWindow (char **title). Fungsi ini
termasuk dalam kelompok GLUT window management, namun untuk
membangun sebuah aplikasi dasar tidak akan lepas dari satu fungsi ini,
32

dikarenakan dalam aplikasi yang dibangun akan lebih nyata jika


disertakan dengan sebuah window sebagai user interface.
Kembali ke pembicaraan semula yaitu mengenai event, pada
pemrograman menggunakan GLUT terdapat dua event pokok yang harus
diperhatikan yaitu glutDisplayFunc() dan glutIdleFunc(). Dua fungsi event
ini merupakan dasar dari state machine. Secara mendasar konsep ini dapat
dianalogikan bahwa setiap aplikasi yang dibangun akan mempunyai dua
kejadian (event) yaitu kejadian dimana aplikasi tersebut harus
menampilkan sesuatu yang akan digambarkan dan kejadian dimana
aplikasi tersebut diam tanpa adanya trigger dari pengguna. Kedua fungsi
ini memiliki parameter fungsi callback yang tidak bernilai atau void. Jika
dideklarasikan, misalnya untuk menggambar routine fungsi yang dibangun
adalah “void gambar(void)” maka deklarasi dari glut adalah
glutDisplayFunc(&gambar). Begitu pula dengan glutIdleFunc, misalnya
dideklarasikan dengan fungsi “void myIdle(void)” maka deklarasi
glutIdelFunc menjadi glutIdleFunc(&myIdle). Pertanyaan kenapa disini
event idle harus dideklarasikan, karena pada program aplikasi yang
bersifat animasi perlu dilakukan perubahan gambar setiap saat tanpa
adanya trigger yang diberikan, sehingga fungsi idle ini lebih cocok untuk
dimanfaatkan.

Contoh program
#include <GL/glut.h>

void MyIdle(void){
/* Some code to modify the variables
defining next frame */
....
};

void MyDisplay(void){
/* Some OpenGL code that draws a frame */
....
/* After drawing the frame we swap the
buffers */
glutSwapBuffers();
};

void main(int argcp, char **argv){


33

/* Initialize GLUT state */


glutInit(&argcp, argv);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);

/* Open a window */
glutCreateWindow("My OpenGL Application");

/* Select type of Display mode:


Double buffer & RGBA color */
glutInitDisplayMode(GLUT_RGBA |
GLUT_DOUBLE);

/* Register Callback Functions */


glutDisplayFunc(MyDisplay)
glutIdleFunc(MyIdle)

/* Start Event Processing Engine */


glutMainLoop();
};

Jika diperhatikan pada fungsi MyDisplay() terdapat pemanggilan


fungsi glutSwapBuffers(). Fungsi ini sangat berguna untuk penanganan
proses animasi dimana ketika proses inisialisasi glut diawal telah
didefinisikan glutDisplayMode(GLUT_RGBA | GLUT_DOUBLE). Hal
ini berarti memori untuk penanganan tampilan pada window didefinisikan
dengan mode double buffer. Dengan definisi ini proses animasi terjadi
dengan selalu menukar isi buffer pertama dengan isi buffer yang kedua.
Begitu seterusnya.

2.14 PLIB
PLIB merupakan singkatan dari Portable Game Library. PLIB
merupakan kumpulan pustaka yang mendukung untuk pembuatan sebuah
aplikasi grafik yang menggunakan bahasa pemrograman C++ dan
platform grafik openGL. Tujuan dari pembuatan PLIB ini untuk lebih
memudahkan proses pembuatan sebuah aplikasi dalam menangani proses
grafik seperti manajemen window, penanganan sistem suara, joystick, dan
perangkat lainnya. PLIB dilengkapi dengan pustaka efek suara, 3D engine,
34

Font Rendering, pustaka window sederhana, script bahasa pemrograman


game, pustaka metematis 3D, dan koleksi pustaka lainnya. Seluruh API
yang terdapat dalam pustaka PLIB dibangun dengan arsitektur
permrograman berorientasi obyek, hal ini akan lebih memudahkan ketika
penanganan atau pemanggilan obyek yang telah dibuat. PLIB berjalan
dalam platform sistem operasi Windows dan Linux dengan lisensi open
source. Saat ini PLIB versi terbaru adalah 1.8.4, kode source bisa di dapat
di alamat situs http://plib.sourceforge.net/download.html. nama dan
penjelasan mengenai pustaka yang terdapat di dalam PLIB sebagai
berikut.

1. Picoscopic User Interface Library


Picoscopic User Interface Library atau disingkat PUI merupakan
pustaka yang berisi sekumpulan obyek yang berkenaan dengan
penanganan GUI yang dibutuhkan oleh openGL atau C++. Pustaka ini
akan mempermudah proses pembuatan GUI pada aplikasi yang dibangun.
PUI terdiri dari object API yang dapat digunakan secara langsung
dengan menyisipkan kode API pada pemrograman dengan menggunakan
GLUT atau C++. Beberapa API yang terdapat dalam pustaka PUI
diantaranya adalah :
a. puFont.
b. puObjet.
c. puButton.
d. puOneshot.
e. puText.
f. puSlider.

2. Sound Library
Pustaka ini berisi obyek untuk penanganan driver sistem audio
yang dapat digunakan dalam pemrograman GLUT atau C++. Beberapa
API yang terdapat dalam pustaka ini adalah :
2.a. slDSP
2.b. slSample
2.c. slScheduler

3. Standard Geometry Library


Pustaka ini menangani beberapa fungsi dan variabel matematis
geometri. API yang disediakan dalam pustaka ini akan lebih
menyederhanakan pemrograman GLUT yang menyertakan fungsi
35

matematis dalam pembangunan sebuah aplikasi. Seperti misalnya fungsi


matrik dan vektor sudah tersedia dalam pustaka ini. API yang terdapat
dalam SGL adalah :
3.a. SGfloat
3.b. sgVect2
3.c. sgMat4
3.d. sgCoord

4. Simple Scene Graph Library


SSG atau simple scene graph merupakan pustaka yang berisi
fungsi grafik yang dalam implementasinya berada pada lapisan diatas
openGL, dengan kata lain SSG sendiri dibentuk dari kumpulan fungsi
openGL untuk memenuhi kebutuhan pengembangan grafik 3D scene.
Pada dasarnya SSG sendiri hanya berisi database pohon struktur yang
berisi hirarki percabangan dan daun dari percabangan. Setiap daun
percabangan merupakan fungsi render openGL. Daun percabangan ini
juga lebih mengarah pada penanganan Field of View (FOV), manajemen
Level of Detail (LOD), transformasi, dan animasi. Berikut ini hirarki yang
terdapat pada pustakan SSG :

--- Class SSGbase


|---Class ssgSimplelist
| |--class ssgVertexarray
| |--class ssgNormalArray
| |--class TexCoordArray
|
|---Class ssgEntity
| |--
| |--
|
|---Class ssgState
| |--
| |--
|---Class ssgTexture

5. PUI Auxiliary Library


Fungsi tambahan dari pustaka PUI, akan tetapi tidak semua
fungsi API yang terdapat pada PUI membutuhkan fungsi yang terdapat
dalam pustaka ini.
36

6. SSG Auxiliary Library


Sama halnya dengan PUI auxiliary, SSG auxiliary juga
merupakan fungsi pustaka tambahan untuk SSG, namun tidak semua
fungsi yang terdapat dalam pustaka SSG membutuhkan fungsi pustaka
SSG auxiliary.

7. Joystick Wrapper
Pustaka ini berisi fungsi API untuk penanganan joystick. Fungsi
penanganan joystick yang terdapat dalam pustaka ini lebih dari yang ada
pada GLUT. Meskipun penanganan joystick pada dasarnya bergantung
pada sistem operasi, fungsi yang terdapat dalam pustaka ini mampu
menangani banyak tipe joystik.

8. Fonts Text Library


Pustaka ini berisi fungsi API untuk proses render huruf dalam
aplikasi grafik. Bentuk huruf dapat dibentuk sedemikian rupa sehingga
hasil tampilan huruf lebih bervariasi.

9. Utility Library
Pustaka ini berisi fungsi API yang merupakan jembatan aplikasi
dengan sistem operasi. Ini memungkinkan dalam pembuatan aplikasi tidak
mengganggu fungsi yang ada dalam sistem operasi.
Dalam pustaka ini terdapat fungsi utilitas yang dapat dipanggil
yang berkenaan dengan sistem operasi, misalnya fungsi hitungan jam,
fungsi timer, fungsi pengaksesan direktori dan lain-lain.

10. Pegassus Network Library


Pustaka ini berisi fungsi API untuk penanganan Networking atau
lebih dikenal dengan istilah socket programming. Dengan API yang
tersedia aplikasi yang dibangun akan lebih mudah mengimplementasikan
program yang berisifat klien-server.
Konvensi untuk penulisan API pada pustaka ini diawali dengan
kata net dan untuk #define diawali dengan kata NET. Hirarki obyek kelas
yang terdapat dalam pustaka ini adalah sebagai berikut :

|---Class netAddress
|---Class netBuffer
| |---class netMessage
|
37

|----Class netGuid
|----Class netSocket
|-----class netChannel
| |
| |----class netBufferChannel
| |----class netChat
|-----class netMonitorServer

11. PLIB Scripting Language


Selain pustaka yang berisi API pada PLIB. PLIB juga memiliki
bahasa scripting yang bisa digunakan langsung. seperti halnya python,
perl, lua dan yang lainnya PSL memberikan kemudahan pembuatan
aplikasi untuk langsung berhubungan dengan pustaka yang ada dalam
PLIB. Bentuk scripting dalam PLIB mirip dengan bahasa pemrograman C
pada umumnya.
Kode berikut merupakan contoh pemrograman menggunakan
PLIB scripting language (PSL).

#include <plib/psl.h>

void main ()
{
pslInit () ;
pslExtension extensions [] = { { NULL, 0,
NULL } } ;
pslProgram *prog = new pslProgram (
extensions, "Program1" ) ;
prog -> compile ( "test.psl" ) ;
while ( prog -> step () != PSL_PROGRAM_END )
/* Nothing */ ;
}

12. PLIB Windowing Library


PWLIB merupakan pustaka yang menangani manajemen window
pada aplikasi yang dibangun. Di dalam pustaka ini berisi API yang bisa
digunakan seperti halnya pemrograman pada Visual Basic atau Delphi,
dimana penanganan sebuah window menjadi lebih mudah, seperti
38

penanganan event dan properti dari sebuah window. perbedaan dengan


bahasa pemrograman VB atau Delphi, PWLIB adalah window yang
dibentuk dari openGL.

Pemrograman Menggunakan PLIB


Pada dasarnya sebuah aplikasi grafik yang dibangun dengan
memanfaatkan API yang ada pada openGL, dapat langsung ditulis begitu
saja dalam program yang dibuat. Akan tetapi untuk membangun sebuah
aplikasi grafik yang berbasis X-window akan lebih rumit. Hal ini
dikarenakan proses yang dilakukan openGL bukanlah seperti proses pada
pemrograman yang berorientasi obyek. Dengan metode berorientasi
obyek, penanganan sebuah fungsi baik itu pembuatan baru atau
pemanggilan ulang akan lebih terstruktur dan mudah dikendalikan. PLIB
merupakan pustaka yang dibentuk untuk lebih memudahkan pemanfaatan
openGL dalam membangun sebuah aplikasi, misalnya sebuah game
multiplayer.
Untuk menggunakan PLIB sama halnya seperti menggunakan
openGL dalam pemrograman bahasa C, dimana file header (*.h) harus
ditulis lebih dahulu. Berikut ini penulisan header PLIB yang harus
dilakukan sebelum memanfaatkan pustaka PLIB.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <math.h>
#include <GL/glut.h>
#include <plib/pu.h>

Pada potongan kode tersebut tampak #include <plib/pu.h>, ini


berarti pustaka PLIB yang akan digunakan adalah fungsi-fungsi yang
terdapat dalam Picoscopic User Interface.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
39

#include <windows.h>
#else
#include <unistd.h>
#endif
#include <math.h>
#include <GL/glut.h>
#include <plib/pu.h>

void motionfn ( int x, int y )


{
puMouse ( x, y ) ;
glutPostRedisplay () ;
}

void mousefn ( int button, int updown, int x,


int y )
{
puMouse ( button, updown, x, y ) ;
glutPostRedisplay () ;
}

void displayfn ()
{
glClearColor ( 0.1, 0.4, 0.1, 1.0 ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;

puDisplay () ;

glutSwapBuffers () ;
glutPostRedisplay () ;
}

void button_cb ( puObject * )


{
fprintf ( stderr, "Hello World.\n" ) ;
}

int main ( int argc, char **argv )


{
glutInitWindowSize ( 240, 120 ) ;
40

glutInit ( &argc, argv ) ;


glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE |
GLUT_DEPTH ) ;
glutCreateWindow ( "PUI Application" ) ;
glutDisplayFunc ( displayfn ) ;
glutMouseFunc ( mousefn ) ;
glutMotionFunc ( motionfn ) ;

puInit () ;

puOneShot *b = new puOneShot ( 50, 50, 200, 80


) ;

b -> setLegend ( "Say Hello" ) ;


b -> setCallback ( button_cb ) ;

glutMainLoop () ;

return 0 ;
}

Object Picking

static void mousefn ( int button, int updown,


int x, int y )
{
if ( !puMouse ( button, updown, x, y ) )
{
// PUI didn't take the mouseclick, try the
main window
mouse_x = x ;
mouse_y = puGetWindowHeight () - y ;
// Check for an active widget.
// If there is one, call its active
callback
if ( puActiveWidget () )
puActiveWidget () ->
invokeActiveCallback () ;
}

glutPostRedisplay () ;
41

2.15 VIDEO FOR LINUX

1. Device
Video4Linux merupakan kumpulan API yang berfungsi untuk
penanganan video pada sistem operasi linux. Bagi yang telah familiar
dengan sistem operasi linux, Video4Linux biasanya sering dikenal dengan
“/dev/bttv”. /dev/bttv ini juga membentuk symlink ke /dev/video0.
Klasifikasi perangkat video pada sistem operasi linux berdasarkan type
Minor Range adalah sebagai berikut :

Nama Device: jarak minor: Fungsi:


/dev/video 0-63 Interface penangkapan video
/dev/radio 64-127 peralatan radio AM/FM
/dev/vtx 192-223 chip untuk perantara Teletext
/dev/vbi 224-239 Raw VBI data (Intercast/teletext)

Pada dasarnya program Video4Linux melakukan proses


pembukaan dan pencarian sebuah perangkat yang terkoneksi dengan
sebuah PC yang berjalan dengan sistem operasi linux. Kemampuan untuk
pencarian ini sepenuhnya ditangani oleh fungsi API yang ada dalam
Video4Linux, namun tidak semua fungsi API yang ada mampu berjalan
pada sebuah perangkat video. Hal ini bergantung pada jenis perangkat
yang digunakan. Fungsi-fungsi API yang terdapat pada Video4Linux akan
dijelaskan selanjutnya.

2. Kemampuan Query Ioctl


Ioctl VIDIOCGCAP berfungsi untuk mendapatkan informasi
kemampuan dari sebuah perangkat, hasil pengembalian dari pemanggilan
VIDIOCGCAP berupa variabel bertipe struct yang berisi :
name[32] nama canonical untuk interface
Type tipe interface
channels jumlah dari channel radio/tv
audios jumlah peralatan audio
maxwidth lebar capture maksimum dalam piksel
maxheight tinggi capture maksimum dalam piksel
minwidth lebar capture minimum dalam piksel
minheight tinggi capture minimum dalam piksel
42

Tipe ini menunjukkan flag kemampuan device. Hal ini ditunjukkan


sebagai berikut:
Nama Definisi
VID_TYPE_CAPTURE dapat mengcapture ke memori
VID_TYPE_TUNER memiliki tuner dari beberapa bentuk
VID_TYPE_TELETEXT memiliki kemampuan teletext
VID_TYPE_OVERLAY dapat menutup gambar pada bagian
atas frame buffer
VID_TYPE_CHROMAKEY penutup dikromakey
VID_TYPE_CLIPPING overlay clipping disupport
VID_TYPE_FRAMERAN overlay menumpuki memori frame
buffer
VID_TYPE_SCALES hardware mensupport skala gambar
VID_TYPE_MONOCHROME gambar hanya dicapture pada skala
abu-abu
VID_TYPE_SUBCAPTURE capture hanya bisa pada bagian
gambar

Ukuran minimum dan maksimum dilist untuk capture device, hal


ini tidak mengimplikasikan bahwa semua perbandingan tinggi/lebar atau
ukuran dalam jarak itu memungkinkan. Permintaan untuk mengeset
ukuran oleh ukuran capture terbesar yang tersedia dengan capturenya tidak
lebih besar daripada persegi yang diminta dalam salah satu perintah.
Sebagai contoh quickcam mempunyai 3 setingan yang tetap.

3. Frame buffer
Capture card yang mengalirkan data secara langsung kedalam
frame buffer dikatakan pengalamatan dasar dari frame buffer, merupakan
ukuran dan pengelompokan. Hal ini merupakan keistimewaan ioctl dan
salah satu kejadian X diset pada dirinya sendiri.

*VIDIOCSFBUF* ioctl mengeset parameter frame buffer untuk capture


card. Jika card tidak ditulisi langsung pada frame buffer maka ioctl ini
tidak akan disupport. *VIDIOCGFBUF* ioctl mengembalikan paramater
yang baru saja digunakan. Struct ini digunakan keduanya untuk *struct
video_buffer*

*void *base* pengalamatan fisik dasar dari buffer


*int height* tinggi dari frame buffer
*int width* lebar dari frame buffer
43

*int depth* kedalaman dari frame buffer


*int bytesperline* jumlah bit dari memory antara dimulainya dua
garis yang berdekatan.

Sebagai catatan bahwa nilai ini memberikan reflek physical layout dari
frame buffer. Area yang tampak ini mungkin lebih kecil. Secara nyata
dibawah XFree86 ini merupakan kasus yang umum. XFree86 DGA dapat
menyediakan parameter yang dibutuhkan untuk mengeset ioctl ini.
Menetapkan pengalamatan dasar untuk NULL mengindikasikan bahwa
tidak ada physical frame buffer yang mengakses.

4. Capture windows
Area capture digambarkan dengan *struct video_window*. Ini
mendefinisikan area capture dan pemotongan informasi jika berhubungan.
*VIDIOCGWIN* ioctl menutup setingan yang sudah ada dan
*VIDIOCSWIN* menentukan nilai yang baru. Panggilan yang berhasil
untuk *VIDIOCSWIN* mengindikasikan bahwa setingan yang cocok dari
parameter yang telah dipilih. Kesemuanya tidak mengindikasikan secara
persis apa yang diminta itu dibolehkan. Program memanggil
*VIDIOCGWIN* untuk memeriksa jika proses yang terdekat itu cocok.
*struct video_window* termasuk bidang-bidang yang mengikutinya.

*x* Koordinat X yang dikhususkan dalam format windows


*y* Koordinat Y yang dikhususkan dalam format windows
*width* Lebar dari gambar yang dicapture
*height* Tinggi dari gambar yang dicapture
*chromakey* Host meminta nilai RGB32 untuk chromakey
*flags* Flag capture tambahan
*clips* Daftar dari pemotongan empat persegi panjang. (hanya
diset)
*clipcount* jumlah dari pemotongan empat persegi panjang. (hanya
diset)

Pemotongan empat persegi panjang dilewatkan sebagai array. Masing-


masing potongan terdiri dari bagian - bagian sebagai berikut yang tersedia
untuk user.

*x* koordinat X dari empat persegi panjang untuk lompatan


*y* koordinat Y dari empat persegi panjang untuk lompatan
*width* lebar dari empat persegi panjang untuk lompatan
44

*height* tinggi dari empat persegi panjang untuk lompatan

Hanya menyeting window tidak bisa melakukan proses capturing. Lapisan


atas pengcapturan (sebagai contoh Transfer PCI-PCI ke frame buffer dari
video card) diaktifkan dengan melewatkan *VIDIOCCAPTURE* ioctl
yang nilainya 1, dan tidak bisa melewatkan sebuah nilai dari 0.

Beberapa peralatan capture dapat mengcapture sebuah sub bidang dari


gambar yang secara nyata terlihat. Hal ini diindikasikan ketika
VIDEO_TYPE_SUBCAPTURE didefinisikan. video_capture
menggambarkan waktu dan sub bidang yang khusus untuk mengcapture.
Struktur video_capture seperti yang ada dibawah ini

*x* koordinat x dari source persegi panjang untuk grab


*y* koordinat y dari source persegi panjang untuk grab
*width* lebar dari source persegi panjang untuk grab
*height* tinggi dari source persegi panjang untuk grab
*decimation* uraian untuk pemakaiannya
*flags* flag setting untuk proses grabbing

Flag-flag yang tersedia yaitu


Nama Penjelasan
*VIDEO_CAPTURE_ODD* hanya mengcapture frame ganjil
*VIDEO_CAPTURE_EVEN* hanya mengcapture frame genap

5. Source video
Masing-masing video pada video4linux atau peralatan audio
mengcapture dari salah satu atau lebih source *channels*. Masing-masing
channel dapat ditanyakan dengan memanggil *VIDIOCGCHAN* ioctl.
Sebelum meminta fungsi ini pemanggil harus mengeset bidang channel
untuk channel yang ditanyakan. Pada pengembalian *struct
video_channel* diisi dengan informasi tentang keaslian dari chanel itu
sendiri.

*VIDIOCSCHAN* ioctl mengambil sebuah argument integer dan switch-


switch capture sebagai input. Hal ini tidak didefinisikan apakah parameter
seperti seting warna atau tuning dijaga untuk melewati switch channel.
Pemanggil seharusnya menjaga setingan seperti yang diinginkan untuk
masing-masing channel. ( Hal ini dapat dimungkinkan seperti perbedaan
input video yang mempunyai perbedaan properti).
45

*struct video_channel* terdiri dari bagian-bagian sebagai berikut


*channel* jumlah channel
*name* nama input-yang lebih disukai untuk merefleksi
label pada card inputnya sendiri
*tuners* jumlah dari tuner untuk input ini
*flags* properti yang dimiliki tuner
*type* tipe input(jika diketahui)
*norm* aturan untuk channel ini

Definisi dari flags yaitu


*VIDEO_VC_TUNER* channel yang mempunyai tuner
*VIDEO_VC_AUDIO* channel yang mempunyai suara
*VIDEO_VC_NORM* channel yang mempunyai aturan setting

Tipenya didefinisikan sebagai berikut


*VIDEO_TYPE_TV* inputnya adalah input TV
*VIDEO_TYPE_CAMERA* inputnya adalah kamera

Properti gambar
Properti gambar dari foto dapat ditanyakan dengan
*VIDIOCGPICT* ioctl yang mengisi kedalam sebuah *struct
video_picture*.
*VIDIOCSPICT* ioctl yang melewatkan nilai untuk diubah. Semua nilai
yang diterima untuk tipe palette yaitu yang berskala antara 0-65535.

*struct video_picture* termasuk bagian-bagian sebagai berikut


*brightness* kecerahan gambar
*hue* warna-warni gambar (hanya untuk warna)
*colour* warna gambar (hanya untuk warna)
*contrast* kekontrasan gambar
*whiteness* sifat putih (hanya abu-abu)
*depth* kedalaman capture (membutuhkan untuk
mencocokkan kedalaman frame buffer)
*palette* menginformasikan palette bahwa seharusnya
digunakan untuk gambar ini.

Palette-palette tersebut didefinisikan sebagai berikut


*VIDEO_PALETTE_GREY* intensitas linier skala abu-abu (255
yang paling cerah)
46

*VIDEO_PALETTE_HI240* 8 bit BT848 warna kubus


*VIDEO_PALETTE_RGB565* RGB565 dikumpulkan kedalam 16 bit
kata-kata.
*VIDEO_PALETTE_RGB555* RGV555 dikumpulkan kedalam 16 bit
kata-kata, bit yang atas tidak
didefinisikan.
*VIDEO_PALETTE_RGB24* RGB888 dikumpulkan kedalam 24 bit
kata-kata
*VIDEO_PALETTE_RGB32* RGB888 dikumpulkan kedalam 3 byte
yang rendah dari 32 bit kata-kata. 8 bit
teratas tidak didefinisikan.
*VIDEO_PALETTE_YUV422* video model YU422 - 8 bit
dikumpulkan 4 bit Y 2 bit U 2 bit V
*VIDEO_PALETTE_YUYV* menerangkan model YUYV
*VIDEO_PALETTE_UYVY* menerangkan model UYVY
*VIDEO_PALETTE_YUV420* YUV420 capture
*VIDEO_PALETTE_YUV411* YUV411 capture
*VIDEO_PALETTE_RAW* RAW capture (BT848)
*VIDEO_PALETTE_YUV422P* YUV 4:2:2 planar
*VIDEO_PALETTE_YUV411P* YUV 4:1:1 planar

6. Tuning
Masing-masing channel input video dapat memiliki satu atau
lebih tuner yang dihubungkan dengannya. Banyak device yang tidak
memiliki tuner. TV card dan radio card akan memiliki satu atau lebih
tuner yang ditambahkan.

Tuner digambarkan dengan sebuah *struct video_tuner* yang


dapat dihasilkan dengan *VIDIOCGTUNER* ioctl. Menambahkan jumlah
tuner kedalam struktur kemudian melewatkan struktur ke ioctl untuk
memiliki data yang dimasukkan kedalamnya. Tuner dapat diswitch
menggunakan *VIDIOCSTUNER* yang mengambil sebuah integer yang
memberikan tuner untuk digunakan. Struct tuner memiliki bidang-bidang
sebagai berikut

*tuner* Jumlah dari tuner


*name* nama canonical untuk tuner ini (contoh FM/AM/TV)
*rangelow* frekuensi terendah yang dapat dipilih
*rangehigh* frekuensi tertinggi yang dapat dipilih
*flags* flag menggambarkan tuner
47

*mode* mode signal video jika cocok


*signal* kekuatan sinyal jika diketahui - antara 0-65535

Flag yang mengikutinya sebagai berikut


*VIDEO_TUNER_PAL* PAL tuning disupport
*VIDEO_TUNER_NTSC* NTSC tuning disupport
*VIDEO_TUNER_SECAM* SECAM tuning disupport
*VIDEO_TUNER_LOW* Frekuensinya pada jarak yang lebih
pendek
*VIDEO_TUNER_NORM* aturan untuk tuner yang dapat diset
*VIDEO_TUNER_STEREO_ON* Tuner melihat audio stereo
*VIDEO_TUNER_RDS_ON* Tuner melihat datastream RDS
*VIDEO_TUNER_MBS_ON* Tuner melihat datastream MBS

Mode-modenya didefinisikan sebagai berikut


*VIDEO_MODE_PAL* Tunernya dalam mode PAL
*VIDEO_MODE_NTSC* Tunernya dalam mode NTSC
*VIDEO_MODE_SECAM* Tunernya dalam mode SECAM
*VIDEO_MODE_AUTO* Tuner auto switch

Memilih frekuensi tanpa ditandai nilai 32 bit dalam 1/16th MHz atau jika
flag *VIDEO_TUNER_LOW* diset dalam 1/16th KHz. Frekuensi yang
digunakan sekarang dihasilkan sebagai waktu lama yang tanpa ditandai
melalui *VIDIOCGFREQ* ioctl dan diset dengan *VIDIOCSFREQ*
ioctl.

7. Membaca gambar
Masing-masing memanggil *read* syscall mengembalikan
gambar yang sudah tersedia selanjutnya dari device. Sampai pemanggil
menset format dan ukuran (menggunakan VIDIOCSPICT dan
VIDIOCSWIN ioctl) kemudian melewatkan buffer dengan ukuran yang
cocok dan panjang untuk fungsinya. Tidak semua peralatan akan
mensupport pembacaan operasi.

Cara yang kedua untuk menangani capture gambar adalah


melalui interface mmap jika disupport. Untuk menggunakan interface
mmap user pertama mengeset ukuran gambar yang diinginkan dan
kedalaman properti. Kemudian VIDIOCGMBUF ioctl dilaporkan.
Laporan dari ukuran buffer ini untuk mmap dan mengimbangi buffer
48

untuk masing-masing frame. Jumlah dari frame yang disupport tergantung


dari device dan mungkin hanya satu.

Struktur video_mbuf termasuk bidang-bidang dibawah ini

*size* jumlah dari byte untuk memetakan


*frame* jumlah dari frame
*offset* keseimbangan dari masing-masing frame

mmap dibuat VIDIOCMCAPTURE ioctl sekali untuk memulai capture ke


frame menggunakan format dan ukuran gambar yang dikhususkan dalam
video_mmap (yang seharusnya cocok). Ketika VIDIOCMCAPTURE ioctl
mengembalikan frame yang belum dicapture, driver hanya diinstruksi
hardware untuk memulai capture. Aplikasi yang dimiliki menggunakan
VIDIOCSYNC ioctl untuk menunggu sampai capture dari frame
diselesaikan. VIDIOCSYNC mengambil nomer frame yang diinginkan
untuk menunggu sebagai argument.
Ini diikuti untuk memanggil VIDIOCMCAPTURE multiple times (dengan
perbedaan jumlah frame dalam video_mmap-> frame tentunya) dengan
demikian mempunyai lebih dari satu permintaan capture outstanding. Cara
yang mudah mengerjakan untuk double-buffering menggunakan fitur
seperti yang diperlihatkan seperti ini:
/*setup everything*/
VIDIOCMCAPTURE(0)
while (whatever) {
VIDIOCMCAPTURE(1)
VIDIOCSYNC(0)
/* proses frame ke- 0 ketika hardware mengcapture frame 1*/
VIDIOCMCAPTURE(0)
VIDIOCSYNC(1)
/*proses frame 1 ketika hardware mengcapture frame 0 */
}
Sebagai catatan bahwa anda tidak dibatasi hanya untuk dua
frame. API melewatkan diatas 32 frame, VIDIOCGMBUF ioctl
mengembalikan banyaknya frame yang diijinkan oleh driver. Jadi
mungkin untuk membangun antrian yang lebih dalam untuk menghindari
kehilangan frame pada ujung beban.
Ketika mengcapture memory driver akan membuat usaha yang
baik percobaan untuk mengcapture layar sebaik yang diminta. Secara
49

normal artinya frame-frame yang kehilangan memory capture yang


dipetakan akan dimunculkan ke display.
Ioctl akhir ada untuk melewatkan device untuk menghasilkan
device yang dihubungkan jika driver memiliki lebih dari satu komponen
(sebagai contoh video0 tidak mungkin dihubungkan dengan vbi0 yang
mana seharusnya disebabkan program display intercast untuk membuat
kesalahan yang bodoh). VIDIOCGUNIT ioctl memberitahukan jumlah
unit dari device yang dihubungkan jika yang ada banyak. Struktur
video_unit memiliki bidang-bidang sebagai berikut.
*video* peralatan capture video
*vbi* peralatan capture VBI
*radio* peralatan radio
*audio* audio mixer
*teletext* peralatan teletext

8. RDS datastream
Untuk peralatan radio yang mensupportnya, ini mungkin untuk menerima
Radio Data System (RDS) data dengan utamanya dari membaca device.
Data dikumpulkan dalam tiga kelompok-kelompok, sebagai berikut:
Octet pertama Byte penting yang terkecil dari blok RDS
Octet kedua Byte yang terpenting dari blok RDS
Oktet ketiga Bit 7: bit error. mengindikasikan bahwa
kesalahan yang tidak bisa dibenarkan yang
terjadi selama penerimaan dari blok ini.
Bit 6 : bit yang benar. Mengindikasikan bahwa
kesalahan telah dibenarkan untuk blok data.
Bit 5-3 : keseimbangan yang diterima.
Mengindikasikan keseimbangan yang diterima
oleh sistem sync.
Bit 2-0 : Nama yang seimbang.
Mengindikasikan keseimbangan yang dipakai
untuk data ini.
50

-----Halaman ini sengaja dikosongkan-----


BAB III
PERENCANAAN DAN PERANCANGAN
SISTEM
3.1 Pendahuluan
Pada bab ini akan dijelaskan mengenai perencanaan dan
perancangan sistem. Pada dasarnya sistem yang dibangun merupakan
sebuah perangkat lunak yang memiliki fungsi melakukan tracking wajah
pada gambar sekuen dari video. Algoritma yang digunakan adalah
template matching dengan pendekatan korelasi. Sistem ini dibangun
pada platform sistem operasi Linux.
Sebagai masukan sistem yaitu berupa sekumpulan gambar yang
membentuk sekuen sebuah gerakan kepala. Gambar ini diambil dari
kamera selama selang waktu, setiap frame yang diambil dari kamera
akan disimpan mejadi file bitmap. File bitmap pertama akan diambil
untuk dibuat template. Dengan menggunakan algoritma korelasi antara
template yang dibuat dengan file bitmap frame ke-2 sampai ke-n, akan
ditemukan lokasi yang sama dengan template yang dibuat. Keluaran dari
sistem adalah titik lokasi wajah hasil tracking.

First frame

Template

Camera
Tracking Display

Facial Tracking
Template Matching

Captured Picture frame

Gambar 3.1. Blok diagram sistem face tracking

Pada gambar 3.1 tampak blok diagram sistem yang akan


dirancang yang ditinjau dari masukan yang diolah dan target yang ingin
dicapai. Bagian utama dari sistem ini adalah pada gambar 3.1 yaitu face

51
52

tracking sistem. Bagian ini memiliki arsitektur seperti tampak pada


gambar 3.2. Sistem memiliki beberapa bagian yang meliputi bagian
pengambilan data input yaitu berupa video capture subsistem, yang
kedua adalah bagian subsistem konversi dari gambar video yang diambil
menjadi bentuk frame. Dibagian ketiga terdapat sistem yang
memisahkan frame pertama dengan frame ke-2 sampai dengan ke-n.
Bagian selanjutnya adalah subsistem yang merupakan implementasi
algoritma, dimana semua proses perhitungan dengan algoritma korelasi
dilakukan. Pada bagian akhir adalah subsistem untuk menyimpan dan
menampilkan hasil yang diperoleh dari proses algoritma.

Gambar 3.2. Blok diagram Face Tracking Sistem

Penjelasan mengenai perancangan masing-masing bagian dari


blok sistem pada gambar 3.2 akan dijelaskan pada bagian selanjutnya
dalam bab ini. Sistem perangkat lunak ini dibangun dengan
menggunakan bahasa pemrograman C dengan dukungan pustaka
openGL, PLIB, dan berjalan pada sistem operasi Linux versi kernel
2.6.8. Detail spesifikasi teknis PC dan pustaka tertera pada tabel 3.1.

Tabel 3.1 Spesifikasi teknis perangkat lunak face tracking sistem.


No Deskripsi Spesifikasi
1 CPU P IV 1700 MHz 40 Gb Hardisk

2 RAM 256 MB
3 Graphic Card Nvidia MX2 400 64MB
4 GCC Versi 3.3
5 PLIB 1.8.3
6 Video4Linux Versi 1
7 OpenGL Versi 2.0
8 Sistem Operasi Linux/GNU Debian
9 Kernel 2.6.8-386
53

3.2 Penangkapan dan Pemrosesan Gambar Video


Bagian penangkapan dan pemrosesan video meliputi, video
capture, video to frame converter.

3.2.1 Linux video


Penangkapan gambar dilakukan dengan menggunakan sebuah
kamera digital dengan spesifikasi teknis yang tertera pada tabel 3.2

Tabel 3.2 Spesifikasi teknis kamera digital


Spesifikasi Definisi

Hardware Resolution 1248 x 960 Pixels


Image Sensor 1.3M CMOS
Image Capacity 1248 x 960 - up to 50
Pictures
640 x 480 - up to 160
Pictures
AVI Movie Format 624 x 480 (HR) 30 seconds
@ 10 fps
320 x 240 (LR) 120 seconds
@ 10 fps
Video Conferencing 320 x 240 Pixels (up to 20
fps)
Internal Memory 16 MB Built-in SDRAM (for
AVI)
16 MB Built-in Flash (for
Stills)
External Memory None
Self-Timer 10 second Timer with Beep
Image Control Auto Exposure, Auto White-
Balance
Shutter Speed Electric Variable Speed
Image Format JPEG, AVI (through
software)
Frame Counter 3 Digit LCD Display
Computer Interface USB
Linux driver SPCA5XX
54

Gambar 3.3 Mini PenCam

Untuk bisa menggunakan kamera sebagai media penangkapan


gambar, sistem operasi harus bisa mengenali kamera yang digunakan
sebagai perangkat video. Pada sistem operasi Linux perangkat video
dikelompokkan dalam satu modul yaitu ”videodev”, selain modul ini
modul pendukung lainnya berupa jenis koneksi kamera, apakah itu USB
atau serial. Pada sistem ini jenis kamera yang digunakan adalah USB
kamera, pada sistem operasi Linux modul yang menangani perangkat
USB adalah modul ”USBCORE”.
Kedua modul Videodev dan USBCORE harus sudah tersedia
dalam sistem operasi Linux. Jika ini belum tersedia maka kamera akan
gagal untuk dikenali. Dengan melakukan rekompilasi kernel dan
memasukan opsi pilihan modul tersebut pada kernel yang akan
direkompilasi maka kedua modul tersebut akan masuk dalam sistem
operasi. Modul tersebut akan secara otomatis ada apabila driver kamera
yang digunakan mendukung pada sistem operasi linux. Kebanyakan
kamera-kamera yang bisa didapat tidak semuanya bisa didukung oleh
sistem operasi Linux.
Kamera digital yang digunakan pada sistem yang dibangun ini
didukung oleh sistem operasi Linux. Driver yang mendukung adalah
SPCA5XX. Driver ini bisa didapat dengan men-download di website :”
http://mxhaard.free.fr/download.html”.
Ketika driver kamera sudah diinstal dengan baik tanpa kendala
kesalahan, maka pada saat kamera dicolokan melalui port USB, sistem
operasi akan secara otomatis mengaktifkan modul driver dan modul
video4linux. Untuk memastikan keberadaan kedua modul, videodev dan
usbhid dapat dilakukan dengan mengetikkan perintah pada shell :
55

>lsmod

3.2.2 Video capture


Penangkapan video dilakukan dengan membangun sebuah
perangkat lunak yang mendukung pustaka yang terdapat dalam
video4linux, seperti yang telah dijelaskan pada bab 2.

Gambar 3.4 Diagram alir proses penangkapan gambar


video
Diagram alir sistem penanganan kamera berserta penangkapan
gambar tampak pada gambar 3.4. Proses yang dilakukan pertama kali
adalah openvideo. Pada dasarnya fungsi openvideo ini adalah proses
inisialisasi kamera. Dalam proses ini tahapan yang dilakukan dengan
menggunakan fungsi API pada video4Linux adalah mencari perangkat
kamera yang aktif. Kamera yang aktif akan dialamatkan pada file
/dev/video oleh sistem operasi linux. Dengan memanggil dan membuka
file /dev/video, sama artinya dengan membaca alamat memori dari
perangkat video atau kamera. Tahapan ini tidak hanya membuka file
saja, akan tetapi identifikasi jenis dan kemampuan perangkat akan
56

dibaca, dan hasil pembacaan ini ditampung dalam sebuah variabel yang
bertipe struct. Potongan kode 3.1 merupakan proses pembukaan file
/dev/video.

Kode 3.1 Program open /dev/video

#include "bcapv4l.h"

static unsigned char *frame_buf;


int CaptV4LOpen(char *device_name){
int fd;
if((fd=open(device_name,O_RDWR))==-1){
return -1;
}
return fd;
}

int CaptV4LGetDeviceCapability(int fd,struct


video_capability *vcap){
if(ioctl(fd,VIDIOCGCAP,vcap)==-1){
return -1;
}
return 0;
}

int CaptV4LGetChannelInfo(int fd, struct


video_channel vch[MAX_NO_CHANNEL],int
no_channel){
int i;

for(i=0;i<no_channel;i++){
vch[i].channel = i;
if( ioctl(fd, VIDIOCGCHAN,
&vch[i])==-1){
return -1;
}
}
return 0;
}
57

Selain mengidentifikasi kemampuan perangkat yang digunakan


openvideo juga melakukan identifikasi channel. Identifikasi channel
dilakukan untuk menentukan jenis format data masukan, yang meliputi
Tunner, Audio, Camera, PAL, NTSC, dan Secam. Jika proses ini
berhasil dijalankan fungsi akan mengembalikan nilai ”0”, dan proses
selanjutnya adalah tahapan penangkapan gambar dan menampilkannya
pada sistem window.

Kode 3.2 Inisialisasi video4linux

int videoInitCaptureDevice(char
*device_name,int channel_no){
struct video_capability vcap;
struct video_channel vch[MAX_NO_CHANNEL];
struct video_picture vp;

//inisialisasi device video


if((fd=CaptV4LOpen(device_name))==-1){
fprintf(stderr,"Tidak bisa membuka
device %s.\n",device_name);
exit(-1);
}
printf("Device name = %s\n",device_name);
if(CaptV4LGetDeviceCapability(fd,&vcap)==
-1){
fprintf(stderr,"Tidak bisa
mendapatkan informasi device.\n");
exit(-1);
}
// printf("stage -1\n");
CaptV4LDisplayDeviceCapability(vcap);

if(CaptV4LGetChannelInfo(fd,vch,vcap.chan
nels)==-1){
fprintf(stderr,"Tidak bisa
medapatkan informasi channel.\n");
exit(-1);
}
printf("channel : %d\n",vcap.channels);
58

if(CaptV4LGetMemoryMapInfo(fd,&vm)==-1){
fprintf(stderr,"Tidak bisa
mendapatkan informasi pemetaan memory.\n");
exit(-1);
}

CaptV4LGetPictureInfo(fd,&vp);
CaptV4LDisplayPictureInfo(vp);

CaptV4LDisplayChannelInfo(vch,channel_no)
;

if(CaptV4LSelectChannel(fd,vch,channel_no
)==-1){
fprintf(stderr,"Tidak bisa memilih
channel.\n");
exit(-1);
}

if(CaptV4LMemoryMapping(fd,vm)==-1){
fprintf(stderr,"Tidak bisa
memetakan frame buffer.\n");
exit(-1);
}

vmap.width=CAPTURE_IMAGE_WIDTH;
vmap.height=CAPTURE_IMAGE_HEIGHT;
vmap.format=VIDEO_PALETTE_RGB24;

CaptV4LDisplayMemoryMapInfo(vm);
CaptV4LDoubleBufferingInitCapture(fd,&vma
p);

return 0;

Kode 3.2 merupakan proses lengkap dari inisialisasi perangkat


kamera, dimana seperti yang telah dijelaskan sebelumnya, setelah
informasi channel berhasil didentifikasi maka sistem akan melanjutkan
59

pada proses identifikasi gambar. Identifikasi gambar merupakan fungsi


untuk memperoleh data ukuran gambar yang dapat ditampilkan oleh
perangkat yang bersangkutan. Setiap perangkat memiliki kemampuan
ukuran gambar yang berbeda-beda. Pada sistem ini kemampuan gambar
maksimal yang bisa dilakukan adalah 640x480. Dari informasi ukuran
ini kemudian akan dijadikan referensi proses selanjutnya yaitu mapping
memori dinamik. Kesalahan alokasi memori dinamik akan
menyebabkan sistem tidak berjalan atau keluar dengan paksa, karena
terjadi kesalahan segmentation fault.
Penangkapan gambar dan penampilan pada sistem window
dilakukan dengan teknik double buffer. Dengan menggunakan teknik ini
sistem penangkapan jauh lebih cepat dan gambar yang dihasilkan lebih
jelas. Pada kode 3.3 tampak bagaimana sistem penangkapan dengan
double buffer dilakukan.

Kode 3.3 Program penangkapan gambar video


void videoCaptureImage(){
static char
image_prefix[1024]=PREFIX_IMAGE_FILE;
// static unsigned char
skin_map[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS];

CaptV4LDoubleBufferingCaptureWait(fd,&vma
p);
CaptV4LSetImageDownSamplingForOpenGL(vmap
,vm,DOWN_SAMPLING_RATE,image,disp_image);

if(CaptV4LDoubleBufferingCaptureNextFrame
(fd,&vmap)==-1){
fprintf(stderr,"Tidak bisa
mengambil frame berikutnya.\n");
exit(-1);
}

// CaptV4LDisplayPictureInfo(vptemp);
if(save_flag==1){

videoSavePPMImage(image,IMAGE_HEIGHT_DS,I
MAGE_WIDTH_DS,frame_no,image_prefix);
frame_no++;
60

videoDisplayImage();
glutSwapBuffers();

if(exit_flag){
exit(0);
}

3.2.3 Video to frame image sequence converter

Gambar 3.5. Diagram alir video to frame image sequence


converter
61

Konsep kerja dari subsistem konversi video menjadi frame


image sequence adalah dengan menangkap data frame yang ditampilkan
pada sistem window yang kemudian disimpan menjadi file bitmap.
Penamaan file disesuaikan dengan nomer frame yang ditangkap.
Pada saat awal penangkapan video variabel penghitung di
inisialisasi dengan memberikan nilai 0. Ketika frame data sudah
ditampung kedalam buffer, maka data tersebut dituliskan ke dalam
buffer file bitmap. Setelah proses penyimpanan berhasil dilakukan
variabel penghitung akan menaikkan hitungannya sebesar 1. Dengan
teknik seperti ini, file yang disimpan akan memiliki nama
“namafile_x.bmp”, dimana x merupakan string yang diambil dari
variabel penghitung saat itu.

Kode 3.4 Video to frame converter

void videoDisplayImage(){
glRasterPos2i(50,200);
glDrawPixels(IMAGE_WIDTH_DS,IMAGE_HEIGHT_
DS,GL_BGR,GL_UNSIGNED_BYTE,disp_image);
glFlush();
}

void videoMouseCheck(int button,int status, int


x, int y){
if(button == GLUT_LEFT_BUTTON && status
== GLUT_DOWN){
exit_flag=1;
}
}

void videoSavePPMImage(unsigned char *image,int


iheight, int iwidth,int frame_no,char
*image_prefix){
char file_name[1024];

FILE *fp;
sprintf(file_name,"%s_%d.ppm",image_prefi
x,frame_no);
if((fp=fopen(file_name,"w"))==NULL){
fprintf(stderr,"Tidak dapat membuka
62

file : %s\n",file_name);
exit(1);
}
fprintf(fp,"P6 %d %d
255\n",iwidth,iheight);
fwrite(image,iheight*iwidth*RGB,1,fp);
fclose(fp);
}

unsigned char* getDisplayImage(){


return disp_image;
}

3.3 Implementasi Algoritma


Sistem face tracking dibangun dengan pendekatan algoritma
korelasi. Sistem ini bekerja dengan membandingkan tingkat intensitas
template yang dibuat dengan titik lokasi tertentu objek yang akan di
tracking.
63

Gambar 3.6 Algoritma Face Tracking


64

3.3.1 Image Processing


Sebelum algoritma diterapkan, terdapat proses yang bersifat
opsional, namun proses ini dapat membantu algoritma berjalan dengan
baik. Proses ini adalah perbaikan gambar atau citra.
Dalam sistem face tracking yang dibangun, perbaikan gambar
dilakukan dengan menambahkan beberapa filter dan segmentasi gambar.
Filter yang bisa digunakan pada sistem ini meliputi gaussian filter, mean
filter, dan median filter. Sedangkan untuk segmentasi gambar meliputi
threshold dan greyscale. Ketersediaan ini dapat dimanfaatkan untuk
lebih memaksimalkan algoritma yang dijalankan. Tampak pada kode 3.5
proses filter dan threshold yang telah dibuat. Program berikut ini adalah
contoh program dari filter rata-rata (mean filter) yang didapat dari rumus

1
h(x,y) =
M
∑ f (k , l )
( k ,l )∈N
(3.1)

Dimana M adalah jumlah piksel-piksel pada jendela sebesar NxN.


Sebagai contoh pada program dibawah ini daerahnya adalah 3x3 ( N=3,
M=9) pada tetangga (x,y). Jadi dari sini dihitung rata-ratanya dari
intensitas pada beberapa piksel lokal dimana setiap piksel akan
digantikan nilainya dengan rata-rata dari nilai intensitas piksel tersebut
dengan piksel-piksel tetangganya.
Untuk segmentasi citra dengan treshold, program dibawah ini
menggunakan acuan sebagai berikut;
If F[x,y] ≥ Tr
F[x,y] = obyek = 1
Else
F[x,y] = background = 0

Teknik ini didasarkan pada konsep yang sederhana yaitu


membandingkan data citra setiap piksel dengan parameter ambang ( Tr
). Parameter ambang dipilih dan diberikan pada suatu citra F[x,y]. Jadi
untuk algoritma diatas diasumsikan bahwa obyek diberi warna putih dan
background diberi warna hitam.
65

Kode 3.5 Filter dan treshold


void meanFilterfn(){
int a,r,g,b;
unsigned int tempR[9];
unsigned int tempG[9];
unsigned int tempB[9];

for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
a=0;
for(int k=-1;k<=1;k++){
for(int l=-1;l<=1;l++){

tempR[a]=getR(image1,j+l,i+k);

tempG[a]=getG(image1,j+l,i+k);

tempB[a]=getB(image1,j+l,i+k);
a++;
}
}
r=0;g=0;b=0;
for(int k=0;k<9;k++){
r=r+tempR[k];
g=g+tempG[k];
b=b+tempB[k];
}
setR(image2,j,i,r/9);
setG(image2,j,i,g/9);
setB(image2,j,i,b/9);
}
}
loadTexture(2,image2);
}
.
.
void tresholdfn(){
int a;
for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
66

a=(getR(image1,j,i)+getG(image1,j,i)+getB
(image1,j,i))/3;
if(a<=100){
setR(image2,j,i,0);
setG(image2,j,i,0);
setB(image2,j,i,0);}
else if(a<=160){
setR(image2,j,i,0);
setG(image2,j,i,0);
setB(image2,j,i,0);
}
else{
setR(image2,j,i,255);
setG(image2,j,i,255);
setB(image2,j,i,255);
}

}//loop j
}//loop j
loadTexture(2,image2);
}

3.3.2 Pembuatan template


Template adalah potongan gambar dengan ukuran tertentu yang
diambil dari sebuah gambar dengan ukuran besar. Ukuran template
biasanya sebesar ukuran sebuah fitur wajah yang terdapat pada gambar,
contohnya template mata memiliki ukuran sama dengan ukuran mata
yang terdapat pada gambar wajah. Template ini berfungsi sebagai
referensi pada saat pencarian fitur target pada gambar wajah di gambar-
gambar sequen yang lain. Teknik seperti ini sudah banyak digunakan
pada aplikasi komputer vision yang lain, terutama untuk pencarian cepat
sebuah target pada gambar atau video.
Pada sistem yang dibangun ini, template dibuat dengan ukuran
dinamik dan diambil dari frame/sequen ke-1. Dinamik disini memiliki
arti bahwa setiap kali melakukan pembuatan template, ukuran yang
dibuat dapat berubah-ubah. Dengan menggunakan alat bantu mouse,
ukuran template dapat disesuaikan dengan ukuran fitur target yang
terdapat pada gambar. Disini juga ditentukan jumlah maksimal 4
template yang bisa dibuat.
67

Kode 3.6 Proses pembuatan template


.
.
void createTemplate_cb(puObject *){
if(edit_mode == 0){
edit_mode = 1;
flag_template=1;
for(int i = 0; i <
JUMLAH_SEGIEMPAT_YANG_BISA_DIBIKIN*2;i++){
titik[i][0] = 0;
titik[i][1] = 0;
}
hitmos = 0;
}else{
edit_mode = 0;
flag_template=0;
}

}
.
.
void mousefn(int button, int updown,int x,int
y){
int w,h;
w=puGetWindowWidth();
h=puGetWindowHeight();
puMouse(button,updown,x,y);
curr_button = button;
updateEventQueue(curr_button,x,y,updown ==
PU_DOWN);
if(button==GLUT_LEFT_BUTTON &&
updown==GLUT_DOWN && edit_mode==1 &&
draw_enable==1){
//kalo dah max gak usah nggambar
lagi
if(hitmos <
JUMLAH_SEGIEMPAT_YANG_BISA_DIBIKIN*2 ){
titik[hitmos][0]=x;
titik[hitmos][1]=h-y;
68

if( hitmos%2==0){
titik[hitmos+1][0]=x;
titik[hitmos+1][1]=h-y;
}
hitmos++;
}

}
//ngapus semua kotak saat klik kanan
if(button==GLUT_RIGHT_BUTTON &&
updown==GLUT_DOWN){
for(int i = 0; i <
JUMLAH_SEGIEMPAT_YANG_BISA_DIBIKIN*2;i++){
titik[i][0] = 0;
titik[i][1] = 0;
}
hitmos = 0;
}
}

Hasil pembuatan template pada sistem ini dapat disimpan ke


dalam file *.bcd dan bisa diambil kembali ketika akan melakukan
tracking ulang. File ini menyimpan nilai posisi koordinat template pada
gambar. Kode 3.7 berikut merupakan proses penyimpanan file template

Kode 3.7 program penyimpanan file template


.
.
char guess_fname[PUSTRING_MAX];

strcpy(guess_fname,dataFilename);
for(int
i=strlen(guess_fname);i>=0;i--)
if(guess_fname[i]=='.'){
guess_fname[i]='\0';
break;
69

}
strcat(guess_fname,".bcd");
pfileSelector-
>setInitialValue(guess_fname);
.
.
if(pfileSelector-
>getStringValue()[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
//dialog("Gagal Menyimpan
Template",1,0,0);
return;
}
FILE *fd=fopen(pfileSelector-
>getStringValue(),"wa");
puDeleteObject(pfileSelector);
pfileSelector=NULL;

if(fd==NULL){
//dialog("Tidak bisa membuat
file template",1,0,0);
return;
}
fwrite(titik,sizeof(int),16,fd);
fclose(fd);
//dialog("Penyimpanan sukses
!!!!",1,1,0)

3.3.3 Perhitungan tingkat intensitas gambar template


Pada dasarnya algoritma korelasi yang digunakan pada sistem
ini memiliki parameter utama adalah besar nilai intensitas, yaitu
intensitas template dan intensitas gambar.
Intensitas template dihitung dengan mendapatkan jumlah nilai
normalisasi RGB untuk semua piksel yang termasuk dalam template.
Begitu juga dengan perhitungan nilai intesitas pada gambar. Nilai
intensitas ini disimpan kedalam sebuah variabel global, ini dimaksudkan
supaya nilai tersebut bisa dipanggil dari semua bagian pada perangkat
lunak.
70

3.3.4 Komputasi Korelasi


Pada sistem ini perancangan untuk komputasi algoritma
kolerasi, diawali dengan melakukan perhitungan nilai intensitas titik
pada gambar template dengan ukuran nxn. Jika diberikan gambar
template n x n dan gambar yang akan dijadikan objek pelacakan m x m.
nilai intensitas pada masing-masing titik di dapat dengan menggunakan
persamaan berikut :
r + g +b
Intensitas (i,j)= (3.2)
3
Nilai intensitas pada masing-masing posisi kemudian dihitung dengan
persamaan korelasi sebagai berikut:
n n

∑∑ M (i, j ) N (i, j )
i =1 j =1
Korelasi : (3.3)
n n n n
[∑∑ M (i, j ) 2 ∑∑ N (i, j ) 2 ]1/ 2
i =1 j =1 i =1 j =1

dimana: M = Template
N = Image
Diagram alir dari komputasi korelasi tampak pada gambar 3.7.
Proses awal komputasi algoritma korelasi adalah mengambil nilai
intensitas pada seluruh lokasi gambar template, dan dilanjutkan dengan
mengambil nilai intensitas pada gambar obyek yang seukuran dengan
template. Hasil pembacaan ini kemudian akan dijadikan nilai
perhitungan pencarian korelasi. Pada saat awal proses berjalan nilai
korelasi maksimum diset sama dengan 0.
71

Gambar 3.7 Algoritma korelasi

Perhitungan korelasi dilakukan di seluruh posisi titik pada gambar obyek


yang akan dilacak. Secara perhitungan perulangan yang terjadi pada
proses pencarian untuk gambar obyek dengan ukuran 320 x 240 piksel
adalah :
jumlah titik pencarian = (320 – lebar template) x (240 – tinggi template).
72

sehingga,
apabila ukuran template 100 x 100 piksel
maka,
jumlah titik pencarian = (320-100) x (240-100)
= 220 x 140
= 30800
Pada setiap kali perulangan perhitungan korelasi, nilai yang didapat
akan dibandingkan dengan korelasi maksimum. Jika nilai korelasi saat
ini lebih besar dari nilai korelasi maksimum, maka korelasi maksimum
akan dirubah, yaitu korelasi maksimum = korelasi saat ini. sehingga
pada akhir perulangan didapat nilai korelasi tertinggi.

Kode 3.8. Perhitungan algoritma korelasi


void findCorrelation(TempImage *tImage,Image
*image,unsigned data[4]){
unsigned int i,j,k,l;
unsigned int pr,pg,pb,pgs;
unsigned qr,qg,qb,qgs;
float p,q,r,s;
int ssd=0;
double coreVal,t;
for(i=0;i<image->sizey-tImage->sizey;i++){
for(j=0;j<image->sizex-tImage-
>sizex;j++){
p=0;q=0;r=0;s=0;t=0;
ssd=0;
coreVal=0.0;
for(k=0;k<tImage->sizey;k++){
for(l=0;l<tImage-
>sizex;l++){
73

pr=tImage-
>data[(k*tImage->sizex+l)*3];
pg=tImage-
>data[(k*tImage->sizex+l)*3+1];
pb=tImage-
>data[(k*tImage->sizex+l)*3+2];
pgs=(pr+pg+pb)/3;

qr=getR(image,j+l,i+(tImage->sizey-k));

qg=getG(image,j+l,i+(tImage->sizey-k));

qb=getB(image,j+l,i+(tImage->sizey-k));
qgs=(qr+qg+qb)/3;
p+=float(qgs*pgs);
q+=float(qgs*qgs);
r+=float(pgs*pgs);
ssd+=int ((qgs-
pgs)*(qgs-pgs));
}//loop l
}//loop k
s= q*r ;
t=sqrt(s);
coreVal=double(p/t);
if(coreVal>=0.98){
data[0]=j;data[1]=i;
data[2]=tImage->sizex;
data[3]=tImage->sizey;
printf("nilai ssd = %d x =
%d y = %d \n",ssd,j,i);
printf("p= %.2f q= %.2f r=
%.2f s= %.2f t = %.2lf correlation =
74

%.4lf\n",p,q,r,s,t,coreVal);
flag_viewTracking=1;
//return;
}
}//loop j
}//loop i
}

3.4 Sistem GUI


GUI atau Graphics User Interface, adalah antarmuka aplikasi
yang dibangun dengan pengguna. Pembuatan GUI pada sistem ini
dirancang dengan mempertimbangkan aspek kenyamanan pada
pengguna. Namun disisi lain aspek performa juga menjadi pertimbangan
yang utama. Sistem GUI dibuat dengan memanfaatkan pustaka yang
terdapat dalam openGL, dan pustaka PLIB.

3.4.1 Window utama


Window utama pada sistem ini memiliki ukuran awal 800x600
piksel. Kemungkinan untuk merubah ukuran window di sistem ini masih
dimungkinkan. Window utama inilah yang akan menjadi ruang tampilan
untuk seluruh proses yang dilakukan oleh sistem face tracking.
Potongan kode 3.8, memperlihatkan bagaimana window utama
dibuat, mulai dari ukuran window dan judul window. Proses pertama
kali yang dilakukan adalah melakukan inisialisasi window dan sistem
openGL. Proses ini kemudian dilanjutkan dengan penunjukan fungsi-
fungsi pada openGL. Fungsi tersebut meliputi fungsi display, fungsi
reshape, fungsi mouse, fungsi keyboard, dan fungsi idle.
Fungsi display menjadi fungsi utama dalam sistem GUI yang
dibangun. Fungsi ini berisi kode dari pustaka openGL untuk
menampilkan gambar yang akan diproses dan juga hasil dari proses
yang dilakukan. Selain itu juga pada fungsi utama GUI terdapat
beberapa proses yang menangani sistem interaksi user, misalnya button,
menufile, dan lain-lain. Komponen button, menu ini dibuat dengan
memanfaatkan pustaka PLIB.
Untuk membuat sebuah dialog interaksi user contohnya
command button, terdapat beberapa prosedur fungsi yang harus
dipenuhi. Pada dasarnya ketika sebuah komponen (misalnya command
button) dibuat, yang harus dilakukan adalah menginisialisasi pembuatan
75

komponen tersebut dengan perintah kode ”new”, setelah itu kemudian


dikuti dengan inisialisasi properti awal seperti ukuran, lokasi, dan state
(kondisi) awal dari komponen tersebut. Proses yang terakhir untuk
membuat sebuah komponen pada sistem GUI adalah menentukan fungsi
callback dari komponen tersebut. Fungsi callback merupakan fungsi
yang dipanggil ketika event yang dimaksud, terjadi komponen tersebut.
Contoh event misalnya ”on-mouse-click” potongan kode 3.9
menunjukkan bagaimana sebuah komponen dibuat pada sistem face
tracking.

Kode 3.9 Inisialisasi GUI


void init_graphic(){
int w,h;
int fake_argc = 1;
char *fake_argv[3];
fake_argv[0]="CORRELATION BASED TEMPLATE
MATCHING FACE TRACKING ON IMAGE SEQUENCE";
fake_argv[1]="EMBOH VERSION";
fake_argv[2]=NULL;
.
.
glutInitWindowPosition(0,0);
glutInitWindowSize(800,600);
glutInit(&fake_argc,fake_argv);
glutInitDisplayMode(GLUT_RGBA |
GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
glutCreateWindow(fake_argv[0]);
initRender();
openTexture();
loadTexture(1,image1);
loadTexture(2,image2);
videoInitCaptureDevice("/dev/video0",0);
glutDisplayFunc(&redraw);
glutIdleFunc(&videoCaptureImage);
glutReshapeFunc(&reshape);
glutKeyboardFunc(&keyfn);
glutSpecialFunc(&specialfn);
glutMouseFunc(&mousefn);
glutMotionFunc(&motionfn);
glutPassiveMotionFunc(passmotionfn);
76

ssgInit();
puInit();
puSetDefaultStyle(PUSTYLE_SMALL_SHADED);
puSetDefaultFonts(PUFONT_HELVETICA_10,PUF
ONT_HELVETICA_10);

glClearColor(0.0f,0.0f,0.0f,1.0f);

//ssgSetFOV(60.0f,0.0f);
//ssgSetNearFar(1.0f,700.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

w = puGetWindowWidth();
h = puGetWindowHeight();

//sgSetVec3(sunposn,0.2f,0.5f,0.5f);
//ssgGetLight(0)->setPosition(sunposn);

w=puGetWindowWidth();
h=puGetWindowHeight();
.
.

}
77

Berikut adalah gambar dari rancangan window utama;

Gambar 3.8 Window utama

3.4.2 Fitur menu


Fitur menu pada sistem ini dirancang dengan mengelompokkan
menu berdasarkan fungsi. Menu dengan fungsi yang umum dipakai
dalam aplikasi dijadikan satu dalam menu ”File”, sedangkan untuk
menu yang berhubungan sistem tracking dikelompokkan dalam menu
”Face”. Menu ”Image” merupakan kelompok fungsi yang berhubungan
dengan pengolahan citra. Diagram arsitektur dari fitur menu pada sistem
tracking ini tampak pada gambar 3.7.
78

3.5 Arsitektur Perangkat Lunak

Gambar 3.8 Arsitektur perangkat lunak

3.5.1 Struktur file


Pada sistem ini struktur file perangkat lunak dibagi menjadi
beberapa kelompok, seperti halnya dalam fitur menu yang dibuat.
Pengelompokan ini dimaksudkan untuk lebih memudahkan dalam
pelacakan kesalahan. Setiap file C yang dibuat memiliki file header yang
sama namanya dengan file *.cxx. File header ini digunakan untuk
menghubungkan antar file pada saat melakukan pemanggilan fungsi
yang terdapat pada file yang bersangkutan. Gambar 3.8 menunjukkan
struktur file yang dibuat pada sistem tracking ini. Penjelasan mengenai
fungsi dan isi dari masing-masing file adalah sebagai berikut.

Main.cxx
File ini berisi definisi fungsi grafik dan pembuatan window
utama. Definisi komponen baik menu bar atau komponen yang
berhubungan dengan antarmuka perangkat lunak dengan pengguna
berada dalam file ini. File ini memiliki header file main.h, dimana pada
file ini seluruh file header lainnya didefinisikan.
79

Image.h
File ini berisi fungsi-fungsi untuk pemrosesan texture. Selain
itu juga fungsi yang berhubungan dengan pembacaan file bitmap juga
terdapat dalam file ini.

Dip.h
Fungsi filter yang digunakan pada sistem ini didefinisikan
semuanya dalam file ini.

Bcap.cxx
File ini berisi definisi fungsi untuk inisialisasi video4linux.
Daftar fungsi yang ada dalam bcap.cxx semuanya berada pada bcap.h,
dengan demikian akan lebih mudah untuk melihat fungsi yang telah
didefinisikan dan untuk melakukan pemanggilan cukup menyertakan
bcap.h.

Bshow.cxx
Fungsi untuk penangkapan file dari perangkat video4linux
berada dalam file bshow.cxx, file ini juga dilengkapi dengan header
bshow.h

Bmplib.cxx
Berisi fungsi dasar pustaka untuk pembacaan file bitmap. File
ini disertai file header bmplib.h

File config
File ini berkenaan dengan konfigurasi sistem yang digunakan.
File tersebut meliputi file dengan ekstensi *.bcd. File *.bcd merupakan
file yang berisi nilai koordinat template pada gambar yang telah dibuat
templatenya. File bmp merupakan file masukan yang dibutuhkan oleh
sitem tracking untuk diproses.
80

-----Halaman ini sengaja dikosongkan-----


BAB IV
PENGUJIAN DAN ANALISA

4.1 Pendahuluan
Pada bab pengujian dan analisa ini akan dibahas mengenai
pengujian dari perangkat lunak (software) yang dibuat. Hal ini bertujuan
untuk mengetahui sejauh mana ketepatan eksekusi perangkat lunak yang
telah dibuat serta tidak menutup kemungkinan mengetahui
kelemahannya. Sehingga dari sini nantinya dapat disimpulkan apakah
perangkat lunak yang dibuat dapat berjalan secara benar dan sesuai
dengan kriteria yang diharapkan
Pengujian sistem face tracking meliputi dua kategori, yang
pertama adalah uji fungsi, dan yang kedua uji performa.
Pengujian fungsionalitas ditekankan pada fungsi kerja dari
sistem. Hasil dari pengujian ini berupa respon keluaran yang dihasilkan
sistem, apakah itu sesuai dengan yang diinginkan. Perangkat lunak face
tracking sistem memiliki beberapa fungsi, selain fungsi utama juga
terdapat beberapa fungsi tambahan sebagai kelengkapan untuk lebih
memudahkan pada penggunaannya. Fungsi utama dari sistem ini adalah
melakukan tracking. Fungsi ini direpresentasikan pada fungsi
perhitungan korelasi.
Berikut ini spesifikasi fungsi dari perangkat lunak face tracking
sistem :
1. Menghitung korelasi
2. Menghitung intensitas template
3. Membuat template
4. Menyimpan template
5. Melakukan image filtering
6. Pengambilan gambar dari kamera
7. Menyimpan hasil tangkapan kamera menjadi bitmap sekuen
8. Replay image sekuen.

Pada pengujian performa ditekankan pada aspek kecepatan


eksekusi sebuah fungsi, dalam hal ini adalah fungsi utama. Perhitungan
korelasi dan penemuan obyek yang ditracking akan diukur
kecepatannya. Selain itu juga uji performa juga meliputi pokok yang
menjadi batasan sistem perangkat lunak. Batasan disini lebih mengarah
pada fleksibilitas sistem menangani error atau berbagai macam masukan

81
82

yang menyebabkan sistem menjadi lambat, dan atau program keluar


secara paksa.
Pengujian sistem dilakukan dengan menjalankan perangkat lunak
pada sebuah PC dengan spesifikasi tertentu. Adapun spesifikasi PC dan
sistem operasi untuk proses pengujian ini adalah sebagai berikut :

Tabel 4.1 spesifikasi perangkat keras pengujian

No Deskripsi Spesifikasi
1 CPU P IV 1700 MHz 40 Gb Hardisk

2 RAM 256 MB
3 Graphic Card Nvidia MX2 400 64MB
4 GCC Versi 3.3
5 PLIB 1.8.3
6 Video4Linux Versi 1
7 OpenGL Versi 2.0
8 Sistem Operasi Linux/GNU Debian
9 Kernel 2.6.8-386

4.2 Pengujian fungsionalitas


Sebelum melakukan pengujian sistem terintegrasi, pada sistem
ini dilakukan pengujian fungsi secara perbagian. Tujuan dari pengujian
ini memastikan bagian-bagian dari sistem berfungsi dengan baik,
sehingga pada saat diintegrasikan dapat memperkecil terjadinya
kesalahan yang disebabkan oleh kegagalan sub proses dari sistem
tracking.

4.2.1 Fungsi pembuatan template


Sistem ini dilengkapi dengan fasilitas fungsi yang berguna
untuk membuat template sesuai dengan ukuran yang diinginkan. Bentuk
dari template terdiri dari dua jenis yaitu persegi empat dan template titik.
Hasil dari pembuatan template yang dibuat tampak pada gambar 4.1
berikut.
83

Gambar 4.1. Hasil pembuatan template persegi empat

Gambar 4.2 Hasil template titik

Agar template yang dibuat masih bisa digunakan kembali, pada sistem
ini juga dilengkapi untuk menyimpan template ke dalam sebuah file
yang berektensi *.bcd.

4.2.2 Fungsi penangkapan gambar video


Penangkapan video dilakukan dengan menangkap gambar dari
kamera. Data dari kamera ini kemudian disimpan menjadi file bitmap
sesuai dengan urutan frame. Tampak pada gambar 4.3 hasil
penangkapan gambar dari kamera.
84

Gambar 4.3 Hasil penangkapan gambar dari kamera

4.2.3 Fungsi Perhitungan SSD (Sum of Squared Difference)


Perhitungan SSD digunakan untuk memastikan apakah
intensitas dari piksel yang dibaca telah dilakukan dengan benar. Pada
sistem ini fungsi perhitungan SSD dilakukan pada satu gambar, dimana
dari gambar tersebut jika pembacaan intesitas benar, dan persamaan
yang digunakan adalah selisih kuadrat antara template dengan gambar.
Jika nilai SSD yang dihasilkan sama dengan nol maka dipastikan ada
kesamaan antara gambar dengan template. Jadi pada saat SSD sama
dengan nol posisi tersebut merupakan posisi obyek yang dicari.
Sebaliknya jika tidak menemukan SSD sama dengan nol maka fungsi
pembacaan nilai intesitas piksel salah, atau terbalik urutannya.
Gambar 4.3 menunjukkan hasil pencarian dengan
menggunakan perhitungan SSD.

Gambar 4.4Hasil tracking dengan perhitungan SSD


85

4.2.4 Perhitungan korelasi


Untuk memastikan perhitungan korelasi dilakukan dengan
benar, pada sistem ini digunakan data referensi nilai SSD. Jika nilai SSD
sama dengan ’0’ maka nilai korelasi harus sama dengan 1. Selain nilai
tersebut adalah salah.

Tabel 4.2. Perbandingan Korelasi dan SSD


N Frame Mean Std Me x y C SSD T
o Dev an (ms)
1 Poc1.bmp 181,1 78,7 231 120 100 1.0 0 2830
2 Poc2.bmp 125,6 54,7 161 114 99 0,9951 1685584 2791
3 Poc3.bmp 109,8 53,7 145 107 99 0,9950 2037257 2800
4 Poc4.bmp 103,4 49,5 111 107 21 0,9942 2822202 605
5 Poc5.bmp 100,5 45,1 131 111 108 0,9946 3894155 3057
6 Poc6.bmp 103,3 43,5 132 103 107 0,9952 3231178 3034
7 Poc7.bmp 101,1 42,7 125 108 92 0,9900 3081754 2572
8 Poc8.bmp 77,8 57,4 93 236 137 0,9591 1705813 3151
9 Poc9.bmp 58,4 58,3 34 281 68 0,9599 1483667 1962
10 Poc10.bm 54,6 54,6 28 28 99 0,9601 1339506 3381
p

Pada tabel diatas adalah hasil pengujian proses tracking dengan


korelasi dan SSD. Dari hasil pengujian diatas tampak jika nilai
korelasinya sama dengan 1 maka nilai SSD nya 0, meskipun demikian
tidak ada hubungan sebab akibat diantara keduanya, hanya cara
perhitungannya yang berbeda.

4.3 Pengujian performa


Pengujian performa dilakukan dengan sistem yang terintegrasi.
Maksud dari pengujian ini adalah untuk mengetahui beberapa faktor
yang mempengaruhi sistem, dan juga kecepatan sistem untuk melakukan
tracking. Pada pengujian ini dilakukan dengan mode offline.
Pada mode offline gambar frame yang telah ditangkap dibaca kembali
dan dibuat template untuk masing-masing kumpulan sekuen frame. Dari
template yang dibuat ini kemudian dilakukan pengujian tracking untuk
masing masing frame.
86

4.3.1 Pengujian faktor brightness


Pengujian faktor brightness dilakukan untuk mengetahui
pengaruh faktor pencahayaan terhadap tracking. Tabel 4.2 berikut ini
adalah hasil pengujian faktor brightness. Tingkat brightness diukur
dengan menggunakan utilitas gambar GIMP.

Tabel 4.3. Hasil pengujian tracking dengan variabel faktor


brightness
No Frame Mean Std Mean x y C SSD T
Dev (ms)
1 Poc1.bmp 181,1 78,7 231 120 100 1.0 0 2830
2 Poc2.bmp 125,6 54,7 161 114 99 0,9951 1685584 2791
3 Poc3.bmp 109,8 53,7 145 107 99 0,9950 2037257 2800
4 Poc4.bmp 103,4 49,5 111 107 21 0,9942 2822202 605
5 Poc5.bmp 100,5 45,1 131 111 108 0,9946 3894155 3057
6 Poc6.bmp 103,3 43,5 132 103 107 0,9952 3231178 3034
7 Poc7.bmp 101,1 42,7 125 108 92 0,9900 3081754 2572
8 Poc8.bmp 77,8 57,4 93 236 137 0,9591 1705813 3151
9 Poc9.bmp 58,4 58,3 34 281 68 0,9599 1483667 1962
10 Poc10.bmp 54,6 54,6 28 28 99 0,9601 1339506 3381

Pada tabel 4.3 diatas adalah proses pengujian tracking dengan


faktor brightness. Dari tabel diatas didapat bahwa proses pengujian
faktor brightness gagal pada tingkat ke-8, hal ini dikarenakan faktor
kecerahan merupakan salah satu faktor penentu keberhasilan proses
tracking. Gambar berikut ini adalah kegagalan proses tracking pada
tingkat brightness ke-8;
87

Gambar 4.5 Hasil tracking gagal pada tingkat brightness ke 8.

4.3.2 Pengujian tracking untuk template persegi empat


Data pada tabel berikut ini adalah hasil pengujian tracking yang
dilakukan untuk beberapa template yang dibuat.
88

Gambar 4.6 Frame-frame Dino untuk data pengujian

Gambar 4.7 Template mata kanan ukuran 58 x 44 pixel

Tabel 4.4. Hasil tracking template mata kanan

Nama Korelasi Waktu


No template x y SSD Max pencarian
1 frame 1 86 74 0 1 4176 ms
2 frame 2 86 74 109790 0,9972 4093 ms
3 frame 3 84 75 281985 0,9941 4106 ms
4 frame 4 83 75 230996 0,9949 4209 ms
5 frame 5 85 75 225613 0,9957 4198 ms
6 frame 6 89 74 427045 0,995 4250 ms
7 frame 7 99 72 428747 0,9937 4148 ms
8 frame 8 111 69 657005 0,9915 3915 ms
9 frame 9 122 68 1293426 0,9892 3870 ms
10 frame 10 137 67 747651 0,9901 3785 ms
11 frame 11 149 67 757579 0,99 3817 ms
12 frame 12 159 66 519591 0,9903 3722 ms
13 frame 13 165 66 559665 0,99 3697 ms
14 frame 14 165 69 991627 0,9855 3857ms
15 frame 15 166 69 533142 0,9858 3797 ms
16 frame 16 157 71 698363 0,9821 4020 ms
17 frame 17 157 71 698363 0,9821 4013ms
18 frame 18 152 41 937618 0,9759 2188 ms
19 frame 19 140 74 826999 0,978 2530 ms
20 frame 20 134 72 697969 0,9816 3967 ms
21 frame 21 128 72 787443 0,9814 4012 ms
22 frame 22 123 72 800882 0,9825 4074 ms
23 frame 23 119 72 809782 0,987 4214 ms
89

24 frame 24 115 73 1107292 0,989 4111 ms


25 frame 25 109 74 1118074 0,9897 4182 ms
26 frame 26 100 75 816542 0,99 4290 ms
27 frame 27 91 75 743626 0,9849 4235 ms
28 frame 28 78 78 800458 0,9788 4449 ms
29 frame 29 66 82 887086 0,9762 2933 ms
30 frame 30 54 82 879718 0,9765 4583 ms
31 frame 31 46 83 1071422 0,9727 3437 ms

Gambar 4.8 Template alis ukuran 68 x 32 pixel

Tabel 4.5 Hasil tracking template alis


Nama Korelasi Waktu
No template x y SSD Max pencarian
1 frame 1 165 52 86543 0,9977 2372 ms
2 frame 2 165 52 237533 0,9954 2386 ms
3 frame 3 164 53 198174 0,9952 2402 ms
4 frame 4 166 53 180426 0,9965 2552 ms
5 frame 5 170 53 330987 0,9953 2528 ms
6 frame 6 180 54 384196 0,9923 2412 ms
7 frame 7 192 55 510618 0,9872 2580 ms
8 frame 8 204 54 551746 0,9872 2553 ms
9 frame 9 212 53 849326 0,9812 2429 ms
10 frame 10 224 54 813966 0,9821 2480 ms
11 frame 11 233 54 777926 0,9816 2479 ms
12 frame 12 238 55 896400 0,9803 2544ms
13 frame 13 241 55 797016 0,9816 2540ms
14 frame 14 242 56 648480 0,9838 2582 ms
15 frame 15 239 55 640060 0,9842 2535 ms
16 frame 16 232 55 587727 0,9849 2530 ms
17 frame 17 225 51 1180034 0,9838 2341 ms
90

18 frame 18 218 46 1621161 0,9781 2132 ms


19 frame 19 211 48 1515895 0,9821 2200ms
20 frame 20 206 48 1900506 0,9828 2201 ms
21 frame 21 201 49 1901801 0,9855 2260 ms
22 frame 22 195 51 1661587 0,9852 2338 ms
23 frame 23 190 54 1601711 0,988 2548 ms
24 frame 24 183 54 1554264 0,9857 2477 ms
25 frame 25 176 53 1317480 0,9854 2442ms
26 frame 26 149 41 1526192 0,9766 1876 ms
27 frame 27 149 41 1526192 0,9766 1888 ms
28 frame 28 132 39 1174920 0,9767 1777ms
29 frame 29 118 40 1026150 0,977 1822 ms
30 frame 30 109 45 918418 0,978 2056 ms
31 frame 31 109 45 918418 0,978 2056 ms

Gambar 4.9 Template mata kanan ukuran 66 x 36 pixel

Tabel 4.6 Hasil pengujian template mata kiri


Nama Korelasi Waktu
No template x y SSD Max pencarian
1 frame 1 160 76 0 1 3791 ms
2 frame 2 158 75 288388 0,989 3786 ms
3 frame 3 156 75 406409 0,9874 3800 ms
4 frame 4 156 76 307870 0,9894 3811 ms
5 frame 5 158 76 369505 0,9887 3840 ms
6 frame 6 160 76 517127 0,9873 3813 ms
7 frame 7 172 76 501301 0,9871 3818 ms
8 frame 8 185 77 486897 0,9872 3889 ms
9 frame 9 197 78 628709 0,9872 3949 ms
10 frame 10 209 79 618324 0,9856 3995 ms
11 frame 11 222 80 670934 0,9856 4057ms
12 frame 12 242 81 678004 0,984 3992 ms
13 frame 13 242 86 1276331 0,9717 4605 ms
14 frame 14 241 86 750513 0,9718 3073 ms
91

15 frame 15 237 85 784209 0,9701 3444 ms


16 frame 16 231 88 664874 0,9763 3784 ms
17 frame 17 223 89 715683 0,9752 3365 ms
18 frame 18 217 86 734163 0,975 5040 ms
19 frame 19 210 83 789194 0,976 2872 ms
20 frame 20 206 82 907473 0,9756 3170 ms
21 frame 21 201 81 972820 0,9752 4614 ms
22 frame 22 195 81 987181 0,9775 4462 ms
23 frame 23 190 81 1144330 0,9775 3330 ms
24 frame 24 184 81 1104998 0,9754 3358 ms
25 frame 25 175 81 949023 0,9758 4680 ms
26 frame 26 166 80 949023 0,9765 3544 ms
27 frame 27 149 80 702251 0,9753 4469 ms
28 frame 28 119 78 700644 0,9754 4731 ms
29 frame 29 119 78 64383 0,9754 4731 ms
30 frame 30 107 78 649488 0,9753 4252 ms

Gambar 4.10 Template mulut ukuran 96 x 42 pixel

Tabel 4.7 Hasil pengujian tracking template mulut.


Nama Korelasi Waktu
No template x y SSD Max pencarian
1 frame 1 114 160 0 1 1189ms
2 frame 2 113 160 213730 0,9924 1188ms
3 frame 3 111 160 500615 0,9849 1189ms
4 frame 4 112 160 468283 0,984 1188ms
5 frame 5 113 160 563007 0,9823 1188ms
6 frame 6 117 160 683310 0,9825 1189ms
7 frame 7 127 159 739575 0,9808 1185ms
8 frame 8 140 157 1037903 0,9721 1167ms
9 frame 9 149 157 1356048 0,9682 1166ms
92

10 frame 10 162 156 1459663 0,9641 1158ms


11 frame 11 174 154 1624587 0,9601 1143ms
12 frame 12 183 154 1436041 0,9587 1143ms
13 frame 13 189 155 1576741 0,9577 1023ms
14 frame 14 191 155 1455380 0,9572 1137ms
15 frame 15 191 156 1162158 0,958 977ms
16 frame 16 188 156 1177384 0,9574 955ms
17 frame 17 182 156 1176348 0,9576 804ms
18 frame 18 * * * * *
19 frame 19 * * * * *
20 frame 20 * * * * *
21 frame 21 * * * * *
22 frame 22 * * * * *
23 frame 23 * * * * *
24 frame 24 * * * * *
25 frame 25 * * * * *
26 frame 26 * * * * *
27 frame 27 * * * * *
28 frame 28 * * * * *
29 frame 29 * * * * *
30 frame 30 * * * * *
31 frame 31 * * * * *
93

Gambar 4.11 Frame – frame Sari untuk data pengujian

Gambar 4.12 Template wajah ukuran 116 x 112 pixel

Tabel 4.8 Hasil pengujian tracking wajah


Nama Korelasi Waktu
No Template x y SSD Max pencarian
1 frame 1 114 72 4199687 0,9891 15954ms
2 frame 2 113 70 4501113 0,9892 15527ms
3 frame 3 114 69 4442950 0,99 15334ms
4 frame 4 115 69 4624026 0,9894 15407ms
5 frame 5 117 69 4909848 0,9889 15353ms
6 frame 6 116 69 4740016 0,9892 15311ms
7 frame 7 115 69 4782406 0,9894 15315ms
8 frame 8 114 69 4668068 0,989 15311ms
9 frame 9 113 70 4235939 0,99 15529ms
10 frame 10 111 71 4520985 0,9892 15735ms
11 frame 11 112 71 4049119 0,9899 15741ms
12 frame 12 111 71 4208813 0,9893 15743ms
13 frame 13 111 71 3988780 0,9901 15887ms
14 frame 14 111 71 4112921 0,9897 15752ms
15 frame 15 111 72 3674224 0,9907 15978ms
16 frame 16 112 72 3383804 0,9914 15959ms
17 frame 17 113 71 3815242 0,9905 15730ms
18 frame 18 113 70 3547461 0,9917 15520ms
19 frame 19 114 69 3979271 0,9909 15312ms
94

20 frame 20 114 69 4141360 0,9904 15317ms

Gambar 4.13 Template mata kanan ukuran 42 x 34 pixel

Tabel 4.9 hasil tracking mata kanan


Nama Korelasi Waktu
No Template x y SSD Max pencarian
1 frame 1 117 83 338284 0,9902 2790ms
2 frame 2 118 84 289293 0,9905 2907ms
3 frame 3 118 83 309778 0,9906 2958ms
4 frame 4 120 83 294608 0,9906 2877ms
5 frame 5 119 84 330386 0,9916 2949ms
6 frame 6 121 83 307542 0,9902 2885ms
7 frame 7 120 83 306121 0,9906 2886ms
8 frame 8 119 83 293515 0,9907 2875ms
9 frame 9 117 84 304165 0,9911 2904ms
10 frame 10 115 85 361284 0,9903 2971ms
11 frame 11 119 74 267074 0,9912 2574ms
12 frame 12 119 74 297357 0,9901 2644ms
13 frame 13 118 75 293853 0,9904 2609ms
14 frame 14 119 75 281145 0,9907 2618ms
15 frame 15 117 76 295754 0,9902 2650ms
16 frame 16 117 76 290919 0,9903 2648ms
17 frame 17 116 77 292127 0,9904 2682ms
18 frame 18 116 77 297200 0,9904 2703ms
19 frame 19 114 78 295101 0,9903 2760ms
20 frame 20 115 77 303106 0,9901 2790ms

Gambar 4.14 Template mata kiri ukuran 46 x 36 pixel


95

Tabel 4.10 hasil tracking mata kiri


Nama Korelasi Waktu
No Template x y SSD Max pencarian
1 frame 1 180 88 0 1 3488ms
2 frame 2 177 83 339772 0,9901 3265ms
3 frame 3 178 82 296698 0,991 3287ms
4 frame 4 180 82 281703 0,9915 3269ms
5 frame 5 181 82 324694 0,9901 3262ms
6 frame 6 181 82 322866 0,9902 3214ms
7 frame 7 180 82 317626 0,9903 3244ms
8 frame 8 179 82 322337 0,9905 3255ms
9 frame 9 180 82 324199 0,9902 3263ms
10 frame 10 177 83 335365 0,9903 3289ms
11 frame 11 177 72 330930 0,9907 2868ms
12 frame 12 177 72 355043 0,99 2884ms
13 frame 13 176 73 331446 0,9909 2900ms
14 frame 14 176 73 355618 0,9902 2895ms
15 frame 15 176 74 331061 0,9913 2920ms
16 frame 16 176 74 328683 0,991 2965ms
17 frame 17 175 75 349386 0,9911 2999ms
18 frame 18 174 75 381814 0,9902 2985ms
19 frame 19 174 75 365706 0,9905 2976ms
20 frame 20 179 82 288808 0,9913 3260ms

Gambar 4.15 Template mulut ukuran 56 x 22

Tabel 4.11 hasil tracking mulut


Nama Korelasi Waktu
No Template x y SSD Max pencarian
1 frame 1 144 162 0 1 4560ms
2 frame 2 141 159 165705 0,9905 4466ms
3 frame 3 142 158 172063 0,9905 4433ms
4 frame 4 144 158 172180 0,9905 4417ms
5 frame 5 145 158 180377 0,9909 4445ms
96

6 frame 6 144 158 168052 0,9911 4399ms


7 frame 7 142 158 185165 0,9904 4426ms
8 frame 8 142 158 150198 0,9918 4419ms
9 frame 9 140 159 160168 0,991 4507ms
10 frame 10 141 159 184729 0,99 4483ms
11 frame 11 139 160 164857 0,9902 4510ms
12 frame 12 139 160 157031 0,9903 4687ms
13 frame 13 138 160 180488 0,9894 4485ms
14 frame 14 139 160 168858 0,9899 4549ms
15 frame 15 140 160 186378 0,989 4536ms
16 frame 16 141 160 177178 0,9894 4515ms
17 frame 17 142 159 191382 0,9892 4466ms
18 frame 18 145 157 206813 0,9891 4404ms
19 frame 19 143 157 194882 0,9902 4407ms
20 frame 20 143 157 191166 0,9902 4413ms

4.3.3 Pengujian Tracking untuk template titik


Berikut adalah hasil tracking frame-frame menggunakan
template titik;

Gambar 4.16 Frame – frame Puthut untuk data pengujian

Tabel 4. 12 koordinat hasil tracking titik fitur untuk frame 1 s/d 4


97

frame 1 frame 2 frame 3 frame 4


Titik
x y x y x y x y
48 114 113 114 114 115 114 114 114
49 108 107 108 108 108 108 108 108
51 113 113 113 113 113 113 113 113
17 115 115 115 115 115 115 115 115
17 115 115 115 115 115 115 115 115
16 107 107 107 107 107 107 107 107
18 111 111 111 111 111 111 111 111
15 112 111 111 112 111 112 111 112
3 116 115 116 116 116 116 116 116
53 127 126 127 127 127 127 127 127
56 131 131 132 131 132 131 132 131
52 121 121 121 121 121 121 121 121
57 132 132 132 132 132 132 132 132
23 130 129 130 130 130 130 130 130
20 126 126 127 126 126 126 126 126
19 120 120 120 120 120 120 120 120
24 133 132 133 133 133 133 133 133
5 160 160 160 160 160 160 160 160
6 167 167 167 167 167 167 167 167
59 169 169 169 169 169 169 169 169
26 169 169 169 169 169 169 170 169
76 164 164 165 164 165 164 164 164
75 163 163 163 163 164 163 163 163
64 189 188 189 189 189 189 189 189
31 188 188 188 188 188 188 188 188
7 183 183 183 183 183 183 183 183
8 201 201 201 201 201 201 201 201
83 191 191 191 191 191 191 191 191
98

81 190 190 190 190 190 190 190 190


89 190 189 190 190 190 190 190 190
88 189 189 189 189 189 189 189 189
10 222 222 222 222 223 222 222 222
0 73 73 74 73 73 73 73 73
62 123 123 124 123 124 123 124 123
29 121 121 122 121 121 121 122 121

Tabel 4.13 koordinat hasil tracking titik fitur untuk frame 5 s/d 8
Titik frame 5 frame 6 frame 7 frame 8
x y x y x y x y
48 114 114 114 114 114 114 114 114
49 107 108 106 107 105 106 106 105
51 113 113 114 113 113 114 113 113
50 111 112 112 111 111 112 111 111
17 116 115 115 116 115 115 114 115
16 107 107 107 107 107 107 106 107
18 111 111 111 111 111 111 110 111
15 111 111 112 111 111 112 111 111
3 116 116 116 116 115 116 115 115
53 127 127 126 127 125 126 125 125
56 131 132 131 131 131 131 131 131
52 121 121 121 121 121 121 120 121
57 132 132 132 132 132 132 132 132
23 130 130 131 130 131 131 131 131
20 126 126 126 126 126 126 126 126
19 120 120 120 120 119 120 119 119
24 133 133 133 133 132 133 132 132
5 160 160 160 160 160 160 159 160
6 167 167 167 167 166 167 166 166
59 170 169 169 170 168 169 168 168
26 170 170 169 170 168 169 168 168
99

76 164 164 164 164 164 164 163 164


75 164 163 163 164 163 163 163 163
64 189 189 189 189 188 189 188 188
31 188 188 188 188 188 188 188 188
7 183 183 183 183 182 183 182 182
8 201 201 201 201 200 201 200 200
83 191 191 191 191 191 191 191 191
81 190 190 190 190 190 190 190 190
89 190 190 189 190 189 189 189 189
88 189 189 188 189 188 188 189 188
10 221 222 221 221 220 221 219 220
0 73 73 73 73 72 73 72 72
62 124 124 123 124 123 123 123 123
29 121 122 121 121 121 121 121 121

Tabel 4. 14 koordinat hasil tracking titik fitur untuk frame 9 s/d 12


frame 9 frame 10 frame 11 frame 12
Titik x y x y x y x y
48 114 114 114 114 113 114 113 113
49 106 106 106 106 107 108 107 107
51 113 113 112 113 112 113 111 112
50 111 111 111 111 112 112 111 112
17 114 114 114 114 115 115 114 115
16 106 106 106 106 106 107 106 106
18 110 110 110 110 111 111 111 111
15 110 111 111 110 111 112 111 111
3 115 115 115 115 115 116 115 115
53 126 125 126 126 126 127 125 126
56 131 131 131 131 131 131 130 131
52 120 120 120 120 121 121 121 121
57 132 132 132 132 132 132 132 132
23 130 131 129 130 129 130 129 129
20 126 126 126 126 125 126 126 125
19 119 119 119 119 119 120 119 119
100

24 131 132 131 131 132 133 132 132


5 158 159 159 158 159 160 158 159
6 166 166 166 166 166 167 166 166
59 168 168 168 168 168 169 168 168
26 169 168 168 169 168 169 168 168
76 162 163 162 162 163 164 163 163
75 163 163 162 163 162 163 162 162
64 188 188 188 188 188 189 188 188
31 188 188 187 188 187 188 187 187
7 182 182 181 182 182 183 181 182
8 200 200 200 200 201 201 201 201
83 191 191 191 191 191 191 191 191
81 190 190 189 190 189 190 189 189
89 189 189 189 189 189 190 188 189
88 188 189 187 188 188 189 188 188
10 219 219 220 219 222 222 221 222
0 72 72 72 72 73 73 73 73
62 124 123 123 124 122 123 123 122
29 121 121 122 121 121 121 121 121

Tabel 4. 15 koordinat hasil tracking titik fitur untuk frame 13 s/d 16


Frame 13 Frame 14 Frame 15 Frame 16
Titik x y x y x y x y
48 112 113 112 112 112 112 113 112
49 107 107 107 107 107 107 107 107
51 112 112 112 112 111 112 111 111
50 110 111 110 110 110 110 110 110
17 115 115 115 115 115 115 115 115
16 107 107 107 107 107 107 107 107
18 111 111 111 111 110 111 111 110
15 111 111 111 111 111 111 111 111
3 115 116 114 115 114 114 114 114
101

Frame 13 Frame 14 Frame 15 Frame 16


Titik x y x y x y x y
53 126 126 125 126 126 125 126 126
56 130 130 130 130 130 130 130 130
52 121 121 121 121 122 121 123 122
57 132 132 132 132 132 132 131 132
23 130 130 130 130 129 130 129 129
20 126 126 126 126 126 126 125 126
19 119 119 118 119 119 118 120 119
24 132 132 132 132 132 132 132 132
5 159 159 159 159 159 159 158 159
6 166 166 166 166 166 166 166 166
59 168 168 168 168 168 168 167 168
26 167 168 168 167 168 168 169 168
76 163 163 163 163 163 163 163 163
75 161 162 162 161 162 162 162 162
64 188 188 188 188 188 188 188 188
31 187 187 186 187 186 186 186 186
7 182 182 182 182 181 182 181 181
8 201 201 200 201 200 200 199 200
83 190 191 190 190 190 190 190 190
81 189 189 189 189 188 189 188 188
89 188 189 187 188 188 187 188 188
88 188 188 188 188 187 188 187 187
10 222 221 222 222 222 222 221 222
0 73 73 72 73 72 72 72 72
62 121 122 122 121 122 122 123 122
29 121 122 121 121 121 121 121 121

Tabel 4. 16 koordinat hasil tracking titik fitur untuk frame 17 s/d 20


Frame 17 Frame 18 Frame 19 Frame 20
Titik x y x y x y x y
48 112 113 113 112 113 113 113 113
49 107 107 107 107 107 107 107 107
102

51 111 111 111 111 111 111 112 111


50 111 110 111 111 110 111 110 110
17 115 115 115 115 115 115 114 115
16 107 107 107 107 107 107 107 107
18 112 111 111 112 111 111 111 111
15 111 111 110 111 110 110 110 110
3 115 114 115 115 115 115 115 115
53 126 126 126 126 126 126 126 126
56 130 130 130 130 130 130 130 130
52 122 123 121 122 121 121 120 121
57 131 131 130 131 130 130 130 130
23 128 129 129 128 129 129 129 129
20 126 125 126 126 126 126 126 126
19 120 120 120 120 120 120 119 120
24 133 132 133 133 132 133 131 132
5 158 158 158 158 158 158 159 158
6 166 166 166 166 166 166 166 166
59 168 167 168 168 168 168 168 168
26 170 169 169 170 169 169 168 169
76 163 163 163 163 163 163 163 163
75 162 162 162 162 162 162 161 162
64 188 188 188 188 188 188 188 188
31 186 186 186 186 186 186 187 186
7 182 181 182 182 182 182 182 182
8 200 199 200 200 200 200 200 200
83 190 190 190 190 191 190 190 191
81 188 188 188 188 188 188 188 188
89 188 188 188 188 189 188 189 189
88 187 187 188 187 188 188 188 188
10 220 221 221 220 222 221 222 222
0 72 72 72 72 72 72 72 72
62 122 123 121 122 120 121 120 120
29 122 121 122 122 123 122 124 123
103

4.4 Analisa
Dari hasil pengujian sistem didapat beberapa karakteristik
sistem terhadap faktor yang mempengaruhi proses tracking yang
dilakukan. Selain itu juga disini akan dibahas mengenai hasil dari
pengujian secara modular.
Secara keseluruhan sistem berjalan dengan baik pada tiap-tiap
bagian. Untuk penangkapan dari kamera sistem mampu menangkap
gambar dengan kecepatan rata-rata 9 fps. Kecepatan ini didapat dari
pengukuran fps yang dilakukan, namun hal ini tidak berlaku untuk
semua kamera yang dipakai. Untuk kamera jenis Intel CS-330,
kecepatan yang bisa didapat adalah berkisar 2-3 fps.
Pengujian pembuatan template juga berhasil dengan baik. Pada
proses pembuatan template ini yang ditekankan adalah proses
pengambilan data intensitas dan juga proses tampilan template. Pada
proses pengambilan data tidak terjadi masalah, akan tetapi pada proses
pemunculan gambar template terjadi permasalahan yaitu gambar
mengalami pergeseran sehingga tampilan menjadi menggulung (filped).
Dari hasil observasi, hal ini disebabkan kelemahan yang terdapat pada
fungsi openGL ”glDrawPixel”, ini juga dikuatkan oleh beberapa
referensi. Sehingga untuk mengatasi ini dilakukan penggambaran secara
bertahap dengan mengambil data perbaris kemudian dilakukan
pengambaran perbaris. Dan hasilnya sistem dapat melakukan
penggambaran template dengan benar.
Pengujian berikutnya adalah mencari hubungan kecerahan
gambar (brightness) dengan hasil tracking. Pada pengujian kali ini
variabel yang dipakai adalah brightness yang diukur dengan melihat data
yang ditampilkan oleh utilitas GIMP. Brightness direpresentasikan
dengan data standart deviasi dari gambar, nilai median dan mean
gambar. Semakin kecil standard deviasi, median, dan mean, gambar
akan semakin gelap. Pada tabel 4.3 hasil pengujian ditunjukkan, proses
tracking dilakukan dengan mencoba 10 frame dengan tingkat kecerahan
yang berbeda. Pada frame 1 sampai dengan 7 proses tracking berhasil
dilakukan, namun pada frame ke-8 sampai dengan fram ke-10 tracking
tidak berhasil dilakukan. Pada saat awal tracking nilai mean, standard
deviasi, dan median pixel image maupun template adalah sama yaitu
181.1, 78.7, 231.
Untuk mean, standard deviasi, dan median frame ke-8 berturut-
turut adalah 77.8, 57.4, 93. dengan menggunakan patokan standard
deviasi data maka tracking ini berhasil dilakukan maksimal apabila
memiliki jarak kecerahan kurang lebih 103.3. dengan demikian jika
104

tingkat kecerahan masih dalam range jarak tersebut, tracking masih


berhasil dilakukan. Tabel berikut menunjukkan grafik intensitas piksel
pada frame yang ditracking dibandingkan dengan template.

Intesitas pixel frame 5

250

200

150 Template
100 Image

50

0
1 118 235 352 469 586 703 820 937 1054 1171

Gambar 4.17 Grafik intesitas pixel frame 5 pada saat tracking


berhasil ditemukan

Tabel 4.17 Data grafik frame 5


Template Width = 38
Template Heigh = 32
Image Width = 320
Image Heigh = 240
Match Position on Image Data :
Pos X = 108
Pos Y = 92
Sum of Squared Differences = 3081754
Correlation : 0.990028
105

Intensitas pixel frame 6

250

200

150 Image

100 Template

50

0
1 118 235 352 469 586 703 820 937 1054 1171

Gambar 4.18 Grafik intesitas pixel frame 6 pada saat tracking


berhasil ditemukan

Tabel 4.18 Data frame 6


Template Width = 38
Template Heigh = 32
Image Width = 320
Image Heigh = 240
Match Position on Image Data :
Pos X = 111
Pos Y = 108
Sum of Squared Differences = 3894155
Correlation : 0.994561

Intesitas pixel frame 7

250

200

150 Template
100 Image

50

0
1 118 235 352 469 586 703 820 937 1054 1171

Gambar 4.19 Grafik intesitas pixel frame 7 pada saat tracking


berhasil ditemukan
106

Intensitas pixel frame 8

250

200

150 Template
100 Image

50

0
1 118 235 352 469 586 703 820 937 1054 1171

Gambar 4.20 grafik intesitas pixel frame 7 pada saat tracking


berhasil ditemukan

Tabel 4.19 Data frame8


Template Width = 38
Template Heigh = 32
Image Width = 320
Image Heigh = 240
Match Position on Image Data :
Pos X = 236
Pos Y = 137
Sum of Squared Differences = 1705813
Correlation : 0.959095

Pengujian tracking sistem ini dilakukan secara offline yaitu


dengan menggunakan beberapa gambar sekuen. Dalam pengujian untuk
template kotak ini digunakan 2 model yaitu frame-frame Dino dan Sari.
Untuk data gambar frame Dino tampak pada gambar 4.6, yaitu sebanyak
30 gambar sekuen. Template yang dibuat untuk menguji sebanyak 4
gambar yaitu bagian mata kanan, mata kiri, alis, dan mulut.
Pada pengujian template mata kanan dengan ukuran 58 x 44
pixel. Pada pengujian ini berhasil dilakukan meskipun gambar bergerak
sehingga memiliki perubahan kemiringan. Kecepatan rata-rata pencarian
adalah 3899 ms, sedangkan rata-rata nilai korelasi adalah 0.9868.
Pengujian selanjutnya adalah dengan template ukuran 68 x 32 dengan
fitur gambar template adalah alis. Pada tabel 4.5 tampak hasil pengujian
tracking dengan template ini. Kecepatan rata-rata yang diperlukan untuk
107

tracking adalah 2232.8 ms dengan rata-rata korelasi adalah 0.9847. Hasil


perhitungan rata-rata kecepatan seluruh pengujian template tertera pada
tabel 4.11 berikut.

Tabel 4.20 Data rata-rata kecepatan dan korelasi hasil pengujian


tracking frame-frame Dino
No Template Ukuran Rata-rata Rata-rata
Lebar Tinggi korelasi kecepatan (ms)
1 Mata Kanan 58 44 0,9868 3389
2 Alis kiri 64 32 0,9847 2232
3 Mata kiri 66 36 0,9803 3935,5
4 Mulut 96 42 0,9716 1117

Grafik korelasi template

1,01
1
0,99
Mata Kanan
0,98
Alis kiri
0,97
Mata Kiri
0,96
Mulut
0,95
0,94
0,93
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31

Gambar 4.21 Grafik nilai korelasi masing-masing template

Grafik kecepatan tracking

6000
5000

4000 Mata Kanan


Alis Kiri
3000
Mata Kiri
2000 Mulut
1000

0
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31

Gambar 4.22Grafik kecepatan tracking masing-masing template


108

Pada pengujian tracking dengan menggunakan template mulut,


setelah frame ke-17 tidak dapat diketemukan dikarenakan template yang
digunakan mengalami perubahan pola. Pada gambar template mulut
terbuka, namun pada frame ke-18 sampai dengan frame ke-30 mulut
menutup, sehingga pola pada template tidak bisa dikenali dengan
perhitungan korelasi. Hal ini sangat berbeda dengan tracking dengan
template alis, dimana template ini tidak mengalami perubahan bentuk,
namun alis ini juga mengalami perubahan kemiringan atau orientasi.
Dari tabel 4.7, pada saat nilai korelasi mencapai titik terendah kira 0.97,
gambar mulai mengalami perubahan orientasi.
Untuk data gambar frame Sari tampak pada gambar 4.11, yaitu
sebanyak 20 gambar sekuen. Template yang dibuat untuk menguji
sebanyak 4 gambar yaitu bagian wajah dengan ukuran 116 x 112 pixel,
mata kanan dengan ukuran 42 x 34 pixel , mata kiri dengan ukuran 46 x
36 pixel, dan mulut dengan ukuran 56 x 22 pixel. Hasil perhitungan rata-
rata kecepatan seluruh pengujian template tertera pada tabel 4.21 berikut

Tabel 4.20 Data rata-rata kecepatan dan korelasi hasil pengujian


tracking frame-frame Sari
No Template Ukuran Rata-rata Rata-rata
Lebar Tinggi korelasi kecepatan (ms)
1 Wajah 116 112 0,9899 15586
2 Mata kanan 42 34 0,9905 2784
3 Mata kiri 46 36 0,9911 3124
4 Mulut 56 22 0,9906 4476

Rata-rata untuk tracking frame-frame sari ini tidak mengalami


kendala karena hanya sedikit pergerakan, bahkan tidak ada perubahan
orientasi. Hal ini bisa diketahui dari template wajah dengan korelasi
yang mendekati 1. Sedangkan untuk rata-rata kecepatan tracking yang
paling lama waktunya adalah template wajah, hal ini dikarenakan
ukuran dari template wajah yang lebih besar daripada yang lainnya.

Pada pengujian tracking untuk template titik dilakukan secara


offline yaitu dengan mengambil video selama kurang lebih 2 menit lalu
mengubahnya menjadi frame, jadi kalau kecepatan kamera bisa
menangkap 9 frame per detik maka selama 2 menit kurang lebih ada
1080 frame, namun yang digunakan untuk tracking disini hanya 20
frame dan itupun hanya dipilih untuk frame dengan sedikit pergerakan
dikarenakan pada sistem tracking dengan template titik fitur wajah ini
109

hanya bisa mendeteksi pergerakan titik fitur wajah dengan sedikit


pergerakan.
110

-----Halaman ini sengaja dikosongkan-----


BAB V
PENUTUP

5.1 KESIMPULAN
Berdasarkan hasil pengujian yang telah dilakukan didapatkan
beberapa kesimpulan untuk proses tracking dengan menggunakan
metode korelasi.
1. Proses tracking dipengaruhi oleh faktor brightness. Jarak
maksimum mean antara template dengan gambar yang ditracking
adalah 138.
2. Kecepatan tracking dipengaruhi oleh besar template yang
digunakan. Semakin besar ukuran template akan semakin lama
proses tracking.
3. Untuk gambar template yang memiliki sifat dinamis seperti mata,
mulut dapat ditracking apabila kondisi fitur tersebut tetap. Atau
bisa juga dengan menyertakan ciri fitur lain sebagai tambahan
untuk mendapatkan pola.
4. Nilai SSD tidak bergantung pada korelasi, tetapi sebaliknya jika
nilai SSD sama dengan 0 maka nilai korelasi sama dengan 1.
5. Nilai korelasi merupakan konstanta pengali tingkat kecerahan
pada gambar dengan template.
6. Tracking posisi secara presisi tidak ditentukan oleh nilai korelasi
maksimum. Hal ini dikarenakan gambar yang ditracking dengan
template mengalami kecenderungan perubahan orientasi.
7. Waktu yang diperlukan untuk tracking relatif tinggi yaitu berkisar
2-6 detik

5.2 Saran
sebagai saran untuk tugas akhir ini diperlukan sebuah metode
proses pencarian pada saat tracking untuk mempercepat. Dan juga untuk
mendapatkan keberhasilan tracking dengan orientasi gambar yang
berubah.

111
-----Halaman ini sengaja dikosongkan-----

112
DAFTAR PUSTAKA
[1] Ahmad, Usman, Pengolahan Citra Digital dan Teknik
Pemrogramannya, Yogyakarta; Penerbit Graha Ilmu, 2005.
[2] Dana Harry Ballard & Cristopher M. Brown, Computer Vision,
Prentice Hall Professional Technical Reference, 1982.
[3] Vernon, David, “Machine Vision” Automated Visual Inspection &
Robot Vision, Prentice Hall, 1991.
[4] B S Venkatesh, S Palanivel and B Yegnanarayana, Face Detection
and Recognition in an Image Sequence using Eigenedginess,
Department of Computer Science and Engineering, Indian Institute
of Technology, Madras.
[5] Karl Schwerdt and James L. Crowley, Robust Face Tracking using
Color, Projet PRIMA, INRIA Rhˆone-Alpes, 655 ave. de l’Europe,
38330 Montbonnot St. Martin France.
[6] Mikhail J. Atallah, Faster Image Template Matching in the Sum of the
Absolute Value of Differences Measure, IEEE TRANSACTIONS ON
IMAGE PROCESSING, VOL. 10, NO. 4, APRIL 2001.
[7] Helmut Prendinger and Mitsuru Ishizuka, Introducing the Cast for
Social Computing:Life-like Characters, life-like.pdf, The University
of Tokyo, 2003
[8] http://linux.bytesex.org/v4l2/API.html
[9] http://plib.sourceforge.net/pui/index.html

113
-----Halaman ini sengaja dikosongkan-----

114
LAMPIRAN
1. Program utama
/*main.h*/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include <string.h>
#ifdef WIN32
#include <window.h>
#else
#include <unistd.h>
#endif
#include <math.h>
#include <GL/glut.h>
#include <plib/sg.h>
#include <plib/pu.h>
#include <plib/ssg.h>
#include <plib/ssgAux.h>
#include <plib/ul.h>

#include "image.h"
#include "dip.h"
#include "bshowv4l.h"

void setShowAngle(float a);

/*main.cxx*/
#include "main.h"

#define ARROWS_USED 1
#define TIMEBOX_INITIAL_DURATION 10.0f

int frame_cnt=1;
extern int maks_frame;
extern int video_tracking;
static char label[12][10];
static char pcon_val[5][10];

char *awalan_file="video_image_";

char *radio_label[]={
"Template 1",
"Template 2",
"Template 3",
"Template 4",
NULL
};

115
116

float timebox_maxtime = TIMEBOX_INITIAL_DURATION;


float timebox_scale = 1.0f;
float timebox_start = 0.0f;
int nilai_slide=0;
int xm,ym,px1,py1,px2,py2,r1,g1,b1,r2,g2,b2;
float aspect_ratio=1.3;
#define MODE_ADD 0
#define MODE_SELECT 1

#define PICWH 256.0f


#define PICPOSX 100.0f
#define PICPOSY 150.0f
#define PICPOSX1 PICPOSX+PICWH+50.0f
#define WINH PICPOSY+PICWH+PICPOSY
#define WINW PICPOSX+PICWH+PICWH+50.0f+PICPOSX

#define JUMLAH_TITIK_FITUR 35

char dataPath[PUSTRING_MAX];
char dataFilename[PUSTRING_MAX];
int event_mode = MODE_SELECT;
//Event *curr_event = NULL;
int flag_klik=0;
int titik[JUMLAH_TITIK_FITUR][3];
int titikhasil[JUMLAH_TITIK_FITUR][3];
int hitmos=0;
int edit_mode=0;
int flag_template=0;
int draw_enable=0;
int open_camera=0;
int fps,time_b,timebased=0;
int flag_viewTemplate=0;
int video_tracking=0;
int flag_replay=0;
int konter_frame=1;

int curr_button =0;

void init_event(){
}
/*
titik[32][2]=0;
titik[33][2]=62;
titik[34][2]=29;
titik[35][2]=171;
*/
void drawString(char *data){
117

for(unsigned int i=0;i<strlen(data);i++){


glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,data[i]);
}
}

puFileSelector *pfileSelector=NULL;
puOneShot *capture_button;
puOneShot *replay_button;
puOneShot *gotoFrame;
puOneShot *tracking;
puArrowButton *fwd_button;
puArrowButton *rvr_button;
puText *teksframe;
puText *teksGoto;
puButton *dialog_button=NULL;

puButtonBox *pilihan_template;

puOneShot *hit_ok;
puText *pesan;
puInput *data;
puInput *inp_gotoFrame;
puMenuBar *menuBar;
puFrame *klWarna[4];
puFrame *krWarna[4];
puFrame *stsBar;
puText *stsMsg[12];
puSlider *pconSlide[5];
puText *pconLabel[5];
puText *pconVal[5];
puFrame *panel_kontrol;
puFrame *panel_info;
puText *text_info[5];
puText *label_info[5];
puSlider *korelaslide;
puInput *textKorelasi;

extern int frame_no;

void dismiss_dialog(puObject *){


dialog_button->hide();
}

void dialog(char *msg,float r, float g, float b){


dialog_button->setLegend(msg);
dialog_button->setColorScheme(r,g,b,1);
dialog_button->reveal();
}
118

void loadCB(puObject *){

void start_capture_cb(puObject *){


if(getsave_flag()==1){
setMaksFrame(0);
setsave_flag(0);
frame_no=1;

}else{
setMaksFrame(data->getIntegerValue());
setsave_flag(1);
}

}
void fwd_cb(puObject *){
char datafname[512];
if(frame_cnt>data->getIntegerValue())
frame_cnt=1;

sprintf(datafname,"%s%d.bmp",awalan_file,frame_cnt);
loadTextfile(datafname,&image1);
frame_cnt++;

}
void rvr_cb(puObject *){
char datafname[512];
if(frame_cnt==0)
frame_cnt=data->getIntegerValue();

sprintf(datafname,"%s%d.bmp",awalan_file,frame_cnt);
loadTextfile(datafname,&image1);
frame_cnt--;
}

void gotoFrame_cb(puObject *){


char datafile[512];
sprintf(datafile,"%s%d.bmp",awalan_file,inp_gotoFrame->getIntegerValue());
loadTextfile(datafile,&image1);

void replay_cb(puObject *){


/*
char datafname[512];
for (int i=1;i<maks_frame;i++){
sprintf(datafname,"video_image_%d.bmp",i);
loadTextfile(datafname,&image1);
119

}*/
if(flag_replay==0){
flag_replay=1;
konter_frame=1;
}
else{
flag_replay=0;
}
}

void track_cb(puObject *){

for(int i=0;i<JUMLAH_TITIK_FITUR;i++){

trackPoint(pTemplate[i],image1,pTemplate1[i],dataPos[i],textKorelasi-
>getFloatValue());
printf("posx= %d posy= %d\n",pTemplate1[i]->posy,pTemplate[i]-
>posy);
dataPos[i][0]=pTemplate1[i]->posx;
dataPos[i][1]=pTemplate1[i]->posy;
pTemplate[i]->posx=pTemplate1[i]->posx;
pTemplate[i]->posy=pTemplate1[i]->posy;
titikhasil[i][0]=dataPos[i][0];
titikhasil[i][1]=dataPos[i][1];
tulis_file("yayang.bcd",titikhasil,frame_cnt);
}

void korelaslide_cb(puObject *){


textKorelasi->setValue(korelaslide->getFloatValue());
}
void pickFile(puObject *){
char path[100];
char fname[100];

pfileSelector->getValue(path);
//puDeleteObject(pfileSelector);
//pfileSelector=NULL;

if(path[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
return;
}

char *p =NULL;

for(int i=strlen(path);i>=0;i--){
120

if(path[i]=='/' || path[i]=='\\'){
p=&(path[i+1]);
path[i]='\0';
break;
}

}//loop i

if(p==NULL){
strcpy(fname,path);
//printf("path %s\n",path);
}
else{
strcpy(fname,p);
//printf("p %s",p);
}
if(pfileSelector->getStringValue()[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
return;
}

//strcpy(dataPath,p);
//strcpy(dataFilename,fname);
//printf("%s \n",dataFilename);

loadTextfile(pfileSelector->getStringValue(),&image1);

puDeleteObject(pfileSelector);
pfileSelector=NULL;

//ini buat dialog membuka image 2


void pickFile2(puObject *){
char path[100];
char fname[100];

pfileSelector->getValue(path);
//puDeleteObject(pfileSelector);
//pfileSelector=NULL;

if(path[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
return;
}

char *p =NULL;
121

for(int i=strlen(path);i>=0;i--){
if(path[i]=='/' || path[i]=='\\'){
p=&(path[i+1]);
path[i]='\0';
break;
}

}//loop i

if(p==NULL){
strcpy(fname,path);
//printf("path %s\n",path);
}
else{
strcpy(fname,p);
//printf("p %s",p);
}
if(pfileSelector->getStringValue()[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
return;
}

//strcpy(dataPath,p);
//strcpy(dataFilename,fname);
//printf("%s \n",dataFilename);

loadTextfile(pfileSelector->getStringValue(),&image2);

puDeleteObject(pfileSelector);
pfileSelector=NULL;

char *file_submenu[]={
"Exit",
"________________",
"Preference",
"Open Camera",
"Close Camera",
"Load Image 2",
"________________",
"Load Image 1 ",
NULL
};

void keluar_cb(puObject *){


exit(0);
}
122

//yang ini diganti buat nge-load image ke 2


void simpan_cb(puObject *){
if(pfileSelector==NULL){
pfileSelector=new puFileSelector((800-320)/2,(600-
270)/2,320,270,ARROWS_USED,dataPath,"Load Bitmap(*.bmp)..image 2");
pfileSelector->setCallback(pickFile2);
}

void loadFile_cb(puObject *){


if(pfileSelector==NULL){
pfileSelector=new puFileSelector((800-320)/2,(600-
270)/2,320,270,ARROWS_USED,dataPath,"Load Bitmap(*.bmo)..image 1");
pfileSelector->setCallback(pickFile);
}

void prefer_cb(puObject *){


// findPointCorrelation(titik,image1,dataPos,0.9f);
for(int i=0;i<JUMLAH_TITIK_FITUR;i++){

trackPoint(pTemplate[i],image1,pTemplate1[i],dataPos[i],textKorelasi-
>getFloatValue());
printf("%d %d\n",pTemplate1[i]->posy,pTemplate[i]->posy);
dataPos[i][0]=pTemplate1[i]->posx;
dataPos[i][1]=pTemplate1[i]->posy;
}
}

void loadFromcam_cb(puObject *){


if(open_camera!=1){
open_camera=1;
}
}
void closeCamera_cb(puObject *){
if(open_camera!=0){
open_camera=0;
}
}

puCallback file_submenuCB[]={
keluar_cb,
NULL,
prefer_cb,
loadFromcam_cb,
closeCamera_cb,
123

simpan_cb,
NULL,
loadFile_cb,
NULL
};

char *view_submenu[]={
"Zoom In",
"Zoom Out",
NULL
};

void zoomIn_cb(puObject *){}


void zoomOut_cb(puObject *){}

puCallback view_submenuCB[]={
zoomIn_cb,
zoomOut_cb,
NULL
};

char *filter_submenu[]={
"Median Filter",
"Mean Filter",
"Gaussian Filter",
"Blur",
NULL
};

void medfilCB(puObject *){


medianFilterfn();
}
void menfilCB(puObject *){
meanFilterfn();
}
void gausfilCB(puObject *){
gaussianFilterfn();
}
void blurCB(puObject *){}

puCallback filter_submenuCB[]={
medfilCB,
menfilCB,
gausfilCB,
blurCB,
NULL
};

char *image_submenu[]={
"Edge Detetction",
124

"_______________",
"GreyScale",
"Histogram",
"Treshhold",
"RGB Channel",
NULL
};

void rgb_cb(puObject *){}

void histogram_cb(puObject *){

if(histFlag==0)
histFlag=1;
else
histFlag=0;

void treshold_cb(puObject *){


tresholdfn();
}
void edge_cb(puObject *){}
void grey_cb(puObject *){
greyScalefn();
}

puCallback image_submenuCB[]={
edge_cb,
NULL,
grey_cb,
histogram_cb,
treshold_cb,
rgb_cb,
NULL
};

char *face_submenu[]={
"Create Template",
"Reopen Template",
"Save Template",
"Test Tracking",
"____________________",
"Stop Tracking Online",
"Run Process Online",
NULL
};
//Proses pembuatan template
void createTemplate_cb(puObject *){
125

if(edit_mode == 0){
edit_mode = 1;
flag_template=1;
for(int i = 0; i < JUMLAH_TITIK_FITUR;i++){
titik[i][0] = 0;
titik[i][1] = 0;
//titik[i][2] = 0;
}
hitmos = 0;
}else{
edit_mode = 0;
flag_template=0;
}

void pickTemplatefile(puObject *){


char path[100];
char fname[100];

pfileSelector->getValue(path);
puDeleteObject(pfileSelector);
pfileSelector=NULL;

if(path[0]=='\0'){
return;
}

char *p =NULL;

for(int i=strlen(path);i>=0;i--){
if(path[i]=='/' || path[i]=='\\'){
p=&(path[i+1]);
path[i]='\0';
break;
}

}//loop i

if(p==NULL){
strcpy(fname,path);
//printf("path %s\n",path);
}
else{
strcpy(fname,p);
//printf("p %s",p);
}

// if(pfileSelector->getStringValue()[0]=='\0'){
// puDeleteObject(pfileSelector);
126

// pfileSelector=NULL;
// return;
// }
//printf("%s \n",pfileSelector->getStringValue());
readTemplatefile(fname,titik);

puDeleteObject(pfileSelector);
pfileSelector=NULL;
//flag_template=1;

//fungsi untuk trasfer data template titik fitur

flag_viewTemplate=1;
for(int i=0;i<JUMLAH_TITIK_FITUR;i++){
pTemplate1[i]=(PointTemplate *) malloc(sizeof(PointTemplate));
openPointTemplate(&pTemplate[i],image2,titik[i][0],titik[i][1]);
pTemplate1[i]->posx=pTemplate[i]->posx;
pTemplate1[i]->posy=pTemplate[i]->posy;
titikhasil[i][0]=pTemplate[i]->posx;
titikhasil[i][1]=pTemplate[i]->posy;

}
//histFlag=1;

void reopenTemplate_cb(puObject *){


//readTemplatefile("test.bcd",titik);
//flag_template=1;

if(pfileSelector==NULL){
pfileSelector=new puFileSelector((800-320)/2,(600-
270)/2,320,270,1,dataPath,"Load Template(*.bcd)...");
pfileSelector->setCallback(pickTemplatefile);
}

}
void testTracking_cb(puObject *){
/*
printf("pilihan = %d\n",pilihan_template->getValue());
switch(pilihan_template->getValue()){
case 0:
//findCorrelation(tImage1,image1,dataPos,textKorelasi-
>getFloatValue());
break;
case 1:
//findCorrelation(tImage2,image1,dataPos,textKorelasi-
>getFloatValue());
break;
127

case 2:
//findCorrelation(tImage3,image1,dataPos,textKorelasi-
>getFloatValue());
break;
case 3:
//findCorrelation(tImage4,image1,dataPos,textKorelasi-
>getFloatValue());
break;
}
*/

}
void monitor_cb(puObject *){

video_tracking=0;
/*
switch(pilihan_template->getValue()){
case 0:
//dataPos[0]=tImage1->posx;
//dataPos[1]=tImage1->posy;
break;
case 1:
//dataPos[0]=tImage2->posx;
//dataPos[1]=tImage2->posy;
break;
case 2:
//dataPos[0]=tImage3->posx;
//dataPos[1]=tImage3->posy;
break;
case 3:
//dataPos[0]=tImage4->posx;
//dataPos[1]=tImage4->posy;
break;
}
*/

}
void run_cb(puObject *){
video_tracking=1;
/*
switch(pilihan_template->getValue()){
case 0:
video_tracking=1;
//dataPos[0]=tImage1->posx;
//dataPos[1]=tImage1->posy;
break;
case 1:
video_tracking=2;
//dataPos[0]=tImage2->posx;
//dataPos[1]=tImage2->posy;
128

break;
case 2:
video_tracking=3;
//dataPos[0]=tImage3->posx;
//dataPos[1]=tImage3->posy;
break;
case 3:
video_tracking=4;
//dataPos[0]=tImage4->posx;
//dataPos[1]=tImage4->posy;
break;
}

*/
}

void sTemplate(puObject *){

char path[PUSTRING_MAX];
char fname[PUSTRING_MAX];
pfileSelector->getValue(path);
if(path[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
//dialog("Gagal Melakukan Penyimpanan",1,0,0);
return;
}

char *p=NULL;
int i;

for(i= strlen(path);i>=0;i--)
if(path[i]=='/' || path[i]=='\\'){
p=&(path[i+1]);
path[i]='\0';
break;
}
if(p==NULL) {
strcpy(fname,path);
}else{
strcpy(fname,p);
}

if(pfileSelector->getStringValue()[0]=='\0'){
puDeleteObject(pfileSelector);
pfileSelector=NULL;
dialog("Gagal Menyimpan Template",1,0,0);
return;
}
FILE *fd=fopen(pfileSelector->getStringValue(),"wa");
129

puDeleteObject(pfileSelector);
pfileSelector=NULL;

if(fd==NULL){
dialog("Tidak bisa membuat file template",1,0,0);
return;
}
//ini buat nampilin data titik hitmos yang sudah disimpan. hitmos[32][3]
//hitmos[][0]=posx hitmos[][1]=posy hitmos[][3]=data
for(int i=0;i<35;i++){
for(int j=0;j<3;j++){
printf("data : %d ",titik[i][j]);
}
printf("\n");
}

fwrite(titik,sizeof(int),35*3,fd);
fclose(fd);
dialog("Penyimpanan sukses !!!!",1,1,0);

}
//Program penyimpanan file template
void saveTemplate_cb(puObject *){
if(pfileSelector==NULL){
pfileSelector=new puFileSelector((800-320)/2,(600-
270)/2,320,270,ARROWS_USED,dataPath,"Save Template(*.bcb)");
pfileSelector->setCallback(sTemplate);

char guess_fname[PUSTRING_MAX];
strcpy(guess_fname,dataFilename);
for(int i=strlen(guess_fname);i>=0;i--)
if(guess_fname[i]=='.'){
guess_fname[i]='\0';
break;
}
strcat(guess_fname,".bcd");
pfileSelector->setInitialValue(guess_fname);
}
}

puCallback face_submenuCB[]={
createTemplate_cb,
reopenTemplate_cb,
saveTemplate_cb,
testTracking_cb,
NULL,
monitor_cb,
run_cb,
NULL
};
130

char *help_submenu[]={
"About This Program",
NULL
};

void about_cb(puObject *){}

puCallback help_submenuCB[]={
about_cb,
NULL
};

void slideBrightness_cb(puObject *ob){


setBrightness((int) (ob->getFloatValue()*65535));
sprintf(pcon_val[0],"%d",getBrightness());
pconVal[0]->setLabel(pcon_val[0]);
}

void slideContrast_cb(puObject *ob){


setContrast((int) (ob->getFloatValue()*65535));
sprintf(pcon_val[1],"%d",getContrast());
pconVal[1]->setLabel(pcon_val[1]);
}

void slideColor_cb(puObject *ob){


setColorb((int) (ob->getFloatValue()*65535));
sprintf(pcon_val[2],"%d",getColorb());
pconVal[2]->setLabel(pcon_val[2]);
}

void slideHue_cb(puObject *ob){


setHue((int) (ob->getFloatValue()*65535));
sprintf(pcon_val[3],"%d",getHue());
pconVal[3]->setLabel(pcon_val[3]);
}

void slideWhiteness_cb(puObject *ob){


setWhiteness((int) (ob->getFloatValue()*65535));
sprintf(pcon_val[4],"%d",getWhiteness());
pconVal[4]->setLabel(pcon_val[4]);
}

void button_apply_cb(puObject *){


copyImage(image2,image1);
}

ssgRoot * skinScene = NULL;


ssgRoot * boneScene = NULL;
131

void init_database(){
skinScene=new ssgRoot;
boneScene=new ssgRoot;
}

void penggaris(float posx,float posy,float panjang, int mode){


//mode 1 = penggaris horisontal
//mode 0 = penggaris vertikal
char label[30];
unsigned int i;
switch(mode){
case 0:
sprintf(label,"%2.0f",0.0f);
glRasterPos2f(posx+5,posy);
drawString(label);

glColor4f(0.6f,0.60f,0.6f,1);

glBegin(GL_LINES);
glVertex3f(posx,posy,-1);
glVertex3f(posx,posy+panjang,-1);

for(i=0;i<panjang;i+=5){
glVertex3f(posx-5,posy+i,-1);
glVertex3f(posx+5,posy+i,-1);
}
for(i=0;i<panjang;i+=25){
glVertex3f(posx-10,posy+i,-1);
glVertex3f(posx+10,posy+i,-1);
}
glEnd();

sprintf(label,"%2.0f",panjang);
glRasterPos2f(posx-10,posy+panjang+2);
drawString(label);

break;
case 1:
glColor4f(0.6f,0.6f,0.6f,1.0f);
glBegin(GL_LINES);
glVertex3f(posx,posy,-1);
glVertex3f(posx+panjang,posy,-1);
for(i=0;i<panjang;i+=5){
glVertex3f(posx+i,posy,-1);
glVertex3f(posx+i,posy+5,-1);
}
for(i=0;i<panjang;i+=25){
glVertex3f(posx+i,posy,-1);
132

glVertex3f(posx+i,posy+15,-1);
}
glEnd();

break;

}
void kotakWarna(int posx,int posy,int size){
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_POLYGON);
glVertex2f(posx,posy);
glVertex2f(posx+size,posy);
glVertex2f(posx+size,posy+size);
glVertex2f(posx,posy+size);
glEnd();
}

void initRender(){
glClearColor(1.0f,1.0f,1.0f,1.0f);
glPointSize(3);
glLineWidth(0.5);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_LINE_STIPPLE);
//glEnable(GL_TEXTURE_2D);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

void redraw(){
int w,h;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

w = puGetWindowWidth();
h = puGetWindowHeight();

//glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
133

gluOrtho2D(0,w,0,h);
// gluPerspective(90.0f,1.0f,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_LIGHTING);

glLineWidth(1.0);
glPushAttrib(GL_LINE_BIT);
glLineStipple(3,0xFFFF);

if(histFlag==1){

customHistogram(image1,titik[0][0],titik[0][1],titik[1][0],titik[1][1],dataTemp)
;
drawCurve(50,200,dataTemp,2,4);

customHistogram(image1,titik[2][0],titik[2][1],titik[3][0],titik[3][1],dataTemp)
;
drawCurve(50,300,dataTemp,2,3);
/*
histogramfn(image1,dataTemp,4);
drawCurve(50,200,dataTemp,10,4);
histogramfn(image1,dataTemp,1);
drawCurve(50,200,dataTemp,10,1);
histogramfn(image1,dataTemp,2);
drawCurve(50,200,dataTemp,10,2);
histogramfn(image1,dataTemp,3);
drawCurve(50,200,dataTemp,10,3);
*/
}
//display tracking

if(flag_viewTracking==1){
glColor3f(1.0f,1.0f,0.0f);
glPointSize(3);
glBegin(GL_POINTS);
for(int i=0;i<JUMLAH_TITIK_FITUR;i++){
glVertex2f(50+dataPos[i][0],h-
(dataPos[i][1]+160));
}

glEnd();
glFlush();
}

if(flag_template==1){
glColor3f(1.0f,1.0f,0.0f);
sprintf(label[4],"_%d",titikhasil[hitmos][2]);
glRasterPos2i(xm,h-ym);
134

drawString(label[4]);

for(int i = 0; i < hitmos; i++){


sprintf(label[4],"%d",titikhasil[i][2]);
glRasterPos2i(titik[i][0]+400,h-(titik[i][1]+160));
drawString(label[4]);

glPointSize(3);
glBegin(GL_POINTS);
for(int i = 0; i < hitmos; i++){
glVertex2f(titik[i][0]+400,h-(titik[i][1]+160));

}
glEnd();
glFlush();
/*
glColor3f(0.0f,1.0f,1.0f);
glLineWidth(0.5);
glPushAttrib(GL_LINE_BIT);
glLineStipple(3,0xAAAA);
for(int i = 0; i <
JUMLAH_SEGIEMPAT_YANG_BISA_DIBIKIN*2; i+=2){
glBegin(GL_LINE_LOOP);
glVertex2f(titik[i][0]+400,h-(titik[i][1]+160));
glVertex2f(titik[i+1][0]+400,h-(titik[i][1]+160));
glVertex2f(titik[i+1][0]+400,h-(titik[i+1][1]+160));
glVertex2f(titik[i][0]+400,h-(titik[i+1][1]+160));
glEnd();
}
glFlush();*/
}

if(flag_viewTemplate==1){
glColor3f(1.0f,1.0f,0.0f);
glPointSize(3);
glBegin(GL_POINTS);
for(int i=0;i<JUMLAH_TITIK_FITUR;i++){
glVertex2f(400+titik[i][0],h-
(titik[i][1]+160));
}
glEnd();
glFlush();

if(flag_replay==1 && open_camera==0){


char datafname[512];
135

sprintf(datafname,"%s%d.bmp",awalan_file,konter_frame);
loadTextfile(datafname,&image1);

for(int i=0;i<JUMLAH_TITIK_FITUR;i++){

trackPoint(pTemplate[i],image1,pTemplate1[i],dataPos[i],textKorelasi-
>getFloatValue());
//printf("posx= %d posy=
%d\n",pTemplate1[i]->posy,pTemplate[i]->posy);
dataPos[i][0]=pTemplate1[i]->posx;
dataPos[i][1]=pTemplate1[i]->posy;
pTemplate[i]->posx=pTemplate1[i]->posx;
pTemplate[i]->posy=pTemplate1[i]->posy;
titikhasil[i][0]=pTemplate1[i]->posx;
titikhasil[i][1]=pTemplate1[i]->posy;

tulis_file("yayang.bcd",titikhasil,konter_frame);
}

if(konter_frame>=data->getIntegerValue())
konter_frame=1;
else
konter_frame++;

if(open_camera==0){
glRasterPos2i(50,200);
glDrawPixels(image1->sizex,image1-
>sizey,GL_RGB,GL_UNSIGNED_BYTE,image1->data);

glRasterPos2i(400,200);
glDrawPixels(image2->sizex,image2-
>sizey,GL_RGB,GL_UNSIGNED_BYTE,image2->data);

//glDrawPixels(IMAGE_WIDTH_DS,IMAGE_HEIGHT_DS,GL_BGR,GL_U
NSIGNED_BYTE,disp_image);
glFlush();

//penggaris(380.0f,150.0f,255.0f,0);
//penggaris(100.0f,410.0f,255.0f,1);
//penggaris(400.0f,410.0f,255.0f,1);
136

if(open_camera==1){
videoDisplayImage();
}

glColor3f(0.96f,0.76f,0.97f);
glLineWidth(10.0f);
glPushAttrib(GL_LINE_BIT);
glLineStipple(3,0xffff);
glBegin(GL_POLYGON);
glVertex2f(45,195);
glVertex2f(375,195);
glVertex2f(375,445);
glVertex2f(45,445);
glEnd();
glBegin(GL_POLYGON);
glVertex2f(395,195);
glVertex2f(725,195);
glVertex2f(725,445);
glVertex2f(395,445);
glEnd();

//gambar latar wireframe


glRasterPos2i(640,0);
glDrawPixels(image3->sizex,image3-
>sizey,GL_RGB,GL_UNSIGNED_BYTE,image3->data);
//histogramfn(image1,dataTemp);
//drawCurve(100,450,dataTemp,10);
glEnable(GL_LIGHTING);

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glLoadIdentity();

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER,0.1f);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);

puDisplay();
w = puGetWindowWidth();
h = puGetWindowHeight();

glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT |
GL_LIGHTING_BIT);

glDisable(GL_LIGHTING);
137

glDisable(GL_FOG);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);

//videoCaptureImage();
//update mouse posistion
sprintf(label[0],"Xm = %d",xm);
stsMsg[0]->setLabel(label[0]);
sprintf(label[1],"Ym = %d",ym);
stsMsg[1]->setLabel(label[1]);
sprintf(label[2],"Px1 = %d",px1);
stsMsg[2]->setLabel(label[2]);
sprintf(label[3],"Py1 = %d",py1);
stsMsg[3]->setLabel(label[3]);
/*
sprintf(label[4],"R1 = %d",getR(image1,px1,py1));
stsMsg[4]->setLabel(label[4]);
sprintf(label[5],"G1 = %d",getG(image1,px1,py1));
stsMsg[5]->setLabel(label[5]);
sprintf(label[6],"B1 = %d",getB(image1,px1,py1));
stsMsg[6]->setLabel(label[6]);
*/
sprintf(label[7],"Px2 = %d",px2);
stsMsg[7]->setLabel(label[7]);
sprintf(label[8],"Py2 = %d",py2);
stsMsg[8]->setLabel(label[8]);

sprintf(label[9],"R2 = %d",getR(image2->data,px2,py2));
stsMsg[9]->setLabel(label[9]);
sprintf(label[10],"G2 = %d",getG(image2->data,px2,py2));
stsMsg[10]->setLabel(label[10]);
sprintf(label[11],"B2 = %d",getB(image2->data,px2,py2));
stsMsg[11]->setLabel(label[11]);

/* //update color picker


klWarna[0]-
>setColour(PUCOL_FOREGROUND,(GLfloat)getR(image1,px1,py1)/255,(GLfloat)getG
(image1,px1,py1)/255,(GLfloat)getB(image1,px1,py1)/255,1.0f);
klWarna[1]-
>setColour(PUCOL_FOREGROUND,0.0f,0.0f,(GLfloat)getB(image1,px1,py1)/255,1.0f);
klWarna[2]-
>setColour(PUCOL_FOREGROUND,0.0f,(GLfloat)getG(image1,px1,py1)/255,0.0f,1.0f);
klWarna[3]-
>setColour(PUCOL_FOREGROUND,(GLfloat)getR(image1,px1,py1)/255,0.0f,0.0f,1.0f);
*/
138

krWarna[0]->setColour(PUCOL_FOREGROUND,(GLfloat)getR(image2-
>data,px2,py2)/255,(GLfloat)getG(image2->data,px2,py2)/255,(GLfloat)getB(image2-
>data,px2,py2)/255,1.0f);
krWarna[1]-
>setColour(PUCOL_FOREGROUND,0.0f,0.0f,(GLfloat)getB(image2-
>data,px2,py2)/255,1.0f);
krWarna[2]->setColour(PUCOL_FOREGROUND,0.0f,(GLfloat)getG(image2-
>data,px2,py2)/255,0.0f,1.0f);
krWarna[3]->setColour(PUCOL_FOREGROUND,(GLfloat)getR(image2-
>data,px2,py2)/255,0.0f,0.0f,1.0f);

//menghitung frame per second


fps++;
time_b=glutGet(GLUT_ELAPSED_TIME);
if(time_b-timebased>1000){
sprintf(label[6],"%3.2f Fps",fps*1000.0/(time_b-timebased));
text_info[0]->setLabel(label[6]);
timebased=time_b;
fps=0;
}

glutPostRedisplay();
glutSwapBuffers();
}

void reshape(int w, int h){


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// ssgSetFOV(60.0f,60.0f * (float)h/(float)w);
// glutPostRedisplay();
}

void updateEventQueue(int button,int x,int y,int new_click){


y=puGetWindowHeight()-y;
}

void mousefn(int button, int updown,int x,int y){


int w,h;
// int xx;
w=puGetWindowWidth();
h=puGetWindowHeight();
puMouse(button,updown,x,y);
curr_button = button;
updateEventQueue(curr_button,x,y,updown == PU_DOWN);
139

if(button==GLUT_LEFT_BUTTON && updown==GLUT_DOWN &&


edit_mode==1 && draw_enable==1){
//if(x%2!=0) x++;
//if(y%2!=0) y++;
//kalo dah max gak usah nggambar lagi
if(hitmos < JUMLAH_TITIK_FITUR ){
//if(flag_klik==0){
//flag_klik=1;
titik[hitmos][0]=x-400;
//titik[hitmos][1]=(((x-400)-titik[hitmos-
1][0])*1.3)+titik[hitmos-1][1];
titik[hitmos][1]=y-160;

//titik[hitmos][2]=(getR(image2-
>data,titik[hitmos][0],titik[hitmos][1])+getG(image2-
>data,titik[hitmos][0],titik[hitmos][1])+getB(image2-
>data,titik[hitmos][0],titik[hitmos][1]))/3;
//inisialisasi nilai kotak awal
//titik[hitmos+1][0]=x-400;
//titik[hitmos+1][1]=y-160;

//}
//if( hitmos%2==0){
/*
else{
flag_klik=0;
titik[hitmos][0]=x-400;
//titik[hitmos+1][1]=y-160;
xx=int(titik[hitmos-1][0]*aspect_ratio);

titik[hitmos][1]= y-160;//(((x-400)-
xx))+titik[hitmos-1][1];
//if(titik[hitmos][1]%2!=0)titik[hitmos][1]++;

}*/
// printf("hm = %d data = %d\n",hitmos,titik[hitmos][2]);
hitmos++;
}

}
//ngapus semua kotak saat klik kanan
if(button==GLUT_RIGHT_BUTTON && updown==GLUT_DOWN){
for(int i = 0; i < JUMLAH_TITIK_FITUR;i++){
titik[i][0] = 0;
titik[i][1] = 0;
//titik[i][2] = 0;
}
hitmos = 0;
}
}
140

void specialfn(int key,int , int){


puKeyboard(key + PU_KEY_GLUT_SPECIAL_OFFSET,PU_DOWN);

void passmotionfn(int x, int y){


int w,h;
//int xx;
w=puGetWindowWidth();
h=puGetWindowHeight();
puMouse(x,y);
xm=x;
ym=y;
if(x>=50 && x<=370 && y>=h-440 && y<=h-200){
px1=x-50;
py1=y-(h-440);
}else{
px1=0;
py1=0;
}

if(x>=400 && x<=720 && y>=h-440 && y<=h-200){


px2=x-400;
py2=y-(h-440);
draw_enable=1;
}else{
px2=0;
py2=0;
draw_enable=0;
}
/*
if(flag_klik==1){

titik[hitmos][0]=x-400;
xx=int (titik[hitmos-1][0]*aspect_ratio);
titik[hitmos][1]=y-160;//(((x-400)-xx))+titik[hitmos-1][1];
//if(titik[hitmos][1]%2!=1)titik[hitmos][1]++;
//px2=x-400;
//py2=titik[hitmos-1][0];
}*/
if(px1 !=0 || py1 !=0 || py2!=0 || px2!=0){
glutSetCursor(GLUT_CURSOR_CROSSHAIR);
}else{
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
}

}
141

void motionfn(int x, int y){


puMouse(x,y);
updateEventQueue(curr_button,x,y,FALSE);
}

void keyfn(unsigned char key,int x, int y){

puKeyboard(key,PU_DOWN);

if(key=='B'){
if(edit_mode == 0){
edit_mode = 1;
flag_template=1;
}else{
edit_mode = 0;
flag_template=0;
}
}else if(key=='O'){
readTemplatefile("test1.bcd",titik);
for(int i=0;i<8;i++){
for(int j=0;j<2;j++){
printf("%d ",titik[i][j]);
}
printf("\n");
}
flag_template=1;
}else if(key=='S'){
/*
for(int i=0;i<8;i++){
for(int j=0;j<2;j++){
printf("%d ",titik[i][j]);
}
printf("\n");
}*/
saveTemplatefile(titik);

}else if(key=='1'){
aspect_ratio=1.3;
}else if(key=='2'){
aspect_ratio=0.75;
}else if(key=='3'){
aspect_ratio=1.0;
}else{
}
}
//Inisialisasi GUI
void init_graphic(){
//ID titik template
titik[0][2]=48; titik[1][2]=49; titik[2][2]=51;
titik[3][2]=50;
142

titik[4][2]=17; titik[5][2]=16; titik[6][2]=18;


titik[7][2]=15;
titik[8][2]=3; titik[9][2]=53; titik[10][2]=56; titik[11][2]=52;
titik[12][2]=57; titik[13][2]=23; titik[14][2]=20; titik[15][2]=19;
titik[16][2]=24; titik[17][2]=5; titik[18][2]=6; titik[19][2]=59;
titik[20][2]=26; titik[21][2]=76; titik[22][2]=75; titik[23][2]=64;
titik[24][2]=31; titik[25][2]=7; titik[26][2]=8; titik[27][2]=83;
titik[28][2]=81; titik[29][2]=89; titik[30][2]=88; titik[31][2]=10;
titik[32][2]=0; titik[33][2]=62; titik[34][2]=29;

//ID titik hasil perpindahan


titikhasil[0][2]=48; titikhasil[1][2]=49; titikhasil[2][2]=51; titikhasil[3][2]=50;
titikhasil[4][2]=17; titikhasil[5][2]=16; titikhasil[6][2]=18; titikhasil[7][2]=15;
titikhasil[8][2]=3; titikhasil[9][2]=53; titikhasil[10][2]=56; titikhasil[11][2]=52;
titikhasil[12][2]=57; titikhasil[13][2]=23; titikhasil[14][2]=20;
titikhasil[15][2]=19;
titikhasil[16][2]=24; titikhasil[17][2]=5; titikhasil[18][2]=6;
titikhasil[19][2]=59;
titikhasil[20][2]=26; titikhasil[21][2]=76; titikhasil[22][2]=75;
titikhasil[23][2]=64;
titikhasil[24][2]=31; titikhasil[25][2]=7; titikhasil[26][2]=8;
titikhasil[27][2]=83;
titikhasil[28][2]=81; titikhasil[29][2]=89; titikhasil[30][2]=88;
titikhasil[31][2]=10;
titikhasil[28][2]=81; titikhasil[29][2]=89; titikhasil[30][2]=88;
titikhasil[31][2]=10;
titikhasil[32][2]=0; titikhasil[33][2]=62; titikhasil[34][2]=29;

int w,h;
int fake_argc = 1;
char *fake_argv[3];
fake_argv[0]="FACIAL FITUR TRACKING BASED CORRELATION
TEMPLATE MATCHING ON IMAGE SEQUENCE";
fake_argv[1]="EMBOH VERSION";
fake_argv[2]=NULL;

glutInitWindowPosition(0,0);
glutInitWindowSize(800,600);
glutInit(&fake_argc,fake_argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH |
GLUT_ALPHA);
glutCreateWindow(fake_argv[0]);
initRender();
openTexture();
//loadTexture(1,image1);
//loadTexture(2,image2);
videoInitCaptureDevice("/dev/video0",0);
glutDisplayFunc(&redraw);
glutIdleFunc(&videoCaptureImage);
143

glutReshapeFunc(&reshape);
glutKeyboardFunc(&keyfn);
glutSpecialFunc(&specialfn);
glutMouseFunc(&mousefn);
glutMotionFunc(&motionfn);
glutPassiveMotionFunc(passmotionfn);

ssgInit();
puInit();
puSetDefaultStyle(PUSTYLE_SMALL_SHADED);
puSetDefaultFonts(PUFONT_HELVETICA_10,PUFONT_HELVETICA_10);

glClearColor(1.0f,1.0f,1.0f,1.0f);

//ssgSetFOV(60.0f,0.0f);
//ssgSetNearFar(1.0f,700.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

w = puGetWindowWidth();
h = puGetWindowHeight();

//sgSetVec3(sunposn,0.2f,0.5f,0.5f);
//ssgGetLight(0)->setPosition(sunposn);

menuBar = new puMenuBar();


{
menuBar->add_submenu("File ",file_submenu,file_submenuCB);
menuBar->add_submenu("View
",view_submenu,view_submenuCB);
menuBar->add_submenu("Filter
",filter_submenu,filter_submenuCB);
menuBar->add_submenu("Image
",image_submenu,image_submenuCB);
menuBar->add_submenu("Face
",face_submenu,face_submenuCB);
menuBar->add_submenu("Help
",help_submenu,help_submenuCB);
}
menuBar->close();
w=puGetWindowWidth();
h=puGetWindowHeight();

//membuat color picker kiri gambar


for(int i=0;i<4;i++){
klWarna[i]=new puFrame(30,200+(i*20),45,215+(i*20));
klWarna[i]->setStyle(PUSTYLE_BOXED);
klWarna[i]-
>setColour(PUCOL_FOREGROUND,0.0f,1.0f,1.0f,1.0f);
144

}
//membuat color picker kanan gambar
for(int i=0;i<4;i++){
krWarna[i]=new puFrame(725,200+(i*20),740,215+(i*20));
krWarna[i]->setStyle(PUSTYLE_BOXED);
krWarna[i]-
>setColour(PUCOL_FOREGROUND,1.0f,1.0f,0.0f,1.0f);
}
//membuat status bar
stsBar=new puFrame(3,3,w-3,23);
stsBar->setStyle(PUSTYLE_BOXED);
stsBar->setColour(PUCOL_FOREGROUND,0.1f,0.1f,0.1f,0.5f);
//membuat text buat status bar
for(int i=0;i<12;i++){
stsMsg[i]=new puText(10+(i*50),3);
//sMsg[i]->setLabel(msg[i]);
stsMsg[i]->setColour(PUCOL_LABEL,1.0f,1.0f,0.0f,1.0f);
}

//group panel kontrol


panel_kontrol=new puFrame(45,50,375,190);
panel_kontrol->setStyle(PUSTYLE_BOXED);
panel_kontrol->setColour(PUCOL_FOREGROUND,0.8f,0.8f,0.8f,1.0f);

fwd_button=new puArrowButton(50,130,80,155,PUARROW_LEFT);
rvr_button=new puArrowButton(85,130,115,155,PUARROW_RIGHT);
fwd_button->setCallback(rvr_cb);
rvr_button->setCallback(fwd_cb);
capture_button=new puOneShot(50,160,135,185);
capture_button->setLegend("Start Capture");
capture_button->setCallback(start_capture_cb);
replay_button=new puOneShot(50,100,135,125);
replay_button->setLegend("Replay");
replay_button->setCallback(replay_cb);
tracking=new puOneShot(145,130,200,155);
tracking->setLegend("Tracking");
tracking->setCallback(track_cb);
gotoFrame=new puOneShot(50,70,135,95);
gotoFrame->setLegend("Goto Frame");
gotoFrame->setCallback(gotoFrame_cb);

data = new puInput(145,160,200,185);


data->setValue("100");
teksframe=new puText(200,160);
teksframe->setLabel("Frames");
inp_gotoFrame=new puInput(145,70,200,95);
inp_gotoFrame->setValue("1");
145

pilihan_template=new puButtonBox(270,85,370,185,radio_label,1);
korelaslide=new puSlider(250,85,100,TRUE);
korelaslide->setDelta(0.01f);
korelaslide->setValue(0.99f);
korelaslide->setCallback(korelaslide_cb);
textKorelasi=new puInput(205,120,245,145);
textKorelasi->setValue(korelaslide->getFloatValue());
//end of group
panel_info=new puFrame(395,50,725,150);
panel_info->setStyle(PUSTYLE_BOXED);
panel_info->setColour(PUCOL_FOREGROUND,0.8f,0.8f,0.8f,1.0f);

label_info[0]=new puText(405,140);
label_info[0]->setLabelPlace(PUPLACE_CENTERED_RIGHT);
label_info[1]=new puText(445,125);
label_info[1]->setLabelPlace(PUPLACE_CENTERED_RIGHT);
label_info[2]=new puText(450,110);
label_info[2]->setLabelPlace(PUPLACE_CENTERED_RIGHT);
label_info[3]=new puText(445,95);
label_info[3]->setLabelPlace(PUPLACE_CENTERED_RIGHT);
label_info[4]=new puText(442,80);
label_info[4]->setLabelPlace(PUPLACE_CENTERED_RIGHT);

for(int i=0;i<5;i++){
text_info[i]=new puText(520,140-(i*15));
text_info[i]-
>setLabelPlace(PUPLACE_CENTERED_RIGHT);
}

label_info[0]->setLabel("Current Frame Speed :");


label_info[1]->setLabel("Current Time : Off");
label_info[2]->setLabel("Video Mode : OFF");
label_info[3]->setLabel("Offline Mode : ON");
label_info[4]->setLabel("Template Mode : OFF");
//group panel informasi

//end of group panel info

//menggambar slider untuk kontrol gambar


/*
for(int i=0;i<5;i++){
pconSlide[i]= new puSlider(120,170-(i*30),200,FALSE);
pconSlide[i]->setCBMode(PUSLIDER_DELTA);
pconSlide[i]->setDelta(0.01);
pconSlide[i]->setValue(0.0f);
pconLabel[i]=new puText(50,170-(i*30));
pconLabel[i]->setLabel(pcon_label[i]);
pconLabel[i]->setColour(PUCOL_LABEL,0.5f,0.5f,0.5f,1.0f);
sprintf(pcon_val[i],"%.2f",pconSlide[i]->getFloatValue());
pconVal[i]=new puText(330,170-(i*30));
146

pconVal[i]->setLabel(pcon_val[i]);
pconVal[i]->setColour(PUCOL_LABEL,0.5f,0.5f,0.5f,1.0f);
}

pconSlide[0]->setCallback(slideBrightness_cb);
pconSlide[1]->setCallback(slideContrast_cb);
pconSlide[2]->setCallback(slideColor_cb);
pconSlide[3]->setCallback(slideHue_cb);
pconSlide[4]->setCallback(slideWhiteness_cb);
*/
hit_ok = new puOneShot(400,165,500,190);
hit_ok->setLegend("Apply Changes");
hit_ok->setCallback(button_apply_cb);
//t_ok->setValue(FALSE);
//t_ok->se
//textbox input
//data->rejectInput();
//videoCaptureImage();
dialog_button=new puButton(300,240,"");
dialog_button->setSize(300,40);
dialog_button->setLegendFont(PUFONT_TIMES_ROMAN_24);
dialog_button->setCallback(dismiss_dialog);
dialog_button->setColorScheme(1,1,0,1);
dialog_button->hide();

int main(int argc, char **argv){


init_graphic();
init_database();
init_event();
// loadFile_cb(NULL);
glutPostRedisplay();
glutMainLoop();
return 0;

2. Program pemrosesan texture


/*image.h*/
GLuint texture[3];

unsigned char pix[320*240*3];


unsigned char *template_pic;

struct Image{
147

unsigned long sizex;


unsigned long sizey;
unsigned char *data;

};
typedef Image Image;

struct TempImage{
unsigned long sizex;
unsigned long sizey;
int posx;
int posy;
unsigned char *data;
};
typedef TempImage TempImage;

struct PointTemplate{
int posx;
int posy;
unsigned char data[25];
};
typedef PointTemplate PointTemplate;

//variabel image
//image1 = image 1 gambar sebelah kiri
//image2 = image 2 gambar sebelah kanan hasil pengolahan
//image3 = image 3 untuk tempat bertukar data sebelumnya di pindah ke image2

//tImage1 = timage 1 untuk gambar template 1


//tImage2 = timage 2 untuk gambar template 2
//tImage3 = timage 3 untuk gambar template 3
//tImage4 = timage 4 untuk gambar template 4

Image *image1,*image2,*image3,*image4;
TempImage *tImage1,*tImage2,*tImage3,*tImage4;
PointTemplate *pTemplate[35];
PointTemplate *pTemplate1[35];

int imageLoad(char *filename,Image *image){


FILE *file;
unsigned long size;
unsigned long i;
unsigned char temp;
if((file=fopen(filename,"rb"))==NULL){
printf("file tidak ada.....!\n");
return 0;
}
fseek(file,18,SEEK_CUR);
if((i=fread(&image->sizex,4,1,file))!=1){
148

printf("Error baca ukuran x\n");


return 0;
}

if((i=fread(&image->sizey,4,1,file))!=1){
printf("Error baca data ukuran y gambar\n");
return 0;
}

size = image->sizex * image->sizey * 3;


printf("Nama File = %s \n",filename);
fseek(file,28,SEEK_CUR);image->data=(unsigned char *) malloc(size);
if(image->data==NULL){
printf("Error Alokasi Memori\n");
return 0;
}

if((i=fread(image->data,size,1,file))!=1){
printf("Error pembacaan data \n");
return 0;
}

for(i=0;i<size;i+=3){
temp=image->data[i];
image->data[i]=image->data[i+2];
image->data[i+2]=temp;
//pix[i]=image->data[i];
//pix[i+1]=image->data[i+1];
//pix[i+2]=image->data[i+2];
}
//printf("%d %d %d \n",image->data[0],image->data[1],image->data[2]);

return 1;
}

void openTexture(){

image1 =(Image *) malloc(sizeof(Image));


if(image1==NULL){
printf("Error alokasi memori image asal...");
exit(0);
}

if(!imageLoad("video_image_1.bmp",image1)){
exit(1);
}

image2 =(Image *) malloc(sizeof(Image));


if(image2==NULL){
printf("Error alokasi memori image tujuan...");
149

exit(0);
}

if(!imageLoad("video_image_1.bmp",image2)){
exit(1);
}

image3=(Image *) malloc(sizeof(Image));
if(image3==NULL){
printf("Error alokasi memori temporari file ...");
}

if(!imageLoad("wire.bmp",image3)){
exit(1);
}

}
void copyImage(Image *src,Image *dst){
for(unsigned long i=0;i<src->sizex*src->sizey*3;i++){
dst->data[i]=src->data[i];
}
}

void loadTexture(int i,Image *image){


glGenTextures(i,&texture[i-1]);
glBindTexture(GL_TEXTURE_2D,texture[i-1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LI
NEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LIN
EAR);
glTexImage2D(GL_TEXTURE_2D,0,3,image->sizex,image-
>sizey,0,GL_RGB,GL_UNSIGNED_BYTE,image->data);

int loadTextfile(char *fname,Image **image){


*image =(Image *) malloc(sizeof(Image));
if(*image==NULL){
printf("Error alokasi memori image asal...");
exit(0);
}
if(!imageLoad(fname,*image)){
exit(1);
}
//loadTexture(1,image1);
return 1;
}

int readTemplatefile(char *fname,int buf[35][3]){


150

FILE* fp;
int count=35*3;

fp=fopen(fname,"r");
fread(buf,sizeof(int),count,fp);
/*
for(int i=0;i<8;i++){
buf[i][0]=buf[i][0]+400;
buf[i][1]=buf[i][1]+200;
}
*/
/*
for(int i=0;i<32;i++){
for(int j=0;j<3;j++){
printf("%d ",buf[i][j]);
}
printf("\n");
}*/

fclose(fp);
return 1;
}

void saveTemplatefile(int data[35][3]){


FILE* fp;
size_t objsize=sizeof(int);
size_t objcnt = 35*3;

if((fp=fopen("test.bcd","w"))==NULL){
printf("Tidak bisa membuat file\n");
exit(1);
}

for(int i=0;i<35;i++){
data[i][0]=data[i][0]-400;
data[i][1]=data[i][1]-200;
}
/*
for(int i=0;i<32;i++){
for(int j=0;j<3;j++){
printf("data : %d ",data[i][j]);
}
printf("\n");
}
*/
fwrite(data,objsize,objcnt,fp);
fclose(fp);
}
151

int tulis_file(char *fname,int data[35][3],int idframe){


FILE *fp,*fd;
char filename[50];
size_t objsize=sizeof(int);
size_t objcnt=35*3;
if((fp=fopen(fname,"w"))==NULL){
printf("Tidak bisa membuat file\n");
exit(1);
}

fwrite(data,objsize,objcnt,fp);
fclose(fp);
sprintf(filename,"yayang_%d.txt",idframe);
if((fd=fopen(filename,"w"))==NULL){
printf("tidak bisa membuat file teks");
exit(1);
}
fprintf(fd,"x;y;id\n");
for(int i=0;i<35;i++){
fprintf(fd,"%d;%d;%d\n",data[i][0],data[i][1],data[i][2]);

}
fclose(fd);
return 1;
}

unsigned char getR(unsigned char *imagedata,int posx,int posy){


unsigned char dtemp;
dtemp=imagedata[((posx+(240-posy)*320)*3)];
return dtemp;
/*int index;
index = posy*image->sizex + posx;
return image->data[index*3];*/
}

unsigned char getG(unsigned char *imagedata,int posx, int posy){


unsigned char dtemp;
dtemp=imagedata[((posx+(240-posy)*320)*3)+1];
return dtemp;
/*
int index;
index = posy*image->sizex + posx;
return image->data[index*3+1];*/
}

unsigned char getB(unsigned char *imagedata,int posx, int posy){


unsigned char dtemp;
dtemp=imagedata[((posx+(240-posy)*320)*3)+2];
return dtemp;
/*
152

int index;
index = posy*image->sizex + posx;
return image->data[index*3+2];*/
}

void setR(Image *image,int posx,int posy,int cl){


image->data[((posx+(image->sizey-posy)*image->sizex)*3)]=cl;
/*
int index;
index = posy*image->sizex + posx;
image->data[index*3] = cl;*/
}
void setG(Image *image,int posx,int posy,int cl){
image->data[((posx+(image->sizey-posy)*image->sizex)*3)+1]=cl;
/*
int index;
index = posy*image->sizex + posx;
image->data[index*3+1] = cl;*/

void setB(Image *image,int posx,int posy,int cl){


image->data[((posx+(image->sizey-posy)*image->sizex)*3)+2]=cl;
/*
int index;
index = posy*image->sizex + posx;
image->data[index*3+2] = cl;*/

int loadImageTemplate(int sizex,int sizey,int posx,int posy,TempImage *t_image){


long size;
//unsigned long i;
t_image->sizex=sizex;
t_image->sizey=sizey;
t_image->posx=posx;
t_image->posy=posy;
size=t_image->sizex * t_image->sizey * 3;

t_image->data=(unsigned char *)malloc(size);


if(t_image->data==NULL){
return 0;
}
return 1;

//for(i=0;i<size;i++){
// t_image->data[i]=0;
//}
}
153

void openImageTemplate(int x1,int y1,int x2,int y2,Image *image,int id,struct TempImage


**t_image){

long size;
int tinggi,lebar;

*t_image=(TempImage *)malloc(sizeof(TempImage));
(*t_image)->sizex=x2-x1;
(*t_image)->sizey=y2-y1;
(*t_image)->posx=x1;
(*t_image)->posy=y1;
printf("posx =%d posy = %d\n",(*t_image)->posx,(*t_image)->posy);
size=(*t_image)->sizex * (*t_image)->sizey *3;

(*t_image)->data=(unsigned char *) malloc(size);


if((*t_image)->data==NULL){
exit(1);
}
tinggi=(*t_image)->sizey;
lebar=(*t_image)->sizex;

for(int i=0;i<tinggi;i++){
for(int j=0;j<lebar;j++){

(*t_image)->data[((i*lebar)+j)*3]=getR(image-
>data,x1+j,(tinggi-i)+y1);
(*t_image)->data[((i*lebar)+j)*3+1]=getG(image-
>data,x1+j,(tinggi-i)+y1);
(*t_image)->data[((i*lebar)+j)*3+2]=getB(image-
>data,x1+j,(tinggi-i)+y1);
}
}
glGenTextures(id,&texture[id-1]);
glBindTexture(GL_TEXTURE_2D,texture[id-1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LI
NEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LIN
EAR);
glTexImage2D(GL_TEXTURE_2D,0,3,(*t_image)->sizex,(*t_image)-
>sizey,0,GL_RGB,GL_UNSIGNED_BYTE,(*t_image)->data);

printf("copy template sukses....!!!\n");


}

void beeDrawPixeldw(int startx,int starty,struct TempImage **tImage){


unsigned int i,k;
unsigned char *data_baris;
data_baris=(unsigned char *) malloc((*tImage)->sizex*3);
154

for(i=0;i<(*tImage)->sizey;i++){

for(k=0;k<(*tImage)->sizex*3;k++){
data_baris[k]=(*tImage)->data[k+(i*(*tImage)-
>sizex*3)];
}

glRasterPos2i(startx,starty+i);
glDrawPixels((*tImage)-
>sizex,1,GL_RGB,GL_UNSIGNED_BYTE,data_baris);

}
}

void openPointTemplate(PointTemplate **ptemp,Image *image,int posx,int posy){


int a;
*ptemp=(PointTemplate *) malloc(sizeof(PointTemplate));
(*ptemp)->posx=posx;
(*ptemp)->posy=posy;
a=0;
for(int i=-2;i<=2;i++){
for(int j=-2;j<=2;j++){
(*ptemp)->data[a]=(getR(image-
>data,posx+j,posy+i)+getG(image->data,posx+j,posy+i)+getB(image-
>data,posx+j,posy+i))/3;
// printf("%d \\",(*ptemp)->data[a]);
a++;
}
}
//printf("\n");
}

3. Program perbaikan citra


/*Dip.h*/
#include <math.h>

unsigned int dataTemp[256];

int dataPos[35][3];
int histFlag=0;
int flag_viewTracking=0;
double coredata=0.8f;

void histogramfn(Image *image,unsigned int data[256],int mode){


long p;
long size;
size=image->sizex*image->sizey*3;
155

for(int i=0;i<256;i++){
data[i]=0;
}
switch(mode){
case 1:
for(p=0;p<size;p+=3){
data[image->data[p]]+=1;
}
break;
case 2:
for(p=0;p<size;p+=3){
data[image->data[p+1]]+=1;
}
break;
case 3:
for(p=0;p<size;p+=3){
data[image->data[p+2]]+=1;
}
break;
case 4:
for(p=0;p<size;p+=3){
data[(image->data[p]+image1->data[p+1]+image1-
>data[p+2])/3]+=1;
}
break;
default:
break;
}
}

void customHistogram(Image *image,int x1,int y1, int x2,int y2,unsigned int data[256]){
unsigned char dataPix;

for(int i=0;i<256;i++){
data[i]=0;
}

for(int i=y1;i<y2;i++){
for(int j=x1;j<x2;j++){
data[(getR(image->data,i,j)+getG(image-
>data,i,j)+getB(image->data,i,j))/3]+=1;
dataPix=(getR(image->data,i,j)+getG(image-
>data,i,j)+getB(image->data,i,j))/3;
//printf(";%d",dataPix);
}
//printf("\n");
}
//printf("waduhhh....\n");
}
156

void checkIntensity(TempImage *tImage,Image *image,int startx,int starty,char


*fname,int ssd,float corelation){
unsigned int i,j;
unsigned char r,g,b,gs;
FILE *pf;

pf=fopen(fname,"wa");
fprintf(pf,"*******Test Sum of Squared Differences
calculation************* \n");
fprintf(pf,"Template Width = %d\n",tImage->sizex);
fprintf(pf,"Template Heigh = %d\n",tImage->sizey);
fprintf(pf,"Image Width = %d\n",image->sizex);
fprintf(pf,"Image Heigh = %d\n",image->sizey);
fprintf(pf,"Match Position on Image Data : \n");
fprintf(pf,"Pos X = %d\n",startx);
fprintf(pf,"Pos Y = %d\n",starty);
fprintf(pf,"Sum of Squared Differences = %d\n",ssd);
fprintf(pf,"Correlation : %f\n",corelation);
fprintf(pf,"Data : \n");
for(i=0;i<tImage->sizey;i++){
for(j=0;j<tImage->sizex;j++){
r=tImage->data[(i*tImage->sizex+j)*3];
g=tImage->data[(i*tImage->sizex+j)*3+1];
b=tImage->data[(i*tImage->sizex+j)*3+2];
gs=(r+g+b)/3;
r=getR(image->data,startx+j,starty+(tImage->sizey-i));
g=getG(image->data,startx+j,starty+(tImage->sizey-i));
b=getB(image->data,startx+j,starty+(tImage->sizey-i));
fprintf(pf,"%d;%d\n",(r+g+b)/3,gs);
}
//fprintf(pf,"\n");
}
fclose(pf);
printf("saving %s ok..!!!\n",fname);

void findSSD(TempImage *tImage,Image *image,int data[4]){

unsigned int i,j,k,l;


unsigned nr,ng,nb,ngs;
unsigned mr,mg,mb,mgs;
int ssd=0;
//flag_viewTracking=0;
for(i=0;i<image->sizey-tImage->sizey;i++){
for(j=0;j<image->sizex-tImage->sizex;j++){
ssd=0;
for(k=0;k<tImage->sizey;k++){
for(l=0;l<tImage->sizex;l++){
157

nr=tImage->data[(k*tImage-
>sizex+l)*3];
ng=tImage->data[(k*tImage-
>sizex+l)*3+1];
nb=tImage->data[(k*tImage-
>sizex+l)*3+2];
ngs=(nr+ng+nb)/3;
mr=getR(image-
>data,j+l,i+(tImage->sizey-k));
mg=getG(image-
>data,j+l,i+(tImage->sizey-k));
mb=getB(image-
>data,j+l,i+(tImage->sizey-k));
mgs=(mr+mg+mb)/3;
ssd+=(mgs-ngs)*(mgs-ngs);

}//loop l
}//loop k
if(ssd<1){
data[0]=j;data[1]=i;
data[2]=tImage->sizex;data[3]=tImage->sizey;
printf("posx = %d posy = %d ssd = %d \n",j,i,ssd);
printf("Template width = %d \n",data[2]);
printf("Template heigh = %d \n",data[3]);
printf("titik sudah ditemukan\n");

checkIntensity(tImage,image,data[0],data[1],"ssd.txt",ssd,0.00);
}

}//loop j
}//loop i
printf("search finished.....!!!\n");
flag_viewTracking=1;
}
void findPointCorrelation(int pointTemplate[32][3],Image *image,int data[35][3],float
cparam){
FILE *fp;
int i,j,k,l;
unsigned int tgs,ir,ig,ib,igs;
float p,q,r,s;
int waktu;
int waktu_saat_ini;
waktu=0;
int ssd=0;
float coreVal,t,coremak;
waktu=glutGet(GLUT_ELAPSED_TIME);
//printf("test 123\n");
fp=fopen("point.txt","wa");
158

for(k=0;k<35;k++){
for(i=-2;i<=2;i++){
for(j=-2;j<=2;j++){
coreVal=0;coremak=0;ssd=0;
p=0;q=0;r=0;s=0;t=0;

tgs=pointTemplate[k][2];
//printf("xt=%d yt=%d
\n",pointTemplate[k][0],pointTemplate[k][1]);
ir=getR(image-
>data,pointTemplate[k][0]+j,pointTemplate[k][1]+i);
ig=getG(image-
>data,pointTemplate[k][0]+j,pointTemplate[k][1]+i);
ib=getB(image-
>data,pointTemplate[k][0]+j,pointTemplate[k][1]+i);
igs=int(ir+ig+ib)/3;
ssd=(igs-tgs)*(igs-tgs);
//printf("T=%d I=%d\n",tgs,igs);
p=float(igs*tgs);
q=float(igs*igs);
r=float(tgs*tgs);
//ssd+=int ((qgs-pgs)*(qgs-pgs));

s= q*r ;
t=sqrt(s);
coreVal=float (p/sqrt(r*q));
//printf("p=%.3f ,q=%.3f ,r=%.3f\n",p,q,r);
if(ssd<=1){
coremak=coreVal;

data[k][0]=pointTemplate[k][0]+j;

data[k][1]=pointTemplate[k][1]+i;
printf("x = %d y = %d
Corelasi = %d\n",data[k][0],data[k][1],ssd);

//printf("p= %.2f q= %.2f r= %.2f


s= %.2f t = %.2lf correlation = %.4lf\n",p,q,r,s,t,coreVal);
flag_viewTracking=1;

//checkIntensity(tImage,image,data[0],data[1],"ssd.txt",ssd,coreVal);

waktu_saat_ini=glutGet(GLUT_ELAPSED_TIME);
waktu=waktu_saat_ini-waktu;
//printf("waktu tempuh pencarian :
%d ms\n",waktu);
//printf("Finish...!!\n");
//return;
}else{
data[k][0]=data[k][0];
159

data[k][1]=data[k][1];
}
}//loop j
}//loop i
}//loop k

for(l=0;l<32;l++){
pointTemplate[l][0]=data[l][0];
pointTemplate[l][1]=data[l][1];
fprintf(fp,"%d;%d\n",pointTemplate[l][0],pointTemplate[l][1]);
//pointTemplate[l][2]=data[l][2];
}
fclose(fp);
printf("Pencarian berakhir....!!!\n");

float pointCorrelation(PointTemplate *ptemp,Image *image,int iposx,int iposy){


int a;
int gs,ts;
float mkalin,mkuadrat,nkuadrat,penyebut;
float hasil=0.0f;
a=0;mkalin=0;mkuadrat=0;nkuadrat=0;penyebut=0;
for(int i=-2;i<=2;i++){
for(int j=-2;j<=2;j++){
gs=(getR(image->data,iposx+j,iposy+i)+getG(image-
>data,iposx+j,iposy+i)+getB(image->data,iposx+j,iposy+i))/3;
ts=ptemp->data[a];
mkalin+=float(gs*ts);
mkuadrat+=float(gs*gs);
nkuadrat+=float(ts*ts);
a++;
}
}
penyebut=mkuadrat*nkuadrat;
//printf("mkalin = %.3f mkuadrat = %.3f nkuadrat = %.3fd akar :
%.3f\n",mkalin,mkuadrat,nkuadrat,sqrt(penyebut));
hasil=mkalin/float(sqrt(penyebut));
return hasil;
}

float VpointCorrelation(PointTemplate *ptemp,unsigned char *video_disp,int iposx,int


iposy){
int a;
int gs,ts;
float mkalin,mkuadrat,nkuadrat,penyebut;
float hasil=0.0f;
a=0;mkalin=0;mkuadrat=0;nkuadrat=0;penyebut=0;
for(int i=-2;i<=2;i++){
for(int j=-2;j<=2;j++){
160

gs=(getR(video_disp,iposx+j,iposy+i)+getG(video_disp,iposx+j,iposy+i)+getB
(video_disp,iposx+j,iposy+i))/3;
ts=ptemp->data[a];
mkalin+=float(gs*ts);
mkuadrat+=float(gs*gs);
nkuadrat+=float(ts*ts);
a++;
}
}
penyebut=mkuadrat*nkuadrat;
//printf("mkalin = %.3f mkuadrat = %.3f nkuadrat = %.3fd akar :
%.3f\n",mkalin,mkuadrat,nkuadrat,sqrt(penyebut));
hasil=mkalin/float(sqrt(penyebut));
return hasil;
}

void trackPoint(PointTemplate *ptemp,Image *image,PointTemplate *ptempdst,int


data[3],float cparam){
float nilai=0;
float cmax=0;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
nilai=pointCorrelation(ptemp,image,ptempdst-
>posx+j,ptempdst->posy+i);
if(nilai>=cmax){
cmax=nilai;
ptempdst->posx=ptemp->posx+j;
ptempdst->posy=ptemp->posy+i;
}
}
}
flag_viewTracking=1;
}

void VtrackPoint(PointTemplate *ptemp,unsigned char *video_disp,PointTemplate


*ptempdst,float cparam){
float nilai=0;
float cmax=0;
for(int i=-2;i<=2;i++){
for(int j=-2;j<=2;j++){
nilai=VpointCorrelation(ptemp,video_disp,ptempdst-
>posx+j,ptempdst->posy+i);
if(nilai>=cparam){
cmax=nilai;
ptempdst->posx=ptemp->posx+j;
ptempdst->posy=ptemp->posy+i;

}
}
161

}
flag_viewTracking=1;
}

void findCorrelation(TempImage *tImage,Image *image,int data[4],float cparam){


unsigned int i,j,k,l;
unsigned int pr,pg,pb,pgs;
unsigned qr,qg,qb,qgs;
float p,q,r,s;
int waktu;
int waktu_saat_ini;
waktu=0;
int ssd=0;
double coreVal,t;
waktu=glutGet(GLUT_ELAPSED_TIME);
for(i=0;i<image->sizey-tImage->sizey;i++){
for(j=0;j<image->sizex-tImage->sizex;j++){
p=0;q=0;r=0;s=0;t=0;
ssd=0;
coreVal=0.0;
for(k=0;k<tImage->sizey;k++){
for(l=0;l<tImage->sizex;l++){

pr=tImage->data[(k*tImage-
>sizex+l)*3];
pg=tImage->data[(k*tImage-
>sizex+l)*3+1];
pb=tImage->data[(k*tImage-
>sizex+l)*3+2];
pgs=(pr+pg+pb)/3;
qr=getR(image-
>data,j+l,i+(tImage->sizey-k));
qg=getG(image-
>data,j+l,i+(tImage->sizey-k));
qb=getB(image-
>data,j+l,i+(tImage->sizey-k));
qgs=(qr+qg+qb)/3;

p+=float(qgs*pgs);
q+=float(qgs*qgs);
r+=float(pgs*pgs);
ssd+=int ((qgs-pgs)*(qgs-pgs));
}//loop l
}//loop k
s= q*r ;
t=sqrt(s);
coreVal=double(p/t);
if(coreVal>=cparam){
data[0]=j;data[1]=i;
data[2]=tImage->sizex;
162

data[3]=tImage->sizey;
printf("nilai ssd = %d x = %d y = %d
Correlation = %.4lf\n",ssd,j,i,coreVal);
//printf("p= %.2f q= %.2f r= %.2f s= %.2f t =
%.2lf correlation = %.4lf\n",p,q,r,s,t,coreVal);
flag_viewTracking=1;

//checkIntensity(tImage,image,data[0],data[1],"ssd.txt",ssd,coreVal);

waktu_saat_ini=glutGet(GLUT_ELAPSED_TIME);
waktu=waktu_saat_ini-waktu;
printf("waktu tempuh pencarian : %d
ms\n",waktu);
printf("Finish...!!\n");
//ktu=0;
return;

}
}//loop j
}//loop i
printf("Penchariean berakhir....!!!\n");

}
void videoTracking(TempImage *tImage,unsigned char *displ_video,int startx,int
starty,int data[4],float cparam){
int i,j;
unsigned int k,l;
int pr,pg,pb,pgs;
unsigned qr,qg,qb,qgs;
float p,q,r,s;
int waktu;
int waktu_saat_ini;
waktu=0;
int ssd=0;
double coreVal,t;
waktu=glutGet(GLUT_ELAPSED_TIME);
//coredata=0.99f;
//data[0]=tImage->posx;
//data[1]=tImage->posy;

for(i=-10;i<=10;i++){
for(j=-10;j<=10;j++){

p=0;q=0;r=0;s=0;t=0;
ssd=0;
coreVal=0.0;
for(k=0;k<tImage->sizey;k++){
for(l=0;l<tImage->sizex;l++){
163

pr=tImage->data[(k*tImage-
>sizex+l)*3];
pg=tImage->data[(k*tImage-
>sizex+l)*3+1];
pb=tImage->data[(k*tImage-
>sizex+l)*3+2];
pgs=(pr+pg+pb)/3;

qr=getR(displ_video,startx+j+l,starty+i+(tImage->sizey-k));

qg=getG(displ_video,startx+j+l,starty+i+(tImage->sizey-k));

qb=getB(displ_video,startx+j+l,starty+i+(tImage->sizey-k));
qgs=(qr+qg+qb)/3;

p+=float(qgs*pgs);
q+=float(qgs*qgs);
r+=float(pgs*pgs);
ssd+=int ((qgs-pgs)*(qgs-pgs));
}//loop l
}//loop k
s= q*r ;
t=sqrt(s);
coreVal=double(p/t);

if(coreVal>=cparam){
coredata=coreVal;
data[0]=j+startx;data[1]=i+starty;
data[2]=tImage->sizex;
data[3]=tImage->sizey;
startx=data[0];starty=data[1];
//tImage->posx=data[0];
//tImage->posy=data[1];

//printf("p= %.2f q= %.2f r= %.2f s= %.2f t =


%.2lf correlation = %.4lf\n",p,q,r,s,t,coreVal);
//flag_viewTracking=1;

//checkIntensity(tImage,image,data[0],data[1],"ssd.txt",ssd,coreVal);

waktu_saat_ini=glutGet(GLUT_ELAPSED_TIME);
waktu=waktu_saat_ini-waktu;
//printf("posisi Template x = %d y =
%d\n",dataPos[0],dataPos[1]);
//printf("waktu tempuh pencarian : %d
ms\n",waktu);

}//loop j
164

}//loop i
flag_viewTracking=1;
printf("nilai ssd = %d Correlation = %.4lf\n",ssd,coreVal);

//printf("Penchariean berakhir....!!!\n");

void hist_equal(Image *image,unsigned int data[256] ){

void drawCurve(int posx,int posy,unsigned int data[256],int scala,int cl){


switch(cl){
case 1:
glColor3f(1.0f,0.0f,0.0f);
break;
case 2:
glColor3f(0.0f,1.0f,0.0f);
break;
case 3:

glColor3f(0.0f,0.0f,1.0f);
break;
case 4:
glColor3f(0.0f,0.0f,0.0f);
break;
}
glBegin(GL_LINES);
for(int i=0;i<255;i++){
glVertex2f((GLfloat)posx+i,(GLfloat)posy);

glVertex2f((GLfloat)posx+i,(GLfloat)posy+(GLfloat)(data[i]/scala));
}
glEnd();

void greyScalefn(){
unsigned long i;
unsigned int temp;
for(i=0;i<image1->sizex*image1->sizey*3;i+=3){
temp=(image1->data[i]+image1->data[i+1]+image1->data[i+2])/3;
image2->data[i]=temp;
image2->data[i+1]=temp;
image2->data[i+2]=temp;
}
165

//loadTexture(2,image2);
}
void medianFilterfn(){
int a;
unsigned int tempR[9];
unsigned int tempG[9];
unsigned int tempB[9];

for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
a=0;
for(int k=-1;k<=1;k++){
for(int l=-1;l<=1;l++){
tempR[a]=getR(image1-
>data,j+l,i+k);
tempG[a]=getG(image1-
>data,j+l,i+k);
tempB[a]=getB(image1-
>data,j+l,i+k);
a++;
}//loop l
}//loop k

//find mean
for(int k=0;k<8;k++){
for(int l=k+1;l<9;l++){

if(tempR[k]<tempR[l]){
a=tempR[k];
tempR[k]=tempR[l];
tempR[l]=a;
}
if(tempG[k]<tempG[l]){
a=tempG[k];
tempG[k]=tempG[l];
tempG[l]=a;
}

if(tempB[k]<tempB[l]){
a=tempB[k];
tempB[k]=tempB[l];
tempB[l]=a;
}

}//loop l
}//loop k
setR(image2,j,i,tempR[4]);
setG(image2,j,i,tempG[4]);
setB(image2,j,i,tempB[4]);
166

}//lopp j
}//lopp i

//loadTexture(2,image2);
}
void meanFilterfn(){
int a,r,g,b;
unsigned int tempR[9];
unsigned int tempG[9];
unsigned int tempB[9];

for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
a=0;
for(int k=-1;k<=1;k++){
for(int l=-1;l<=1;l++){
tempR[a]=getR(image1-
>data,j+l,i+k);
tempG[a]=getG(image1-
>data,j+l,i+k);
tempB[a]=getB(image1-
>data,j+l,i+k);
a++;
}
}
r=0;g=0;b=0;
for(int k=0;k<9;k++){
r=r+tempR[k];
g=g+tempG[k];
b=b+tempB[k];
}
setR(image2,j,i,r/9);
setG(image2,j,i,g/9);
setB(image2,j,i,b/9);
}
}
//loadTexture(2,image2);
}

void gaussianFilterfn(){
int a;
unsigned int tempR[9];
unsigned int tempG[9];
unsigned int tempB[9];
unsigned int temp_r7[7][7];
unsigned int temp_g7[7][7];
unsigned int temp_b7[7][7];
unsigned int temporer,temp;

for(int b=0;b<9;b++){
167

tempR[b]=0;
tempG[b]=0;
tempB[0]=0;
}

for(int b=0;b<7;b++){
for(int c=0;c<7;c++){
temp_r7[b][c]=0;
temp_g7[b][c]=0;
temp_b7[b][c]=0;
}
}

for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
a=0;
//printf ("stage 1");

for(int k=-3;k<=3;k++){
for(int l=-3;l<=3;l++){
temp_r7[l+3][k+3]=getR(image1-
>data,j+l,i+k);
temp_g7[l+3][k+3]=getG(image1-
>data,j+l,i+k);
temp_b7[l+3][k+3]=getB(image1-
>data,j+l,i+k);
a++;
}
}
//printf("stage 1");

tempR[0]=temp_r7[0][0]+temp_r7[0][6]+temp_r7[6][0]+temp_r7[6][6];

tempR[1]=temp_r7[1][0]+temp_r7[5][0]+temp_r7[1][6]+temp_r7[5][6]+temp_r7[0][1]+te
mp_r7[0][5]+
temp_r7[6][1]+temp_r7[6][5];

tempR[2]=temp_r7[2][0]+temp_r7[4][0]+temp_r7[2][6]+temp_r7[4][6]+temp_r7[0][2]+te
mp_r7[0][4]+
temp_r7[6][2]+temp_r7[6][4];

tempR[3]=temp_r7[3][0]+temp_r7[3][6]+temp_r7[0][3]+temp_r7[6][3];

tempR[4]=temp_r7[1][1]+temp_r7[5][1]+temp_r7[1][5]+temp_r7[5][5];

tempR[5]=temp_r7[2][1]+temp_r7[4][1]+temp_r7[2][5]+temp_r7[4][5]+temp_r7[1][2]+te
mp_r7[1][4]+
temp_r7[5][2]+temp_r7[5][4];
168

tempR[6]=temp_r7[3][1]+temp_r7[3][5]+temp_r7[1][3]+temp_r7[5][3];

tempR[7]=temp_r7[2][2]+temp_r7[4][2]+temp_r7[2][4]+temp_r7[4][4];

tempR[8]=temp_r7[3][2]+temp_r7[3][4]+temp_r7[2][3]+temp_r7[4][3];

tempR[9]=temp_r7[3][3];

temporer=tempR[0]+4*tempR[1]+7*tempR[2]+10*tempR[3]+12*tempR[4]+26*tempR[5]
+33*tempR[6]+55*tempR[7]+71*tempR[8]+91*tempR[9];
temp=(unsigned char) (temporer/1115);
setR(image2,j,i,temp);

tempG[0]=temp_g7[0][0]+temp_g7[0][6]+temp_g7[6][0]+temp_g7[6][6];

tempG[1]=temp_g7[1][0]+temp_g7[5][0]+temp_g7[1][6]+temp_g7[5][6]+temp_g7[0][1]+
temp_g7[0][5]+
temp_g7[6][1]+temp_g7[6][5];

tempG[2]=temp_g7[2][0]+temp_g7[4][0]+temp_g7[2][6]+temp_g7[4][6]+temp_g7[0][2]+
temp_g7[0][4]+
temp_g7[6][2]+temp_g7[6][4];

tempG[3]=temp_g7[3][0]+temp_g7[3][6]+temp_g7[0][3]+temp_g7[6][3];

tempG[4]=temp_g7[1][1]+temp_g7[5][1]+temp_g7[1][5]+temp_g7[5][5];

tempG[5]=temp_g7[2][1]+temp_g7[4][1]+temp_g7[2][5]+temp_g7[4][5]+temp_g7[1][2]+
temp_g7[1][4]+
temp_g7[5][2]+temp_g7[5][4];

tempG[6]=temp_g7[3][1]+temp_g7[3][5]+temp_g7[1][3]+temp_g7[5][3];

tempG[7]=temp_g7[2][2]+temp_g7[4][2]+temp_g7[2][4]+temp_g7[4][4];

tempG[8]=temp_g7[3][2]+temp_g7[3][4]+temp_g7[2][3]+temp_g7[4][3];
tempG[9]=temp_g7[3][3];

temporer=tempG[0]+4*tempG[1]+7*tempG[2]+10*tempG[3]+12*tempG[4]+26*tempG[5
]+33*tempG[6]+55*tempG[7]+71*tempG[8]+91*tempG[9];

temp=(unsigned char) (temporer/1115);

setG(image2,j,i,temp);
169

tempB[0]=temp_b7[0][0]+temp_b7[0][6]+temp_b7[6][0]+temp_b7[6][6];

tempB[1]=temp_b7[1][0]+temp_b7[5][0]+temp_b7[1][6]+temp_b7[5][6]+temp_b7[0][1]+
temp_b7[0][5]+
temp_b7[6][1]+temp_b7[6][5];

tempB[2]=temp_b7[2][0]+temp_b7[4][0]+temp_b7[2][6]+temp_b7[4][6]+temp_b7[0][2]+
temp_b7[0][4]+
temp_b7[6][2]+temp_b7[6][4];

tempB[3]=temp_b7[3][0]+temp_b7[3][6]+temp_b7[0][3]+temp_b7[6][3];

tempB[4]=temp_b7[1][1]+temp_b7[5][1]+temp_b7[1][5]+temp_b7[5][5];

tempB[5]=temp_b7[2][1]+temp_b7[4][1]+temp_b7[2][5]+temp_b7[4][5]+temp_b7[1][2]+
temp_b7[1][4]+
temp_b7[5][2]+temp_b7[5][4];

tempB[6]=temp_b7[3][1]+temp_b7[3][5]+temp_b7[1][3]+temp_b7[5][3];

tempB[7]=temp_b7[2][2]+temp_b7[4][2]+temp_b7[2][4]+temp_b7[4][4];

tempB[8]=temp_b7[3][2]+temp_b7[3][4]+temp_b7[2][3]+temp_b7[4][3];

tempB[9]=temp_b7[3][3];

temporer=tempB[0]+4*tempB[1]+7*tempB[2]+10*tempB[3]+12*tempB[4]+26*tempB[5]
+33*tempB[6]+55*tempB[7]+71*tempB[8]+91*tempB[9];
temp=(unsigned char) (temporer/1115);

setB(image2,j,i,temp);
}
}
//loadTexture(2,image2);
}

void tresholdfn(){
int a;
for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
a=(getR(image1->data,j,i)+getG(image1-
>data,j,i)+getB(image1->data,j,i))/3;
if(a<=100){
setR(image2,j,i,0);
setG(image2,j,i,0);
setB(image2,j,i,0);}
else if(a<=160){
setR(image2,j,i,0);
170

setG(image2,j,i,0);
setB(image2,j,i,0);
}
else{
setR(image2,j,i,255);
setG(image2,j,i,255);
setB(image2,j,i,255);
}

}//loop j
}//loop j
//loadTexture(2,image2);
}

4.Program inisialisasi video4linux


/*bcapv4l.h*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<sys/mman.h>

#include<linux/videodev.h>

//definisi fungsi video for linux

#define DEF_DEVICE_NAME "/dev/video0"


#define MAX_NO_CHANNEL 10

#define CAPTURE_IMAGE_WIDTH 640


#define CAPTURE_IMAGE_HEIGHT 480

#define RGB 3
#define COMPOSITE1 0
#define COMPOSITE2 1
#define S_VIDEO 2

#define DOWN_SAMPLING_RATE 2

#define IMAGE_WIDTH_DS
CAPTURE_IMAGE_WIDTH/DOWN_SAMPLING_RATE
#define IMAGE_HEIGHT_DS
CAPTURE_IMAGE_HEIGHT/DOWN_SAMPLING_RATE
171

//fungsi-fungsi prototype

int CaptV4LOpen(char *device_name);


int CaptV4LGetDeviceCapability(int fd,struct video_capability *vcap);
void CaptV4LDisplayDeviceCapability(struct video_capability vcap);
int CaptV4LGetChannelInfo(int fd, struct video_channel vch[MAX_NO_CHANNEL],int
no_channel);

void CaptV4LDisplayChannelInfo(struct video_channel vch[MAX_NO_CHANNEL],int


no_channel);
int CaptV4LGetPictureInfo(int fd,struct video_picture *vp);
int CaptV4LSetPicture(int fd,struct video_picture *vp);
void CaptV4LDisplayPictureInfo(struct video_picture vp);
int CaptV4LGetMemoryMapInfo(int fd,struct video_mbuf *vm);
void CaptV4LDisplayMemoryMapInfo(struct video_mbuf vm);

int CaptV4LSelectChannel(int fd,struct video_channel vch[MAX_NO_CHANNEL],int


channel_no);
int CaptV4LMemoryMapping(int fd,struct video_mbuf vm);

int CaptV4LSimpleCapture(int fd, struct video_mmap *vmap);


int CaptV4LDoubleBufferingInitCapture(int fd,struct video_mmap *vmap);
int CaptV4LDoubleBufferingCaptureWait(int fd, struct video_mmap *vmap);
int CaptV4LDoubleBufferingCaptureNextFrame(int fd, struct video_mmap *vmap);

unsigned char *CaptV4LSetImage(struct video_mmap vmap, struct video_mbuf vm);


void CaptV4LSetImageDownSamplingForOpenGL(struct video_mmap vmap, struct
video_mbuf vm, int down_sampling_rate,unsigned char *image,unsigned char
*disp_image);

/*bcapv4l.cxx*/

#include "bcapv4l.h"

static unsigned char *frame_buf;

int CaptV4LOpen(char *device_name){


int fd;
if((fd=open(device_name,O_RDWR))==-1){
return -1;
}
return fd;
}
int CaptV4LGetDeviceCapability(int fd,struct video_capability *vcap){
if(ioctl(fd,VIDIOCGCAP,vcap)==-1){
return -1;
}
return 0;
}
172

void CaptV4LDisplayDeviceCapability(struct video_capability vcap){

fprintf(stdout,"**** Device Information *****\n");


fprintf(stdout,"Device Name : %s.\n",vcap.name);

fprintf(stdout,"Type of Device :\n");


if(vcap.type & VID_TYPE_CAPTURE){
fprintf(stdout,"Capture is OK. \n");
}else{
fprintf(stderr,"This Device may NOT be used for capture. Are you
sure about it ?\n");
}
if(vcap.type & VID_TYPE_TUNER){
fprintf(stdout,"Tuner exist. \n");
}
if(vcap.type & VID_TYPE_TELETEXT){
fprintf(stdout,"Teletext can be used.\n");
}
if(vcap.type & VID_TYPE_OVERLAY){
fprintf(stdout,"Overlay is OK.\n");
}
if(vcap.type & VID_TYPE_CHROMAKEY){
fprintf(stdout,"Overlay by chromakey is OK.\n");
}
if(vcap.type & VID_TYPE_CLIPPING){
fprintf(stdout,"Clipping overlay is OK.\n");
}
if(vcap.type & VID_TYPE_FRAMERAM){
fprintf(stdout,"Overlay for frame buffer is OK.\n");
}
if(vcap.type & VID_TYPE_SCALES){
fprintf(stdout,"Scaling by hardware can be used.\n");
}
if(vcap.type & VID_TYPE_MONOCHROME){
fprintf(stdout,"Capture of monochrome image is OK.\n");
}
if(vcap.type & VID_TYPE_SUBCAPTURE){
fprintf(stdout,"Capture of a part of image is OK.\n");
}
fprintf(stdout,"\n");

fprintf(stdout,"Number of channels : %d\n",vcap.channels);


fprintf(stdout,"Number of audio device : %d\n",vcap.audios);

if(vcap.channels > MAX_NO_CHANNEL){


fprintf(stderr,"It seem that many channels exist in this device :
%d\n",vcap.channels);
}

fprintf(stdout,"Maximum width of image : %d\n",vcap.maxwidth);


173

fprintf(stdout,"Maximum height of image : %d\n",vcap.maxheight);


fprintf(stdout,"Minimum width of image : %d\n",vcap.minwidth);
fprintf(stdout,"Minimum height of image : %d\n",vcap.minheight);
fprintf(stdout,"\n");
}

int CaptV4LGetChannelInfo(int fd, struct video_channel vch[MAX_NO_CHANNEL],int


no_channel){
int i;

for(i=0;i<no_channel;i++){
vch[i].channel = i;
if( ioctl(fd, VIDIOCGCHAN, &vch[i])==-1){
return -1;
}
}
return 0;
}

void CaptV4LDisplayChannelInfo(struct video_channel vch[MAX_NO_CHANNEL],int


no_channel){

int i;
for(i=0;i<no_channel;i++){
fprintf(stdout,"**** Channel number : %d ****\n",vch[i].channel);
fprintf(stdout,"Channel Name : %s\n",vch[i].name);
if(vch[i].flags & VIDEO_VC_TUNER){
fprintf(stdout,"This channel has a tuner.\n");
}
if(vch[i].flags & VIDEO_VC_AUDIO){
fprintf(stdout,"This channel has a audio.\n");
}
if(vch[i].type & VIDEO_TYPE_TV){
fprintf(stdout,"Channel type is TV.\n");
}
if(vch[i].type & VIDEO_TYPE_CAMERA){
fprintf(stdout,"Channel type is camera.\n");
}
if(vch[i].norm & VIDEO_MODE_NTSC){
fprintf(stdout,"Video mode is NTSC");
}
if(vch[i].norm & VIDEO_MODE_PAL){
fprintf(stdout,"Video mode is PAL");
}
if(vch[i].norm & VIDEO_MODE_SECAM){
fprintf(stdout,"Video mode is SECAM");
}

}
fprintf(stdout,"\n");
174

}
int CaptV4LGetPictureInfo(int fd,struct video_picture *vp){

if(ioctl(fd,VIDIOCGPICT,vp)==-1){
return -1;
}
return 0;
}

int CaptV4LSetPicture(int fd,struct video_picture *vp){


if(ioctl(fd,VIDIOCSPICT,vp)==-1){
return -1;
}
return 0;
}

void CaptV4LDisplayPictureInfo(struct video_picture vp){


fprintf(stdout,"**** Picture information ***** \n");
fprintf(stdout,"Brightness : %d\n",vp.brightness);
fprintf(stdout,"Hue : %d\n",vp.hue);
fprintf(stdout,"Color : %d\n",vp.colour);
fprintf(stdout,"Contrast : %d\n",vp.contrast);
fprintf(stdout,"Whitness : %d\n",vp.whiteness);
fprintf(stdout,"Depth : %d\n",vp.depth);
switch(vp.palette){
case VIDEO_PALETTE_GREY:
fprintf(stdout,"Grey scale.\n");
break;
case VIDEO_PALETTE_RGB565:
fprintf(stdout,"16bit RGB.\n");
break;
case VIDEO_PALETTE_RGB24:
fprintf(stdout,"24bit RGB.\n");
break;
case VIDEO_PALETTE_RGB32:
fprintf(stdout,"32bit RGB.\n");
break;
case VIDEO_PALETTE_YUV422:
fprintf(stdout,"YUV422.\n");
break;
default:
break;

}
}

int CaptV4LGetMemoryMapInfo(int fd,struct video_mbuf *vm){


if(ioctl(fd,VIDIOCGMBUF,vm)==-1){
return -1;
}
175

return 0;
}

void CaptV4LDisplayMemoryMapInfo(struct video_mbuf vm){


int i;
fprintf(stdout,"Memory size: %d\n",vm.size);
fprintf(stdout,"Number of frames: %d\n",vm.frames);
for(i=0;i<vm.frames;i++){
fprintf(stdout,"Offset(Frame %d) : %d\n",i,vm.offsets[i]);
}
}

int CaptV4LSelectChannel(int fd,struct video_channel vch[MAX_NO_CHANNEL],int


channel_no){
vch[channel_no].norm=VIDEO_MODE_NTSC;
if(ioctl(fd,VIDIOCSCHAN,&vch[channel_no])==-1){
return -1;
}
return 0;
}

int CaptV4LMemoryMapping(int fd,struct video_mbuf vm){


if((frame_buf=(unsigned char *)mmap(0,(size_t)vm.size,PROT_READ |
PROT_WRITE,MAP_SHARED,fd,0))== MAP_FAILED){
return -1;
}
return 0;
}

int CaptV4LSimpleCapture(int fd,struct video_mmap *vmap){

//awal penangkapan gambar;


if(ioctl(fd,VIDIOCMCAPTURE,vmap)==-1){
return -1;
}
//waktu tunggu biar gambar tangkapannya gak jelek atau biar lengkap dalam
bbrp frame
if(ioctl(fd,VIDIOCSYNC,&(vmap->frame))==-1){
return -1;
}
}

int CaptV4LDoubleBufferingInitCapture(int fd,struct video_mmap *vmap){


//seting awal frame
vmap->frame=0;
if(ioctl(fd,VIDIOCMCAPTURE,vmap)==-1){
return -1;
}
vmap->frame=1;
if(ioctl(fd,VIDIOCMCAPTURE,vmap)==-1){
176

return -1;
}
//seting awal frame kembali ke 0
vmap->frame=0;
}
int CaptV4LDoubleBufferingCaptureWait(int fd, struct video_mmap *vmap){
if(ioctl(fd,VIDIOCSYNC,&(vmap->frame))==-1){
return -1;
}
return 0;
}
int CaptV4LDoubleBufferingCaptureNextFrame(int fd, struct video_mmap *vmap){
//ambil frame berikutnya dan simpan di buffer
if(ioctl(fd,VIDIOCMCAPTURE,vmap)==-1){
return -1;
}
if(vmap->frame==0){
vmap->frame=1;
}else{
vmap->frame=0;
}
return 0;
}

unsigned char *captV4LSetImage(struct video_mmap vmap,struct video_mbuf vm){


unsigned char tmpc;
unsigned char *pixel_pos;
int i;

//tdout,"Offset(Frame %d) : %d\n",i,vm.offsets[i]);


pixel_pos=frame_buf+vm.offsets[vmap.frame];
for(i=0;i<vmap.height*vmap.width;i++){
tmpc=pixel_pos[i];
pixel_pos[2]=pixel_pos[0];
pixel_pos[0]=tmpc;
pixel_pos +=RGB;
}
return frame_buf+vm.offsets[vmap.frame];
}
void CaptV4LSetImageDownSamplingForOpenGL(struct video_mmap vmap,struct
video_mbuf vm,int down_sampling_rate,unsigned char *image,unsigned char
*disp_image){
unsigned char *pixel_pos;
int i,j;
int dheight,dwidth;

dheight=vmap.height/down_sampling_rate;
dwidth=vmap.width/down_sampling_rate;
pixel_pos=frame_buf+vm.offsets[vmap.frame];
for(i=0;i<dheight;i++){
177

for(j=0;j<dwidth;j++){
//RGB Order
image[((dheight-1-i)*dwidth+(dwidth-
j))*RGB]=pixel_pos[2];
image[((dheight-1-i)*dwidth+(dwidth-
j))*RGB+1]=pixel_pos[1];
image[((dheight-1-i)*dwidth+(dwidth-
j))*RGB+2]=pixel_pos[0];
//BRG order
disp_image[((dheight-1-i)*dwidth+(dwidth-
j))*RGB]=pixel_pos[0];
disp_image[((dheight-1-i)*dwidth+(dwidth-
j))*RGB+1]=pixel_pos[1];
disp_image[((dheight-1-i)*dwidth+(dwidth-
j))*RGB+2]=pixel_pos[2];
pixel_pos += RGB*down_sampling_rate;
}//loop j
pixel_pos +=vmap.width*RGB*(down_sampling_rate-1);
}//loop i
}

4. Program penangkapan file dari perangkat video4linux


/*bshowv4l.h*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

#include<GL/gl.h>
#include<GL/glu.h>
#include<GL/glut.h>
#include<plib/pu.h>
#include "bcapv4l.h"
#include "bmp.h"
//#include "image.h"
//#include "dip.h"

#define DEFAULT_ZOOM_RATE 1
#define INIT_WINDOW_POS_X 200
#define INIT_WINDOW_POS_Y 200

int videoInitCaptureDevice(char *device_name,int channel_no);


void videoCaptureImage();
void videoDisplayImage();
void videoMouseCheck(int button,int status,int x, int y);
void videoChangeOrderImageRow(unsigned char *image,int iheight,int iwidth);
void videoSavePPMImage(unsigned char *image, int iheight, int iwidth, int frame_no,char
*image_prefix);
178

void saveBitmap(unsigned char *image,int iheight,int iwidth,int frame_no,char


*image_prefix);
void setsave_flag(int val);
void setMaksFrame(int num_frame);
int getsave_flag();
void setBrightness(int val);
void setContrast(int val);
void setColorb(int val);
void setHue(int val);
void setWhiteness(int val);
int getBrightness();
int getContrast();
int getColorb();
int getHue();
int getWhiteness();

/*bshowv4l.cxx*/
#include "bshowv4l.h"

//#include "bee_vproc_v4l.h"

#define PREFIX_IMAGE_FILE "video_image"

struct Image{
unsigned long sizex;
unsigned long sizey;
unsigned char *data;
};
typedef Image Image;

struct TempImage{
unsigned long sizex;
unsigned long sizey;
int posx;
int posy;
unsigned char *data;
};
typedef TempImage TempImage;

struct PointTemplate{
int posx;
int posy;
unsigned char data[25];
};
typedef PointTemplate PointTemplate;

static unsigned char disp_image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB];


static unsigned char image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB];
179

int fd;
int frame_no=1;
int exit_flag;
int save_flag;
int maks_frame=0;

static struct video_mbuf vm;


static struct video_mmap vmap;
static struct video_picture vptemp;

extern int extract_skin_color;


extern Image *image1,*image2,*image3;
extern TempImage *tImage1,*tImage2,*tImage3,*tImage4;
extern int dataPos[32][3];
extern puInput *textKorelasi;
extern puInput *data;
extern int video_tracking;
extern PointTemplate *pTemplate[32];
extern PointTemplate *pTemplate1[32];

BMINFO bi;
BLERR status;

void copyImage(Image *src,Image *dst);


int loadTextfile(char *fname,Image **image);
void videoTracking(TempImage *tImage,unsigned char *displ_video,int startx,int
starty,int data[4],float cparam);
float VpointCorrelation(PointTemplate *ptemp,unsigned char *video_disp,int posx,int
posy);
void VtrackPoint(PointTemplate *ptemp,unsigned char *video_disp,PointTemplate
*ptempdst,float cparam);

void videoCaptureImage(){
static char image_prefix[1024]=PREFIX_IMAGE_FILE;
//static unsigned char
skin_map[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS];

CaptV4LDoubleBufferingCaptureWait(fd,&vmap);
CaptV4LSetImageDownSamplingForOpenGL(vmap,vm,DOWN_SAMPLING
_RATE,image,disp_image);

if(CaptV4LDoubleBufferingCaptureNextFrame(fd,&vmap)==-1){
fprintf(stderr,"Tidak bisa mengambil frame berikutnya.\n");
exit(-1);
}
/*
CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
*/
//CaptV4LDisplayPictureInfo(vptemp);
180

videoDisplayImage();

if(save_flag==1){
saveBitmap(image,IMAGE_HEIGHT_DS,IMAGE_WIDTH_DS,frame_no,ima
ge_prefix);
if(frame_no>=maks_frame){
save_flag=0;
frame_no=0;
}
if(frame_no==1){
loadTextfile("video_image_1.bmp",&image2);
//copyImage(image1,image2);
}
data->setValue(frame_no);
frame_no++;
}
/*
if(video_tracking==1){

videoTracking(tImage1,image,dataPos[0],dataPos[1],dataPos,textKorelasi-
>getFloatValue());
}else if(video_tracking==2){

videoTracking(tImage2,image,dataPos[0],dataPos[1],dataPos,textKorelasi-
>getFloatValue());
}else if(video_tracking==3){

videoTracking(tImage3,image,dataPos[0],dataPos[1],dataPos,textKorelasi-
>getFloatValue());
}else if(video_tracking==4){

videoTracking(tImage4,image,dataPos[0],dataPos[1],dataPos,textKorelasi-
>getFloatValue());
}else{
}
*/
if(video_tracking==1){
for(int i=0;i<32;i++){

VtrackPoint(pTemplate[i],image,pTemplate1[i],textKorelasi-
>getFloatValue());
dataPos[i][0]=pTemplate1[i]->posx;
dataPos[i][1]=pTemplate1[i]->posy;
pTemplate[i]->posx=pTemplate1[i]->posx;
pTemplate[i]->posy=pTemplate1[i]->posy;
}
}

glutSwapBuffers();
181

if(exit_flag){
exit(0);
}

void setsave_flag(int val){


save_flag=val;
}
int getsave_flag(){
return save_flag;
}

void setMaksFrame(int num_frame){


maks_frame=num_frame;
}

void setBrightness(int val){


vptemp.brightness=val;
CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
}
int getBrightness(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.brightness;
}

void setContrast(int val){


vptemp.contrast=val;
CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
}
int getContrast(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.contrast;
}
void setColorb(int val){
vptemp.colour=val;
CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
}
int getColorb(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.colour;
}

void setHue(int val){


vptemp.hue=val;
182

CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
}

int getHue(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.hue;
}

void setWhiteness(int val){


vptemp.whiteness=val;
CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
}

int getWhiteness(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.whiteness;
}

int videoInitCaptureDevice(char *device_name,int channel_no){


struct video_capability vcap;
struct video_channel vch[MAX_NO_CHANNEL];
struct video_picture vp;

//inisialisasi device video


if((fd=CaptV4LOpen(device_name))==-1){
fprintf(stderr,"Tidak bisa membuka device %s.\n",device_name);
exit(-1);
}
printf("Device name = %s\n",device_name);
if(CaptV4LGetDeviceCapability(fd,&vcap)==-1){
fprintf(stderr,"Tidak bisa mendapatkan informasi device.\n");
exit(-1);
}
//printf("stage -1\n");
CaptV4LDisplayDeviceCapability(vcap);

if(CaptV4LGetChannelInfo(fd,vch,vcap.channels)==-1){
fprintf(stderr,"Tidak bisa medapatkan informasi channel.\n");
exit(-1);
}
printf("channel : %d\n",vcap.channels);

if(CaptV4LGetMemoryMapInfo(fd,&vm)==-1){
fprintf(stderr,"Tidak bisa mendapatkan informasi pemetaan
memory.\n");
exit(-1);
}
183

CaptV4LGetPictureInfo(fd,&vp);
CaptV4LDisplayPictureInfo(vp);

CaptV4LDisplayChannelInfo(vch,channel_no);

if(CaptV4LSelectChannel(fd,vch,channel_no)==-1){
fprintf(stderr,"Tidak bisa memilih channel.\n");
exit(-1);
}

if(CaptV4LMemoryMapping(fd,vm)==-1){
fprintf(stderr,"Tidak bisa memetakan frame buffer.\n");
exit(-1);
}

vmap.width=CAPTURE_IMAGE_WIDTH;
vmap.height=CAPTURE_IMAGE_HEIGHT;
vmap.format=VIDEO_PALETTE_RGB24;

CaptV4LDisplayMemoryMapInfo(vm);
CaptV4LDoubleBufferingInitCapture(fd,&vmap);

return 0;

void videoDisplayImage(){
glRasterPos2i(50,200);
glDrawPixels(IMAGE_WIDTH_DS,IMAGE_HEIGHT_DS,GL_BGR,GL_UN
SIGNED_BYTE,disp_image);
glFlush();
}

void videoMouseCheck(int button,int status, int x, int y){


if(button == GLUT_LEFT_BUTTON && status == GLUT_DOWN){
exit_flag=1;
}
}

void videoSavePPMImage(unsigned char *image,int iheight, int iwidth,int frame_no,char


*image_prefix){
char file_name[1024];

FILE *fp;
sprintf(file_name,"%s_%d.ppm",image_prefix,frame_no);
if((fp=fopen(file_name,"w"))==NULL){
fprintf(stderr,"Tidak dapat membuka file : %s\n",file_name);
exit(1);
}
fprintf(fp,"P6 %d %d 255\n",iwidth,iheight);
184

fwrite(image,iheight*iwidth*RGB,1,fp);
fclose(fp);
}

void saveBitmap(unsigned char *image,int iheight,int iwidth,int frame_no,char


*image_prefix){
char file_name[1024];
sprintf(file_name,"%s_%d.bmp",image_prefix,frame_no);
bi.width=iwidth;
bi.height=iheight;
bi.bitmapdata=image;
fflush(NULL);
bi.fd=open(file_name,O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
if(bi.fd<=0){
printf("Tidak bisa menyimpan ke file bmp.\n");
exit(1);
}
status=Save_Bitmap(&bi);
close(bi.fd);

5. Program makefile

GLUT_LDFLAG = -L/usr/X11R6/lib -lglut -lGL -lGLU -lplibsl -lplibssgaux -lplibssg


-lplibpu -lplibfnt -lplibsg -lplibul -lSM -lICE -pthread -lX11 -lXi -lXext -lXmu

LDFLAGS = $(GLUT_LDFLAG) -lm

GLUT_INCFLAG = -I/usr/X11R6/include
INCFLAGS = $(GLUT_INCFLAG)

CXX = g++
CXXFLAGS = -g -O2 -O6 -Wall

SRCS = main.cxx bshowv4l.cxx bcapv4l.cxx bmp.cxx


HDRS = main.h image.h dip.h bshowv4l.h bcapv4l.h bmp.h
OBJS = $(SRCS:.cxx=.o)
TARGET = beeTA

#
# link
#
$(TARGET): $(OBJS)
$(CXX) -o $@ $(OBJS) $(LDFLAGS)

#
# compile
#
185

main.o:
$(CXX) $(INCFLAGS) $(CXXFLAGS) -c main.cxx

bshowv4l.o:
$(CXX) $(INCFLAGS) $(CXXFLAGS) -c bshowv4l.cxx

bcapv4l.o:
$(CXX) $(INCFLAGS) -c bcapv4l.cxx

bmp.o:
$(CXX) $(INCFLAGS) -c bmp.cxx
#
# compare time
#
main.o: main.cxx $(HDRS)
bshowv4l.o: bshowv4l.cxx $(HDRS)
bcapv4l.o: bcapv4l.cxx $(HDRS)
bmp.o: bmp.cxx $(HDRS)
#extract_skin_color.o : extract_skin_color.c $(HDRS)

clean:
rm -f $(TARGET) *.o
186

-----Halaman ini sengaja dikosongkan-----


PROFILE PENULIS

Penulis yang lahir disebuah desa nun jauh di ujung timur jawa,
dengan modal pas-pasan, dan dengan memegang teguh prinsip
“tuntutlah ilmu setinggi langit” bertekad untuk menuntut ilmu dan hidup
mandiri di kota Surabaya tercinta. Berikut jika ingin mengenal lebih
dekat dengan penulis;

Nama : Bitaria Citra Dewi


Panggilan : bita, bee, beetooth
Alamat : Jatiluhur Rt.05/1,
Glagahagung,
Purwoharjo,
Banyuwangi.
Agama : Islam
TTL : Banyuwangi, 22 April
1984
No Telp : (0333) 591452
HP : 081330525012
Email : bee_tooth@yahoo.com
Kirei_xx@plasa.com

Latar Belakang Pendidikan :


1. Tahun 1990 – 1991 : TK. Aisyah Bustanul Atfal
2. Tahun 1991 – 1997 : SDN Glagahagung 02
3. Tahun 1997 – 2000 : SLTPN 1 Purwoharjo
4. Tahun 2000 – 2003 : SMUN 1 Glagah, Banyuwangi
5. Tahun 2003 – 2006 : PENS – ITS (EEPIS)
Jurusan Teknik Telekomunikasi

Pesan dan Kesan :


“ Kesuksesan terkadang harus dilalui dengan cobaan yang besar, dan
kita harus yakin bahwa kemudahan akan datang sesudah kesulitan, asal
dengan kesungguhan hati mau berusaha dan beberapa keberuntungan”

187

You might also like