Professional Documents
Culture Documents
Dosen Pembimbing:
SRITRUSTA SUKARIDHOTO, ST
NIP. 132 300 372
Oleh :
BITARIA CITRA DEWI
7203 030 042
Disetujui oleh
Tim Penguji Proyek Akhir Dosen Pembimbing
1. 1.
ii
ABSTRAK
iii
ABSTRACT
iv
KATA PENGANTAR
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
viii
2.13 Pemrograman Glut ................................................................ 28
2.14 PLIB .................................................................................... 33
2.15 Video for Linux ................................................................... 41
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
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
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.
1
2
1.2 TUJUAN
1.4 PERMASALAHAN
BAB I PENDAHULUAN
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
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.
7
8
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
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).
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 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.
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.
1
h(x,y) =
M
∑ f (k , l )
( k ,l )∈N
(2.3)
x +1 y +1
1
h(x,y) =
9
∑ ∑ f (k , l )
k = x −1 l = y −1
(2.4)
X2
−
2σ 2
g(x) = e (2.6)
( x2 + y2 )
−
2σ 2
g(x,y) = e (2.7)
16
⎡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
( 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.
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
If F[x,y] < Tr
F[x,y] = obyek = 1
Else
F[x,y] = background = 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.
r + g +b
s= (2.16)
3
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)
ϑ = arctan(Gy / Gx ) (2.19)
Yang sering terjadi dalam filter ini adalah nilai absolut dari
magnitude hanya sebatas penglihatan mata kita saja, apabila terdapat dua
24
G = (P1 + 2 × P2 + P3 ) − (P7 + 2 × P8 + P9 ) +
(2.20)
(P3 + 2 × P6 + P9 ) − (P1 + 2 × P4 + P7 )
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)
Ketika ∑x
2
f (x) kurang lebih konstan ini juga dapat dipotong, hal ini
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.
glVertex2i(…..)
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
1. Inisialisasi
#include <GL/glut.h>
GLUT_SINGLE);
glutInit(&argcp,argv);
……. More code
};
glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_RGBA |
GLUT_DOUBLE);
glutInit(&argcp,argv);
…..more code
};
2. Event Processing
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>
/* Open a window */
glutCreateWindow("My OpenGL
Application");
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();
};
/* Open a window */
glutCreateWindow("My OpenGL Application");
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
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
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.
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.
|---Class netAddress
|---Class netBuffer
| |---class netMessage
|
37
|----Class netGuid
|----Class netSocket
|-----class netChannel
| |
| |----class netBufferChannel
| |----class netChat
|-----class netMonitorServer
#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 */ ;
}
#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 displayfn ()
{
glClearColor ( 0.1, 0.4, 0.1, 1.0 ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
puDisplay () ;
glutSwapBuffers () ;
glutPostRedisplay () ;
}
puInit () ;
glutMainLoop () ;
return 0 ;
}
Object Picking
glutPostRedisplay () ;
41
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 :
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.
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.
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.
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.
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.
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.
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
First frame
Template
Camera
Tracking Display
Facial Tracking
Template Matching
51
52
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
>lsmod
dibaca, dan hasil pembacaan ini ditampung dalam sebuah variabel yang
bertipe struct. Potongan kode 3.1 merupakan proses pembukaan file
/dev/video.
#include "bcapv4l.h"
for(i=0;i<no_channel;i++){
vch[i].channel = i;
if( ioctl(fd, VIDIOCGCHAN,
&vch[i])==-1){
return -1;
}
}
return 0;
}
57
int videoInitCaptureDevice(char
*device_name,int channel_no){
struct video_capability vcap;
struct video_channel vch[MAX_NO_CHANNEL];
struct video_picture vp;
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;
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);
}
void videoDisplayImage(){
glRasterPos2i(50,200);
glDrawPixels(IMAGE_WIDTH_DS,IMAGE_HEIGHT_
DS,GL_BGR,GL_UNSIGNED_BYTE,disp_image);
glFlush();
}
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);
}
1
h(x,y) =
M
∑ f (k , l )
( k ,l )∈N
(3.1)
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);
}
}
.
.
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;
}
}
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)
∑∑ 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
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.
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
}
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
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
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.
81
82
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
Agar template yang dibuat masih bisa digunakan kembali, pada sistem
ini juga dilengkapi untuk menyimpan template ke dalam sebuah file
yang berektensi *.bcd.
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
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
250
200
150 Template
100 Image
50
0
1 118 235 352 469 586 703 820 937 1054 1171
250
200
150 Image
100 Template
50
0
1 118 235 352 469 586 703 820 937 1054 1171
250
200
150 Template
100 Image
50
0
1 118 235 352 469 586 703 820 937 1054 1171
250
200
150 Template
100 Image
50
0
1 118 235 352 469 586 703 820 937 1054 1171
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
6000
5000
0
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
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"
/*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
#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;
void init_event(){
}
/*
titik[32][2]=0;
titik[33][2]=62;
titik[34][2]=29;
titik[35][2]=171;
*/
void drawString(char *data){
117
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;
}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--;
}
}*/
if(flag_replay==0){
flag_replay=1;
konter_frame=1;
}
else{
flag_replay=0;
}
}
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);
}
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;
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
};
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;
}
}
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
};
puCallback view_submenuCB[]={
zoomIn_cb,
zoomOut_cb,
NULL
};
char *filter_submenu[]={
"Median Filter",
"Mean Filter",
"Gaussian Filter",
"Blur",
NULL
};
puCallback filter_submenuCB[]={
medfilCB,
menfilCB,
gausfilCB,
blurCB,
NULL
};
char *image_submenu[]={
"Edge Detetction",
124
"_______________",
"GreyScale",
"Histogram",
"Treshhold",
"RGB Channel",
NULL
};
if(histFlag==0)
histFlag=1;
else
histFlag=0;
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;
}
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;
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;
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;
}
*/
}
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
};
puCallback help_submenuCB[]={
about_cb,
NULL
};
void init_database(){
skinScene=new ssgRoot;
boneScene=new ssgRoot;
}
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]);
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();
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();
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]);
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);
glutPostRedisplay();
glutSwapBuffers();
}
//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
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
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
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);
}
//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);
}
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);
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);
}
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();
struct Image{
147
};
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
Image *image1,*image2,*image3,*image4;
TempImage *tImage1,*tImage2,*tImage3,*tImage4;
PointTemplate *pTemplate[35];
PointTemplate *pTemplate1[35];
if((i=fread(&image->sizey,4,1,file))!=1){
printf("Error baca data ukuran y gambar\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(){
if(!imageLoad("video_image_1.bmp",image1)){
exit(1);
}
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];
}
}
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;
}
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
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;
}
int index;
index = posy*image->sizex + posx;
return image->data[index*3+2];*/
}
//for(i=0;i<size;i++){
// t_image->data[i]=0;
//}
}
153
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;
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);
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);
}
}
int dataPos[35][3];
int histFlag=0;
int flag_viewTracking=0;
double coredata=0.8f;
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
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);
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);
//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");
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;
}
}
}
161
}
flag_viewTracking=1;
}
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];
//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");
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];
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);
}
#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>
#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
/*bcapv4l.cxx*/
#include "bcapv4l.h"
for(i=0;i<no_channel;i++){
vch[i].channel = i;
if( ioctl(fd, VIDIOCGCHAN, &vch[i])==-1){
return -1;
}
}
return 0;
}
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;
}
}
}
return 0;
}
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;
}
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
}
#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
/*bshowv4l.cxx*/
#include "bshowv4l.h"
//#include "bee_vproc_v4l.h"
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;
int fd;
int frame_no=1;
int exit_flag;
int save_flag;
int maks_frame=0;
BMINFO bi;
BLERR status;
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);
}
CaptV4LSetPicture(fd,&vptemp);
CaptV4LGetPictureInfo(fd,&vptemp);
}
int getHue(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.hue;
}
int getWhiteness(){
CaptV4LGetPictureInfo(fd,&vptemp);
return vptemp.whiteness;
}
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();
}
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);
}
5. Program makefile
GLUT_INCFLAG = -I/usr/X11R6/include
INCFLAGS = $(GLUT_INCFLAG)
CXX = g++
CXXFLAGS = -g -O2 -O6 -Wall
#
# 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
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;
187