Anda di halaman 1dari 124

DETEKSI WAJAH DENGAN METODE CONSTRAINT

LOCAL MODELS
MELALUI PENDEKATAN R DENGAN IMPLEMENTASI PADA WEBGL

LAPORAN PROYEK

NAMA KELOMPOK

AGNAN ZAKARIYA

: 5A412004

MUHAMMAD RIDWAN ISMANU

: 54411947

WILDAN FIRDAUS

: 57411402

GUSTI PRIBADI R. S.

: 55409234

Diajukan guna memenuhi tugas kelompok mata kuliah Grafik Komputer II

FAKULTAS TEKNIK INDUSTRI


JURUSAN TEKNIK INFORMATIKA
UNIVERSITAS GUNADARMA
DEPOK
2014

ABSTRAK

Deteksi wajah atau yang biasa di kenal dengan sebutan face recognition adalah
metode komputerisasi yang dirancang untuk mengidentifikasi wajah manusia dari
gambar digital atau frame video. Teknologi ini memindai gambar tersebut, dan
mencari apakah di sana ditemukan struktur dan kontur wajah manusia yang terdiri
dari sepasang mata, satu hidung, satu bibir, serta sepasang pipi dan rahang. Beberapa
bentuk persamaan telah di ditawarkan untuk menangani proses artificial pengenalan
wajah ini, diantaranya adalah metode persamaan Constraint Local Models (CLM).
CLM

merupakan

pemodelan

matematika

dengan

dasar

pendekatan

dari

metode regularized landmark mean-shift, seperti yang telah di jelaskan pada paper
Jason M. Saragih yang berjudul Deformable Model Fitting by Regularized
Landmark Mean-Shift. Metode ini berprinsip pada eksperimen numerik, dengan
melakukan pendekatan yang seksama dalam prosesnya, metode ini terbukti dapat
mengungguli beberapa metode yang ada pada umumnya untuk melakukan
serangkaian tugas memindai wajah secara generik.

DAFTAR ISI
COVER
ABSTRAK
DAFTAR ISI

i
3

BAB I PENDAHULUAN
1.1 Latar Belakang
1.2 Batasan Masalah
1.3 Tujuan Penulisan
1.4 Metode Penelitian
1.5 Sistematika Penulisan

4
4
5
5
5
7

BAB II LANDASAN TEORI


2.1. Sistem Pengenalan Wajah
2.2. Proses Pengenalan Wajah
2.3. Pengenalan Bahasa R
2.3.1. Dasar Algoritma Matriks pada R
2.3.1.1. Fungsi Matriks pada R
2.4. Pengenalan WebGL
4.1 Implementasi Browser Desktop
4.2 Implementasi Browser Mobile
2.5. Pengenalan Jquery
2.6. CLMTracker Library

8
8
10
11
12
14
15
17
17
18
18

BAB III PERANCANGAN ALGORITMA DAN PENDEKATAN MODEL


3.1. Perancangan Algoritma Dasar
3.1.1. Algoritma Matriks
3.1.1.1. Deskripsi Algoritma Matriks
3.1.1.2. Pendekatan Peudocode pada C++
3.1.1.3. Pendekatan Peudocode pada R
3.2. Memulai pendekatan mpdel menggunakan R
3.2.1. Membaca Data pada R
3.1.2. Algoritma dengan variabel titik kunci pada data citra dengan R
3.1.3. Algoritma dengan Benchmark sederhana dengan R
3.1.4. Algoritma dengan penggunakan patch gambar dengan R
3.1.5. Algoritma eksperimental dengan R
3.3. Perancangan penggunaan tapis pada (CLM)
3.3.1. Tapis Korelasi MOSSE
3.3.2. Transformasi Fourier Cepat
3.3.3. Tracker Titik Kunci (Keypoints)
3.3.4. Implementasi Eigenvalues dan Eigenvector
3.3.5. Implementasi Jacobian Matriks

20
20
21
22
23
25
26
27
34
38
41
45
47
47
48
49
50
51

BAB IV IMPLEMENTASI PROGRAM


4.1. Implementasi pada WebGl
4.1.1. Implementasi Constrain Local Models pada gambar
4.1.2. Substitusi Wajah
4.1.3. Masking Wajah
4.1.4. Deformasi Realtime Wajah
4.1.4. Deteksi Emosi Wajah

52
52
53
54
55
56
57

BAB V PENUTUP
5.1. Kesimpulan
5.2. Saran

59
59

DAFTAR PUSTAKA

60

LAMPIRAN

67

PENDAHULUAN

1.1 Latar Belakang


Beberapa tahun terakhir perkembangan teknologi berkembang sangat pesat
dari perkembangan tersebut memunculkan

beberapa perkembangan yang baik

terhadap teknologi pengenalan wajah manusia yang mendapatkan perhatian serius


dari beberapa peneliti dibidang face localization yaitu pendeteksian wajah manusia
namun dengan asumsi hanya ada satu wajah manusia di dalam citra, penjejakan wajah
(face tracking) untuk memperkirakan lokasi suatu wajah manusia dalam video
secara real time, dan pengenalan ekspresi wajah (facial expression recognition) untuk
mengenali kondisi emosi manusia.
Selain itu dalam bidang penelitian pemrosesan wajah (face processing),
pendeteksi wajah manusia (face detection) adalah salah satu tahap awal yang sangat
penting di dalam proses pengenalan wajah manusia (face recognition). Sistem
pengenalan wajah manusia digunakan untuk membandingkan satu citra wajah
manusia masukan dengan suatu database wajah dan menghasilkan wajah yang paling
cocok dengan citra tersebut. Dengan berkembangnya teknologi yang berkembang
pesat dan beberapa penelitian tentang pengenalan wajah, hal tersebut dapat
diimplementasikan pada pembuatan sistem keamanan suatu perusahaan, dengan
sistem pengenalan wajah manusia seseorang yang tidak memiliki hak akses tidak
dapat masuk ke dalam ruangan tersebut.
Dalam pengenalan wajah terdapat beberapa metode yang biasa digunakan
antara lain Principal Component Analysis, Constrained Local Models dan Edge
detection. Constrained Local Models merupakan sebuah metode dalam mengekstraksi
ciri suatu objek. Dalam mengekstraksi ciri, CLM membagi beberapa kelas dalam

pencarian ciri, misalnya ada data enam orang, dimana setiap orang terbagi menjadi
setiap kelas. Jika dibandingkan dengan metode-metode lain, CLM memiliki ketepatan
yang sangat tinggi dalam mengenali wajah seseorang, dikarenakan dalam metode
CLM ini memiliki banyak data dalam pengenalan wajah seseorang.

1.2 Batasan Masalah


Untuk menjaga fokus dari penulisan ini, maka beberapa batasan yang
diberikan sebagai berikut :
1. Wajah yang akan dideteksi adalah wajah yang menghadap ke depan, dalam
posisi tegak dan tidak terhalangi sebagian objek lain
2. Metode yang dipakai adalah metode Constrained Local Models dan Edge
detection.
3. Citra yang dideteksi menggunakan format BMP atau JPG
4. Hasil deteksi wajah merupakan titik lokasi penandaan batas wajah.

1.3 Tujuan Penulisan


Tujuan dari penulisan ini adalah untuk membuat pendekatan dalam memahami
bagaimana deteksi wajah bekerja menggunakan metode Constraint Local Models
(CLM). Dengan pendekatan ini kita akan belajar lebih dalam bagaimana sebuah
sistem dapat membangun sistem jaringan syarat tiruan atau Artificial Inteligent dalam
mendeteksi wajah manusia.

1.4 Metode Penelitian


Metode penelitian yang diterapkan pada penulisan laporan ini adalah
memperbaharui hasil penulisan yang telah ada untuk lebih mengembangkannya.

Selain itu dilengkapi juga dengan literasi dari berbagai referensi diantaranya melalui
jurnal, dokumentasi, dan log yang terdapat pada sumber kode terbuka versi paling
terbaru melalui SVN Github.

IDE dan Perangkat lunak pendukung lainnya yang di gunakan sebagai penunjang
penulisan ini diantaranya:
-

Textwrangler

Browser Mozilla Firefox

Berikut dengan library yang mendukungnya, antara lain:


-

JQuery

CLMTracker

Hardware yang digunakan:


-

Intel dual core 2,0 GHz

RAM 2 Gb

VGA approx memory shared 256 Mb

Webcam 1,3 MP

Dalam pembuatan Penulisan ini kami melakukan beberapa tahapan yaitu:


-

Merancang rangkaian hirarki teknis Penulisan.

Tahap berikutnya adalah analisis library dan instalasi toolkit pada IDE.

Pada tahap akhir yaitu melakukan uji coba, dimana kami menguji aplikasi ini
menggunakan webcam.

1.5 Sistematika Penulisan


Penulisan ilmiah ini terdiri dari 4 BAB disertai lampiran dan mempunyai garis besar
sebagai berikut:
BAB I PENDAHULUAN, Bab ini terdiri dari latar belakang masalah, batasan
masalah, tujuan penulisan, metode penelitian dan sistematika penulisan.
BAB II LANDASAN TEORI, Bab ini membahas teori pengenalan wajah,
penggunaan bahasa R, penggunaan WebGL dan library pendukung.
BAB III PERANCANGAN ALGORITMA, Bab ini menerangkan gambaran umum
aplikasi dan perancangan algoritma.
BAB IV IMPLEMENTASI PROGRAM, Bab ini menerangkan pembuatan,
pengimplementasian program dan spesifikasinya.
BAB V PENUTUP, Bab ini berisi kesimpulan dan saran.

BAB II
LANDASAN TEORI

1. Sistem Pengenalan Wajah


Pengenalan wajah manusia adalah bidang penelitian penting dengan banyak
aplikasi yang dapat menggunakannya. Penelitian terhadap pengenalan wajah manusia
sudah banyak dilakukan dengan kelebihan dan kekurangan tertentu. Hal ini
disebabkan karena wajah manusia merepresentasikan sesuatu yang kompleks dan
mengembangkan model komputasi untuk pengenalan wajah manusia adalah hal yang
sulit.
Pengenalan wajah ini dibagi menjadi dua bagian yaitu: dikenali dan tidak
dikenali, setelah dilakukan perbandingan dengan pola yang sebelumnya disimpan di
dalam database. Perhitungan model pengenalan wajah memiliki beberapa masalah.
Kesulitan muncul ketika wajah dipresentasikan dalam suatu pola yang berisi
informasi unik yang membedakan dengan wajah lain. Metode pengenalan wajah
memiliki dua prosedur, yaitu :

a) Pengenalan kontur wajah dengan mengenali bentuk hidung, mata dan mulut dan
bentuk korelasi diantara keduanya. Karakteristik organ tersebut kemudian
dinyatakan dalam bentuk vektor.
b) Analisis komponen yang prinsipil, berdasarkan informasi dari konsep ini, mencari
perhitungan model terbaik yang menjelaskan bentuk wajah dengan mengutip
informasi yang paling relevan yang terkandung didalam wajah tersebut.

Dibalik kemudahan pengenalan wajah, ada beberapa masalah yang mungkin timbul
dalam proses pengenalan wajah yang biasa disebut dengan robust, yaitu:

a) Perubahan skala Citra seseorang dapat dipresentasikan berbeda diakibatkan


perbedaan jarak antara wajah dengan kamera. Semakin dekat jarak maka citra
akan semakin besar.
b) Perubahan posisi Citra seseorang dapat dipresentasikan berbeda diakibatkan
perubahan posisi seseorang ataupun perubahan sudut pengambilan wajah.
c) Perubahan cahaya Citra seseorang dapat dipresentasikan berbeda diakibatkan
perubahan intensitas cahaya yang terjadi pada saat pengambilan citra.

Perubahan detail dan ekspresi Citra seseorang dapat dipresentasikan berbeda


diakibatkan perubahan detail seperti adanya janggut, kumis, pemakaian aksesoris,
perubahan gaya, perubahan ekspresi wajah menjadi tertawa, tersenyum, muram,
menangis dan lain sebagainya yang dapat mengakibatkan perubahan citra.
Langkah-langkah dalam proses pembuatan sistem pengenalan wajah berbeda
satu dengan yang lain. Hal ini disebabkan karena adanya faktor-faktor seperti ukuran
database atau training set dari citra wajah, jenis input yang digunakan (citra foto
atau video), derau (noise) pada citra dan lain-lain.

2. Proses Pengenalan Wajah


Pada dasarnya proses dalam pengenalan wajah terbagi menjadi beberapa bagian
seperti pada blok diagram dibawah ini:

Gambar 1.2.1. Diagram Blok Pengenalan Wajah

Setiap bagian dalam diagram di atas dapat dilakukan melalui metode yang berbedabeda. Sebagai contoh, untuk mendeteksi wajah, kita dapat menggunakan metode
berbasis fitur (feature-based methods) untuk mendeteksi fitur pada wajah (mata,
hidung, mulut), atau dapat juga menggunakan deteksi warna kulit.
Metode Pendekatan Deteksi Wajah
Banyak sekali metode pendekatan yang dapat dilakukan pada tahap deteksi wajah
pada kondisi yang berbeda-beda. Metode pendekatan ini adalah metode berbasis fitur
(feature-based methods), template matching, metode berbasis tampilan (appearancebased methods). Feature-based methods bertujuan untuk mendeteksi keberadaan dan
lokasi fitur seperti mata, hidung, bibir, alis, dan lain-lain. Metode template
matching adalah sebuah metode dengan menggunakan template yang disimpan untuk
mendeskripsikan sebuah wajah secara utuh atau fitur wajah secara terpisah. Dalam
metode template matching ini, keberadaan sebuah wajah dapat diketahui melalui
perhitungan nilai korelasi antara citra masukan dan template yang disimpan.

10

Metode appearance-based adalah metode yang menggunakan template yang


dihasilkan dari training pada dataset citra dan digunakan untuk mendapatkan variabel
yang

mewakili

keberadaan

dari

wajah

itu

sendiri.

Dibandingan feature-

based dan template matching, metode appearance-based memberikan hasil yang


lebih baik ketika diterapkan pada sistem dengan sejumlah besar sampel.

Berikut adalah pengkategorian dari deteksi wajah.

Gambar 1.2.2. Pengkategorian Deteksi Wajah

3. Pengenalan Bahasa R
R adalah bahasa pemrograman dan perangkat lunak untuk analisis statistika
dan grafik. R dibuat oleh Ross Ihaka dan Robert Gentleman di Universitas Auckland,
Selandia Baru, dan kini dikembangkan oleh R Development Core Team, dimana
Chambers merupakan anggotanya. R dinamakan sebagian setelah nama dua
pembuatnya (Robert Gentleman dan Ross Ihaka), dan sebagian sebagian dari nama S.
Bahasa R kini menjadi standar de facto di antara statistikawan untuk pengembangan
perangkat lunak statistika, serta digunakan secara luas untuk pengembangan
perangkat lunak statistika dan analisis data.

11

R merupakan bagian dari proyek GNU. Kode sumbernya tersedia secara bebas
di bawah Lisensi Publik Umum GNU, dan versi biner prekompilasinya tersedia untuk
berbagai sistem operasi. R menggunakan antarmuka baris perintah, meski beberapa
antarmuka pengguna grafik juga tersedia.
R menyediakan berbagai teknik statistika (permodelan linier dan nonlinier, uji
statistik klasik, analisis deret waktu, klasifikasi, klasterisasi, dan sebagainya) serta
grafik. R, sebagaimana S, dirancang sebagai bahasa komputer sebenarnya, dan
mengizinkan penggunanya untuk menambah fungsi tambahan dengan mendefinisikan
fungsi baru. Kekuatan besar dari R yang lain adalah fasilitas grafiknya, yang
menghasilkan grafik dengan kualitas publikasi yang dapat memuat simbol
matematika. R memiliki format dokumentasi seperti LaTeX, yang digunakan untuk
menyediakan dokumentasi yang lengkap, baik secara daring (dalam berbagai format)
maupun secara cetakan.

3.1. Dasar Algoritma Matriks pada R


Misalkan A, B dua matriks persegi pada ring R. Kita ingin menghitung produk
matriks C sebagai

Jika matriks A, B bukan bertipe 2n x 2n kita isi baris-baris dan kolom-kolom yang
kosong dengan nol.
Kita partisi A, B dan C kedalam matriks blok yang berukuran sama.

dengan

lalu

12

Dengan konstruksi ini kita tidak mengurangi jumlah dari perkalian-perkalian. Kita
masih memerlukan 8 perkalian-perkalian untuk menghitung matriks-matriks Ci,j ,
dengan jumlah perkalian yang sama kita perlukan ketika menggunakan matriks
perkalian standar.
Sekarang sampai pada bagian terpenting. Kita tetapkan matriks baru

Yang kemudian digunakan untuk mengekspresikan Ci,j dalam bentuk Mk. Karena kita
telah mendefenisikan Mk kita bisa mengeliminasi satu perkalian matriks dan
mengurangi jumlah perkalian-perkalian menjadi 7 (satu perkalian matriks untuk
tiap Mk) dan ekspresi Ci,j sebagai

Kita iterasikan bagian diatas ke-n kali proses sampai submatriks-submatriks menjadi
angka-angka.

13

3.1.1. Fungsi Matriks menggunakan Bahasa R


Matriks A adalah kumpulan elemen data yang diatur dalam tata letak persegi
panjang dua dimensi. Berikut ini adalah contoh dari sebuah matriks dengan 2 baris
dan 3 kolom. Pada bahasa R, perhitungan matriks mengimplementasi Algoritma
Strassen. Dalam matematika, khususnya aljabar linear Algoritma Strassen
merupakan sebuah algoritma yang dinamakan oleh Volker Strassen yang merupakan
sebuah algoritma yang digunakan untuk perkalian matriks yang secara asimtot lebih
cepat dari pada algoritma perkalian matriks standar dan sangat berguna dalam
penggunaanya untuk matriks yang berukuran besar.

Kami mereproduksi representasi memori dari matriks menggunakan fungsi dalam


bahasa pemrograman R. Dengan unsur-unsur data dari jenis dasar yang sama.
> A = matrix (
+ C (2, 4, 3, 1, 5, 7), # elemen data
+ Nrow = 2, # jumlah baris
+ Ncol = 3, # jumlah kolom
+ Byrow = TRUE) # mengisi matriks dengan baris
> A # mencetak matriks
[1] [2] [3]
[1,] 2

4 3

[2,] 1 5 7

Sebuah elemen pada baris-m dan kolom-n dari matriks A dapat diakses oleh ekspresi
A [m, n].
> A [2, 3] # elemen pada baris 2, kolom 3
[1] 7

Seluruh baris-m pada matriks A dapat diekstraksi oleh ekspresi A[m,].


> A [2,] # baris 2

14

[1] 1 5 7

Demikian pula, seluruh kolom-n pada matriks A dapat diekstraksi oleh ekspresi A[,
n].
> A [3] # 3 kolom
[1] 3 7

Kami juga dapat mengekstrak lebih dari satu baris atau kolom dalam satu waktu.
> A [, c (1,3)] # 1 dan kolom ke-3
[1] [2]
[1,] 2 3
[2,] 1 7

Jika kita menetapkan nama untuk baris dan kolom dari matriks tersebut, kita dapat
menentukannya dengan mengakses elemen menggunakan nama yang ditetapkan.
> Dimnames (A) = list(
+ c ("row1", "row2"), # nama baris
+ C ("col1", "col2", "col3")) # nama kolom
> A # print A
col1 col2 col3
row1 2 4 3
row2 1 5 7
> A ["row2", "col3"] # elemen pada baris 2, kolom 3
[1] 7

4. Pengenalan WebGL
WebGL (Web Graphics Library) adalah JavaScript API untuk rendering grafis
3D interaktif dan grafis 2D dalam browser web yang kompatibel tanpa menggunakan
plug-in. WebGL terintegrasi sepenuhnya ke semua standar web browser yang
memungkinkan penggunaan percepatan GPU fisika dan pengolahan gambar dan efek
sebagai bagian dari kanvas halaman web. Elemen WebGL dapat dicampur dengan
elemen HTML lainnya dan composited dengan bagian-bagian lain dari latar belakang

15

halaman atau halaman. WebGL program terdiri dari kode kontrol ditulis
dalamJavaScript dan

kode

shader

yang

dijalankan

pada

komputer Graphics

Processing Unit (GPU). WebGL dirancang dan dipelihara oleh Kelompok Khronos
non-profit.
WebGL didasarkan pada OpenGL ES 2.0 dan menyediakan sebuah API untuk
grafis 3D. Untuk alasan keamanan, GL_ARB_robustness (OpenGL 3.x) atau
GL_EXT_robustness (OpenGL ES) diperlukan. Ia menggunakan elemen kanvas
HTML5 dan diakses menggunakan antarmuka Document Object Model. Manajemen
memori otomatis disediakan sebagai bagian dari bahasa JavaScript.
WebGL tumbuh dari eksperimen Canvas 3D dimulai oleh Vladimir
Vukievi di Mozilla. Vukievi pertama menunjukkan prototipe 3D kanvas pada
tahun 2006. Pada akhir tahun 2007, baik Mozilla dan Opera telah membuat
implementasi sendiri terpisah. Pada awal 2009, non-profit teknologi konsorsium Grup
Khronos

memulai

Kelompok

Kerja

WebGL,

dengan

partisipasi

awal

dari Apple, Google, Mozilla, Opera, dan lain-lain. Versi 1.0 dari spesifikasi WebGL
dirilis Maret 2011. Pada Maret 2012, ketua kelompok kerja adalah Ken Russell.
Aplikasi awal Terkemuka dari WebGL termasuk Google Maps dan Zygote Body.

16

4.1 Implementasi Browser Desktop


a) Memiliki kartu grafis yang mampu dengan driver diperbarui sejak versi 4.0.
Mozilla Firefox 8.0 dan versi yang lebih baru menggunakan Cross-asal
berbagi sumber daya (CORS) untuk mengontrol semua lintas domain tekstur
WebGL.
b) Google Chrome - WebGL telah diaktifkan pada semua platform yang
memiliki kartu grafis yang mampu dengan driver diperbarui sejak versi 9.
Google Chrome 13.0 dan versi yang lebih baru menggunakan Cross-asal
berbagi sumber daya (CORS) untuk mengontrol semua lintas domain tekstur
WebGL.
c) Safari - Safari 5.1 dan versi yang lebih baru diinstal pada Mac OS X Lion dan
Mac OS X Snow Leopard dukungan diterapkan untuk WebGL, yang
dinonaktifkan secara default.
d) Opera - WebGL telah diimplementasikan di Opera 11, dan 12 juga
dinonaktifkan secara default.
e) Internet Explorer - Saat ini, Microsoft tidak berencana untuk mendukung
WebGL karena alasan keamanan dan karena itu tidak menjadi standar W3C
belum, walaupun dukungan WebGL dapat secara manual ditambahkan ke
Internet Explorer menggunakan plugin pihak ketiga seperti Chrome Frame dan
IEWebGL.
4.2 Implementasi Browser Mobile
a) BlackBerry PlayBook - WebGL tersedia melalui WebWorks dan browser di
PlayBook OS 2.0

17

b) Firefox untuk mobile (en) - WebGL tersedia untuk perangkat Android dalam
membangun tidak stabil sejak awal 2011.
c) Sony Ericsson Xperia berbagai smartphone Android memiliki kemampuan
WebGL setelah upgrade firmware.
d) Opera Mobile (en) 12 akhir mendukung WebGL (pada Android saja).
e) Tizen 1.0

5. Pengenalan JQuery
jQuery adalah pustaka JavaScript kecil bersumber terbuka yang menekankan
pada interaksi antara JavaScript dan HTML. Pustaka ini dirilis pada Januari 2006 di
BarCamp NYC oleh John Resig dan berlisensi ganda di bawah MIT dan GPL.
Microsoft dan Nokia telah mengumumkan akan mengemas jQuery di platform
mereka. Microsoft awalnya mengadopsinya dalam Visual Studio untuk digunakan
dalam ASP.NET AJAX dan ASP.NET MVC Framework, sedangkan Nokia akan
mengintegrasikannya dalam kerangka Web Run-Time mereka.
6. CLMTracker Library
Clmtrackr adalah sebuah library javascript yang digunakan untuk mengenali
pemindaian model wajah pada sebuah citra atau video. Library ini merupakan
pemodelan matematika dari Constrained Local Models dengan dasar pendekatan dari
metode regularized landmark mean-shift, seperti yang telah di jelaskan pada paper
Jason M. Saragih yang berjudul Deformable Model Fitting by Regularized
Landmark Mean-Shift. Model pas terdeformasi secara aktif telah dikenal dalam
komunitas komputer vision selama lebih dari satu dekade. Akibatnya, banyak

18

pendekatan telah diusulkan dengan berbagai tingkat keberhasilan. Sebuah kelas


pendekatan yang menjanjikan secara substansial adalah salah satu yang membuat
prediksi independen mengenai lokasi dari landmark model, yang dikombinasikan
dengan persamaan atas gerak sendi mereka. Sebuah tema umum dalam inovasi untuk
pendekatan ini adalah penggantian distribusi lokasi tengara kemungkinan, yang
diperoleh dari masing-masing detektor lokal, dengan bentuk parametrik sederhana.
Dalam karya ini, strategi optimasi berprinsip diusulkan di mana representasi
nonparametrik dari likelihoods ini dimaksimalkan dalam hirarki estimasi untuk
merapihkan.
Sehingga menghasilkan persamaan yang baru untuk menyimpan rata-shift
selama landmark, dengan regularisasi yang dipaksakan melalui persamaan global
selama pergerakannya. Ekstensi untuk menangani oklusi parsial dan mengurangi
kompleksitas komputasi juga disajikan. Melalui eksperimen numerik, pendekatan ini
terbukti dapat mengungguli beberapa metode yang ada pada umumnya untuk
melakukan tugas memindai wajah secara generik.

19

BAB III
PERANCANGAN ALGORITMA DAN PENDEKATAN MODEL

3.1. Perancangan Algoritma Dasar


Dalam asas rasionalis natura mengungkapkan bahwa semesta ini adalah suatu
substansi tunggal yang mempunyai pola. Sebagian dari pernyataan tersebut dapat di
terima dan sebagian lagi tidak, tapi kunci pemahamannya dari aspek pemikiran
tersebut adalah pernyataan bahwa semua yang terjadi di dunia ini mempunyai pola.
Benar, bagaimana kita melihat aturan alam tentang siang dan malam, bagaimana kita
melihat tentang aturan bentuk manusia dengan rasio emasnya, lalu jarak orbit,
peredaran matahari, susunan tata surya beserta galaksi dsb. Semua mempunyai pola
yang beraturan tentunya.
Pada Matriks, yang hampir kita kenal dari pelajaran Sekolah Menengah
Pertama sampai tingkat pendidikan yang lebih lanjut. Jika Anda pernah bertanyatanya apa sebenarnya fungsi dari pembelajaran tersebut, lalu apakah pembelajaran ini
bermanfaat untuk kehidupan nyata (dalam arti, dapat di implementasi tidak hanya
sekedar teori) tentunya jika Anda tidak ingin mengetahuinya lebih lanjut, tanpa
menyadarinya semua hal tersebut telah nampak nyata dan dekat dengan keseharian
kita. Pada era digital ini, mungkin anda tidak menyadari bahwa foto-foto digital Anda
mengandung implementasi pola Matriks.
Salah satu proses yang penting dalam pengenalan objek yang tersaji secara
visual (berbentuk gambar) adalah segmentasi. Segmentasi objek di dalam citra
bertujuan memisahkan wilayah (region) objek dengan wilayah latar belakang.

20

Selanjutnya, wilayah objek yang telah tersegmentasi digunakan untuk proses


berikutnya (deteksi tepi, pengenalan pola, dan interpretasi objek). Metode segmentasi
yang

umum

adalah

pengambangan

citra

(image

thresholding).

Operasi

pengambangan mensegmentasikan citra menjadi dua wilayah, yaitu wilayah objek


dan wilayah latar belakang. Wilayah objek diset berwarna putih sedangkan sisanya
diset berwarna hitam (atau sebaliknya). Hasil dari operasi pengambangan adalah citra
biner yang hanya mempunyai dua derajat keabuan: hitam dan putih. Sebelum proses
segmentasi, citra mengalami beberapa pemrosesan awal (preprocessing) untuk
memperoleh hasil segmentasi objek yang baik. Pemrosesan awal adalah operasi
pengolahan citra untuk meningkatkan kualitas citra (image enhancement).
3.1.1 Algoritma Matriks
Berikut adalah algoritma dari matriks yang telah terenkapsulasi sebagai fungsi
di R. Dalam artian, pada bahasa R fungsi matriks hanya tinggal di gunakan saja tanpa
harus di inisiasi kembali. Untuk itu kami akan menerangkan lebih jauh tentang
algoritma pada matriks tersebut dengan beberapa pendekatan tentunya.

Judul: Algoritma fungsi matriks berordo-N pada operasi dasar aritmatika antar
matriks
Input : Data bilangan integer dalam bentuk array
Output : Hasil operasi dasar aritmatika pada matriks berordo-N
Proses :
Inisiasi variabel
m, n, row, col, matrix_one[n][m], matrix_two[n][m], matrix_res[n][m] (semua)
bilangan integer
Deklarasi proses

21

perulangan 1 : untuk m 0 ke row kerjakan, inkremental


perulangan 2 : untuk n 0 ke col kerjakan k, inkremental
matrix_res[n][m] = matrix_one[n][m] (OPS.AR) matrix_two[n][m]
akhiri perulangan 2
akhiri perulangan 1
Keterangan :
OPS.AR = Operasi Aritmatika

3.1.1.1 Deskripsi Algoritma Matriks


Judul: Algoritma fungsi matriks berordo-N pada operasi dasar aritmatika antar
matriks
Input : Data bilangan integer dalam bentuk array
Output : Hasil operasi aritmatika pada matriks berordo-N
Proses :
a) Inisiasi variabel
Blok ini menjelaskan inisiasi awal pada tiap variabel yang terdapat pada
fungsi matriks.
Dimana: m, n, row, col, matrix_one[n][m], matrix_two[n][m],
matrix_res[n][m] (semua) bilangan integer.
b) Deklarasi proses
Blok ini menjelaskan inisiasi awal pada tiap variabel yang terdapat pada
fungsi matriks.
Dimana:
Pada perulangan 1: untuk m bernilai 0 dikomparasi dengan nilai row
maka statement dibawahnya akan di kerjakan, dan terjadi inkremental pada m.

22

Sedangkan pada perulangan 2: untuk n bernilai 0 dikomparasi dengan nilai


col maka statement dibawahnya akan di kerjakan, dan terjadi incremental
pada n.
Lalu:
Mencetak hasil dari dari setiap operasi dasar aritmatika yang dilakukan pada
matrix_one dan matrix_two dimana hasilnya akan di simpan pada variabel
matrix_res(ult)
akhiri perulangan 2
akhiri perulangan 1
c) Keterangan
OPS.AR = Operasi Aritmatika
row adalah variabel inputan untuk baris
col adalah variable inputan untuk kolom

3.1.1.2 Pendekatan Pseudocode pada C++


Sebelum menerangkan pseudocode pada bahasa R, kami melakukan
pendekatan pada bahasa C++ sebagai bentuk komparasi pseudocode. Alasan kami
mengkomparasi yaitu untuk memaparkan konsep algoritma pada pseudocode dalam
bentuk bahasa pemrograman yang lebih umum dan lazim di gunakan agar lebih
mudah menjelaskannya secara garis besar. Karena bahasa C++ merupakan bahasa
yang lazim digunakan oleh setiap programmer, maka kami melakukan konversi
bahasa R terhadap C++.

Input:
row, col user input
for (m=0 ; m < row ; m++) {
for (n=0 ; n < col ; n++) {
matrix_definition[n][m] user input

23

}
}
proses:
for (m=0 ; m < row ; m++) {
for (n=0 ; n < col ; n++) {
matrix_res[n][m]
matrix_one[n][m](OPS.AR)matrix_two[n][m]
}
}
output:
for (m=0 ; m < row ; m++) {
for (n=0 ; n < col ; n++) {
output matrix_res[n][m]
}
}

Terdapat 3 blok pseudocode, yaitu blok input, blok proses, dan blok output. Berikut
penjelasannya per tiap blok.
Blok input merupakan blok masukan data yang di kehendaki oleh pengguna, dimana
row dan col mewakili inisiasi dari masukan jumlah baris dan kolom. Lalu nilai-m
sama dengan 0 akan dikomparasi dengan nilai row, dimana m mengalami inkremental
dan mendefinisikan pengulangan pada nilai-n sama dengan 0 yang akan di komparasi
dengan nilai col, dimana n akan mengalami inkremental lalu mendefinisikan tiap
inputan pada matrix [n] [m] sesuai data yang di kehendaki.

Blok proses merupakan blok pemrosesan data yang telah di inputkan, dimana row
dan col mewakili inisiasi dari masukan jumlah baris dan kolom. Lalu nilai-m sama
dengan 0 akan dikomparasi dengan nilai row, dimana m mengalami inkremental dan
mendefinisikan pengulangan pada nilai-n sama dengan 0 yang akan di komparasi
dengan nilai col, dimana n akan mengalami inkremental lalu mendefinisikan hasil
operasi aritmatika antara matrix_one dan matrix_two yang disimpan di matrix_res.
Blok output merupakan blok keluaran data yang telah di proses sebelumnya, dimana
row dan col mewakili inisiasi dari masukan jumlah baris dan kolom. Lalu nilai-m
sama dengan 0 akan dikomparasi dengan nilai row, dimana m mengalami inkremental

24

dan mendefinisikan pengulangan pada nilai-n sama dengan 0 yang akan di komparasi
dengan nilai col, dimana n akan mengalami inkremental lalu mendefinisikan hasil
output dari matrix_res.

3.1.1.3 Pendekatan Pseudocode pada R


Berikut adalah pendekatan pseudocode pada R setelah mengkalibrasi pseudocode
pada C++ . Pseudocode pada R lebih sederhana, karena tidak mengalami pengulangan
pada tiap blok. Rekursif hanya terjadi pada blok input.
Input:
row, col user input
for (m=0 ; m < row ; m++) {
for (n=0 ; n < col ; n++) {
matrix_definition[n][m] user input
}
}
proses:
matrix_res[n][m] matrix_one[n][m](OPS.AR)matrix_two[n][m]
}
output:
output matrix_res[n][m]
}

Blok input merupakan blok masukan data yang di kehendaki oleh pengguna, dimana
row dan col mewakili inisiasi dari masukan jumlah baris dan kolom. Lalu nilai-m
sama dengan 0 akan dikomparasi dengan nilai row, dimana m mengalami inkremental
dan mendefinisikan pengulangan pada nilai-n sama dengan 0 yang akan di komparasi
dengan nilai col, dimana n akan mengalami inkremental lalu mendefinisikan tiap
inputan pada matrix [n] [m] sesuai data yang di kehendaki.
Blok proses merupakan blok pemrosesan data yang telah di inputkan, mendefinisikan
hasil operasi aritmatika antara matrix_one dan matrix_two yang disimpan di
matrix_res.

25

Blok output merupakan blok keluaran data yang telah di proses sebelumnya,
mendefinisikan hasil output dari matrix_res.
3.2. Memulai pendekatan model menggunakan R
Pada uraian ini kami akan menjelaskan pendekatan melalui data perbandingan
pada sample citra, yang semuanya di lakukan dengan menggunakan bahasa R. Bahasa
R merupakan sebuah open source yang bebas di gunakan siapapun, dikenal luas
sebagai sebuah bahasa yang digunakan untuk perhitungan statistik data.
Penggunaannya hampir dapat di lakukan dari berbagai platform baik itu Windows,
OS X, Linux dan yang lainnya.
Tujuan dari pendekatan ini adalah untuk menunjukan titik kunci kordinat
secara spesifik pada sebuah citra wajah. Sehingga dapat melakukan deteksi wajah
pada sebuah citra. Dari data yang didapat tersebut, kita dapat menentukan bagaimana
sebuah algoritma akan di terapkan pada sebuah Library. Sebelum melakukan
pemodelan ini, kita harus menyiapkan data dan mengunduh file yang di butuhkan
melalui kaggle.com. Kaggle menyediakan file training.zip dan test.zip yang yang
didalamnya ada 7049 contoh citra wajah yang telah di lengkapi dengan lokasi titik
korespondensi. Kami akan menggunakan data tersebut untuk menentukan pendekatan
pada algoritma yang di butuhkan.
File unduhan teresebut mempunyai titik kunci yang dapat diprediksi dan
nilainya ditentukan oleh x, y dengan tipe data real dalam ruang indeks piksel. Ada 15
titik kunci, yang mewakili unsur-unsur wajah, berikut diantaranya:
left_eye_center, right_eye_center, left_eye_inner_corner,
left_eye_outer_corner, right_eye_inner_corner, right_eye_outer_corner,
left_eyebrow_inner_end, left_eyebrow_outer_end, right_eyebrow_inner_end,

26

right_eyebrow_outer_end, nose_tip, mouth_left_corner, mouth_right_corner,


mouth_center_top_lip, mouth_center_bottom_lip
Kiri dan kanan di sini mengacu pada sudut pandang subjek.
Dalam contoh, beberapa posisi sasaran titik kunci yang hilang (dikodekan sebagai
entri hilang dalam csv, yaitu, dengan tanda antara dua koma).
Gambar input diberikan dalam bidang terakhir dari file data, dan terdiri dari daftar
piksel (diperintahkan oleh baris), sebagai bilangan bulat (0255). Foto-foto tersebut
berukuruna 96x96 piksel.
file data:
-

training.csv: Terdapat 7049 gambar untuk melakukan pengujian citra.


Setiap baris berisi koordinat x, y yang memiliki 15 titik kunci dan data
citra sebagai daftar perintah baris piksel.

test.csv: Terdapat 1783 citra uji. Setiap baris ImageId gambar dan
memiliki data citra sebagai daftar daftar perintah baris piksel.

submissionFileFormat.csv: Terdapat 27.124 titik kunci untuk


memprediksi. Setiap baris berisi RowId, ImageId, featurename, Location.
Featurename adalah "left_eye_center_x," "right_eyebrow_outer_end_y," dll
Lokasi adalah kolom customable yang Anda butuhkan untuk
memprediksi.

3.2.1 Membaca Data Pada R


Jika sudah melakukan instalasi R pada perangkat yang digunakan, selanjutnya
membuka Terminal aplikasi dan mengetikan huruf R maka tampilan prompt seperti
di bawah ini akan tampil.

27

R version 2.15.1 (2012-06-22) -- "Roasted Marshmallows" Copyright (C)


2012 The R Foundation for Statistical Computing ISBN 3-900051-07-0
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

R is free

software and comes with ABSOLUTELY NO WARRANTY. You are welcome to


redistribute it under certain conditions. Type 'license()' or
'licence()' for distribution details.
running in an English locale

Natural language support but

R is a collaborative project with many

contributors. Type 'contributors()' for more information and


'citation()' on how to cite R or R packages in publications.

Type

'demo()' for some demos, 'help()' for on-line help, or 'help.start()'


for an HTML browser interface to help. Type 'q()' to quit R.

>

Lalu buat variabel penyimpanan sebagai path default data yang telah di download
tadi.

data.dir

<- '~/data/kaggle/facial_keypoint_detection/' train.file

<- paste0(data.dir, 'training.csv') test.file

<- paste0(data.dir,

'test.csv')

Pada dasarnya format direktori ini dapat diubah sesuai dengan kebutuhan dimana file
akan di simpan.
Untuk melakukan selanjutnya gunakan perintah untuk pembacaan pada data yang
akan di baca.

d.train <- read.csv(train.file, stringsAsFactors=F)

Perintah ini akan membuat sebuah data.frame, yaitu sebuah struktur fundamental
yang terdapat di dalam R. Pada dasarnya data ini akan menampilkan sebuah susunan

28

matriks, seperti yang telah di jelaskan diatas, esensinya sebuah citra mempunyai
derajat keabuan dimana setiap kolomnya mempunyai simpanan data yang berbeda.
Untuk menganalisis data yang terdapat pada file tadi, maka gunakan perintah di
bawah ini.

str(d.train)

'data.frame':

7049 obs. of

31 variables:

left_eye_center_x

: num

66 64.3 65.1 65.2 66.7 ...

left_eye_center_y

: num

39 35 34.9 37.3 39.6 ...

right_eye_center_x

: num

30.2 29.9 30.9 32 32.2 ...

right_eye_center_y

: num

36.4 33.4 34.9 37.3 38 ...

left_eye_inner_corner_x

: num

59.6 58.9 59.4 60 58.6 ...

left_eye_inner_corner_y

: num

39.6 35.3 36.3 39.1 39.6 ...

left_eye_outer_corner_x

: num

73.1 70.7 71 72.3 72.5 ...

left_eye_outer_corner_y

: num

40 36.2 36.3 38.4 39.9 ...

right_eye_inner_corner_x : num

36.4 36 37.7 37.6 37 ...

right_eye_inner_corner_y : num

37.4 34.4 36.3 38.8 39.1 ...

right_eye_outer_corner_x : num

23.5 24.5 25 25.3 22.5 ...

right_eye_outer_corner_y : num

37.4 33.1 36.6 38 38.3 ...

left_eyebrow_inner_end_x : num

57 54 55.7 56.4 57.2 ...

left_eyebrow_inner_end_y : num

29 28.3 27.6 30.9 30.7 ...

left_eyebrow_outer_end_x : num

80.2 78.6 78.9 77.9 77.8 ...

left_eyebrow_outer_end_y : num

32.2 30.4 32.7 31.7 31.7 ...

right_eyebrow_inner_end_x: num

40.2 42.7 42.2 41.7 38 ...

right_eyebrow_inner_end_y: num

29 26.1 28.1 31 30.9 ...

right_eyebrow_outer_end_x: num

16.4 16.9 16.8 20.5 15.9 ...

right_eyebrow_outer_end_y: num

29.6 27.1 32.1 29.9 30.7 ...

nose_tip_x

: num

44.4 48.2 47.6 51.9 43.3 ...

nose_tip_y

: num

57.1 55.7 53.5 54.2 64.9 ...

mouth_left_corner_x

: num

61.2 56.4 60.8 65.6 60.7 ...

$
$

$
$

$
$

29

mouth_left_corner_y

: num

80 76.4 73 72.7 77.5 ...

mouth_right_corner_x

: num

28.6 35.1 33.7 37.2 31.2 ...

mouth_right_corner_y

: num

77.4 76 72.7 74.2 77 ...

mouth_center_top_lip_x

: num

43.3 46.7 47.3 50.3 45 ...

mouth_center_top_lip_y

: num

72.9 70.3 70.2 70.1 73.7 ...

mouth_center_bottom_lip_x: num

43.1 45.5 47.3 51.6 44.2 ...

mouth_center_bottom_lip_y: num

84.5 85.5 78.7 78.3 86.9 ...

$ Image

: chr

$
$

$
$

"238 236 237 238 240 240 239 241 241 243 240 239 231 ...

Pada contoh di atas, dalam daftar nama kolom. R akan memperlihatkan beberapa
inisiasi data yang diikuti dengan penamaan kolom jenis, lalu kemudian diikuti
beberapa nilai data pertama pada kolom. Sebagai contoh, kolom pertama (atau
variabel) dalam frame data d.train bernama left_eye_center_x. Ini berisi nilai
numerik, dan dua nilai pertamanya adalah 66 dan 64,3.
Secara keseluruhan, data yang di disiapkan oleh kaggle tersebut memiliki 7049 baris,
masing-masing dengan 31 kolom. Yang pertama 30 kolom lokasi titik kunci dan
diidentifikasi oleh R sebagai data angka. Yang terakhir adalah representasi string dari
gambar, yang diidentifikasi sebagai string. Kolom terakhir ini adalah alias untuk
argumen stringsAsFactors: jika Anda menghilangkan simbol tersebut, R akan
menganggap kolom tersebut sebagai kategori.
Untuk mendapatkan bantuan pada sintaks dari setiap perintah dalam R cukup
tambahkan simbol tanda tanya (?). Sebagai contoh:

?read.csv

Perintah tersebut akan membuka deskripsi dari perintah yang di maksudkan dan akan
memperlihatkan juga beberapa parameter yang kita harapkan. Anda dapat keluar dari

30

jendela deskripsi dengan cepat hanya dengan menekan tombol q. Maka Anda akan
keluar secara otomatis.
Kembali kepada data yang di perlukan. Gunakan perintah head untuk menampilkan
data yang lebih spesifik.

head(d.train)

Sayangnya kolom paling kanan cukup panjang, sehingga output sangat tidak mudah
dibaca. Untuk itu kita akan menyimpan kolom dalam

variabel lain, dan

menghapusnya dari d.train.

im.train

<- d.train$Image d.train$Image <- NULL

Pada baris pertama, kita menetapkan variabel im.train, maka nilai-nilai dari
d.train$Image akan menginisiasi perintah tersebut. Seperti yang Anda lihat, R
menyediakan fungsi untuk penggunanya dengan cara yang mudah dalam
mengidentifikasi kolom yang ingin kita tampilkan dari berbagai kolom dataframe.
Kemudian menetapkan NULL untuk menghapus kolom sebelumnya dari dataframe
tersebut. Sekarang mari kita coba perintah head kembali.

head(d.train)

left_eye_center_x left_eye_center_y

right_eye_center_x

30.22701 2

64.33294

3
65.22574
39.62126

65.05705

66.03356

34.90964

37.26177
32.24481 6

39.00227

34.97008

29.94928
30.90379 4

32.02310 5

66.72530

69.68075

39.96875

29.18355

31

Seperti yang Anda lihat ada satu kolom untuk setiap titik kunci, dan satu baris untuk
masing-masing gambar. Sekarang, mari kita lihat kolom kami pindah ke im.train.
Untuk setiap gambar (yaitu di setiap baris) berisi string panjang angka, di mana setiap
angka menunjukkan intensitas pixel dalam gambar. Mari kita melihat nilai pertama
dalam kolom:

im.train[1]

[1] "238 236 237 238 240 240 239 241 241 243 240

Untuk menganalisa lebih jauh, kita akan mengubah string tersebuk ke bilangan bulat
dengan memisahkan mereka dan mengubah hasilnya ke integer:

as.integer(unlist(strsplit(im.train[1], " ")))

[1] 238 236 237 238

240 240 239 241 241 243 240

strsplit berfungsi untuk membagi string, sedangkan unlist akan menyederhanakan


output-nya ke vektor string andas.integer untuk mengkonversinya menjadi vektor dari
integer. Agar bekerja dengan baik, kita perlu melakukannya untuk semua gambar, dan
bukan hanya yang pertama. Kita bisa melakukan perulangan melalui setiap record
dalam im.train dan menerapkan string ke bilangan bulat pada konversi di atas.
Namun, secara berurutan pengolahan konversi ini dapat memakan waktu. Oleh karena
itu kita dapat memanfaatkan pendekatan multi inti menggunakan perpustakaan doMC
(Hanya tersedia untuk Linux dan OS X - jika Anda bekerja menggunakan Windows
silahkan mencari library alternatif).
Pertama, kita harus menginstal library yang di perlukan dengan perintah ini sebagai
berikut:

32

install.packages('doMC')

Setelah memilih mirror CRAN maka secara otomatis instalasi akan dilakukan.
Selanjutnya, kita perlu memuat library yang telah di unduh lalu mendaftarkannya

library(doMC) registerDoMC()

Sekarang kita siap untuk menerapkan paralelisasi tersebut.

im.train <- foreach(im = im.train, .combine=rbind) %dopar% {


as.integer(unlist(strsplit(im, " "))) }

Untuk setiap masing-masing loop akan akan mengevaluasi perintah pada setiap baris
dalam im.train, dan menggabungkan hasilnya dengan rbind (menggabungkan dengan
baris). %dopar% menginstruksikan R untuk melakukan semua evaluasi secara paralel.
im.train sekarang mempunyai data matriks dengan 7049 baris (satu untuk setiap
gambar) dan 9216 kolom (satu untuk setiap pixel).

str(im.train)
164 226 ...

int [1:7049, 1:9216] 238 219 144 193 147 167 109 178
- attr(*, "dimnames")=List of 2

"result.1" "result.2" "result.3" "result.4" ...

..$ : chr [1:7049]


..$ : NULL

Ulangi proses untuk test.csv, karena kita akan membutuhkannya nanti. Perhatikan
bahwa dalam file tes, kita tidak memiliki nilai pada 30 kolom pertama dengan lokasi
titik kunci.

33

d.test

<- read.csv(test.file, stringsAsFactors=F) im.test <-

foreach(im = d.test$Image, .combine=rbind) %dopar% {


as.integer(unlist(strsplit(im, " "))) } d.test$Image <- NULL

Ini merupakan ide yang baik untuk menyimpan data sebagai data file pada R saat ini,
sehingga Anda tidak harus mengulangi proses ini lagi. Karena dengan proses ini
pengguna dapat menyimpan semua empat variabel ke file data.Rd:

save(d.train, im.train, d.test, im.test, file='data.Rd')

Kita dapat melakukan perintah reload jika suatu saat data tersebut akan di
butuhkan, berikut perintahnya:

load('data.Rd')

3.2.2 Algoritma dengan variabel titik kunci pada data citra dengan R
Sekarang data akan dimuat, perhatikan gambar yang ada. Apakah Anda
perhatikan bagaimana string panjang tersebut terdiri dari 9216 bilangan bulat? Itu
karena masing-masing gambar adalah vektor dari 96 x 96 piksel (96 x 96 = 9216).
Untuk memvisualisasikan setiap gambar, dengan demikian kita harus terlebih dahulu
mengubah 9216 bilangan bulat tersebut menjadi matriks 96 x 96.

im <- matrix(data=rev(im.train[1,]), nrow=96, ncol=96)

im.train[1,] mengembalikan baris pertama dari data im.train, dimana korespondensi


dari file gambar di reverse sehingga menghasilkan vector yang cocok dengan

34

intreprestasi dari fungsi citra pada R. Untuk memvisualisasi gambar maka pengguna
dapat menggunakan fungsi citra pada R.

image(1:96, 1:96, im, col=gray((0:255)/255))

Gambar 3.2.2.1. Visualiasi citra dari data citra menggunakan fungsi image pada R

Setelah itu pengguna dapat menambahkan titik kunci (menambahkannya nilai pada 30
kolom pertama pada file) untuk melakukan pengecekan bahwa sejauh ini langkah
yang sudah dilakukan benar (disini, sekali lagi, pengguna membutuhkan
menambahkan data kordinat berbeda dari data kordinat sebelumnya). Warnai setiap
kordinat pada hidung dan mata.

points(96-d.train$nose_tip_x[1],

96-d.train$nose_tip_y[1],

col="red") points(96-d.train$left_eye_center_x[1],

96-

35

d.train$left_eye_center_y[1],

col="blue") points(96-

d.train$right_eye_center_x[1], 96-d.train$right_eye_center_y[1],
col="green")

Gambar 3.2.2.2. Menentukan kordinat titik kunci pada hidung dan mata.

Untuk mengecek dengan langkah terbaik, maka selalu perhatikan data variabel yang
ada. Sebagai contoh, di manakah pusat dari masing-masing hidung pada 7049 gambar
tadi? (proses ini memerlukan waktu untuk dijalankan):

for(i in 1:nrow(d.train)) {

points(96-d.train$nose_tip_x[i], 96-

d.train$nose_tip_y[i], col="red") }

36

Gambar 3.2.2.3. Generate lokasi titik kunci di wilayah tengah

Kebanyakan titik hidung terkonsentrasi di wilayah tengah (seperti yang diharapkan),


tetapi ada beberapa outlier yang harus di selidiki lebih lanjut, karena bisa saja data
tersebut mengandung label kesalahan. Melihat salah satu contoh ekstrim yang tejadi
seperti di bawah ini:

idx <- which.max(d.train$nose_tip_x) im

<-

matrix(data=rev(im.train[idx,]), nrow=96, ncol=96) image(1:96, 1:96,


im, col=gray((0:255)/255)) points(96-d.train$nose_tip_x[idx], 96d.train$nose_tip_y[idx], col="red")

37

Gambar 3.2.2.4. Label kesalahan penentuan kordinat titik kunci pada wilayah tengah

Dalam hal ini tidak ada kesalahan pelabelan, tapi ini menunjukkan bahwa tidak semua
wajah yang terpusat seperti yang diharapkan. Ada banyak lagi yang dapat dianalisis,
tapi mari kita mulai membangun pendekatan algoritma dari hal tersebut.
3.2.3 Algoritma dengan Benchmark sederhana dengan R
Salah satu hal yang paling sederhana untuk di coba adalah menghitung rata-rata dari
koordinat masing-masing titik kunci pada training set dan menggunakannya sebagai
prediksi untuk semua gambar. Ini adalah algoritma yang sangat sederhana, karena
sama sekali mengabaikan gambar, tapi pengguna dapat menggunakannya sebagai titik
awal untuk membangun sebuah pendekatan model pertama.
Menghitung rata-rata untuk setiap kolom sangat mudah, yaitu dengan perintah
colMeans (na.rm = Ttells colMeans untuk mengabaikan nilai-nilai yang hilang).

38

Maka akan mendapatkan nilai berikut:

colMeans(d.train, na.rm=T)
left_eye_center_y

left_eye_center_x

right_eye_center_x

66.35902

37.65123

right_eye_center_y

30.30610

left_eye_inner_corner_x

left_eye_inner_corner_y
59.15934

37.97694
37.94475

left_eye_outer_corner_y

left_eye_outer_corner_x

right_eye_inner_corner_x

73.33048

37.70701

right_eye_inner_corner_y

right_eye_outer_corner_x

right_eye_outer_corner_y

36.65261

37.98990

22.38450

38.03350

left_eyebrow_inner_end_x

left_eyebrow_inner_end_y

left_eyebrow_outer_end_x

56.06851

29.33268

79.48283

left_eyebrow_outer_end_y right_eyebrow_inner_end_x
right_eyebrow_inner_end_y
39.32214

29.73486
29.50300

right_eyebrow_outer_end_y
15.87118
nose_tip_y

right_eyebrow_outer_end_x
nose_tip_x

30.42817
mouth_left_corner_x

48.37419
mouth_left_corner_y

62.71588

63.28574

mouth_right_corner_x

mouth_right_corner_y

mouth_center_top_lip_x
76.17977

75.97071

32.90040
47.97541

mouth_center_top_lip_y

mouth_center_bottom_lip_x mouth_center_bottom_lip_y
72.91944

48.56947

78.97015

Untuk membangun sebuah file pengajuan kita perlu menerapkan koordinat ini
dihitung dengan contoh uji:

39

p <- matrix(data=colMeans(d.train, na.rm=T), nrow=nrow(d.test),


ncol=ncol(d.train), byrow=T) colnames(p) <- names(d.train)
predictions <- data.frame(ImageId = 1:nrow(d.test), p)
head(predictions)

ImageId left_eye_center_x left_eye_center_y

right_eye_center_x 1

66.35902

37.65123

30.3061 2

66.35902

37.65123

30.3061 3

66.35902

37.65123

30.3061 4

66.35902

37.65123

30.3061 5

66.35902

37.65123

30.3061 6

66.35902

37.65123

30.3061

Format yang diharapkan memiliki masing-masing satu titik kunci per barisnya, untuk
mendapatkannya kita dapat menggunakan bantuan library dari reshape2:

install.packages('reshape2') library(reshape2) submission <melt(predictions, id.vars="ImageId", variable.name="FeatureName",


value.name="Location") head(submission)
Location 1

ImageId

1 left_eye_center_x 66.35902 2

left_eye_center_x 66.35902 3
4 left_eye_center_x 66.35902 5

FeatureName
2

3 left_eye_center_x 66.35902 4
5 left_eye_center_x 66.35902 6

6 left_eye_center_x 66.35902

Pengguna dapat menggabungkan data dengan file pengajuan sampel untuk mengatur
urutan yang sama hasil entri lalu menyimpan hasilnya:

example.submission <- read.csv(paste0(data.dir,


'submissionFileFormat.csv')) sub.col.names

<-

40

names(example.submission) example.submission$Location <- NULL


submission <- merge(example.submission, submission, all.x=T, sort=F)
submission <- submission[, sub.col.names] write.csv(submission,
file="submission_means.csv", quote=F, row.names=F)

3.2.4. Algoritma dengan penggunakan patch gambar dengan R


Metode di atas memang terlalu sederhana, dan tidak menganalisis gambar sama
sekali. Dengan kata lain, kita tidak menggunakan informasi mengenai intensitas setiap
pixel untuk mengidentifikasi titik kunci.
Mari kita mencoba untuk membangun suatu algoritma yang menggunakan
kelimpahan data yang ada. Untuk mempermudah pertama, langkah pertama akan
fokus pada titik kunci tunggal: left_eye_center.
Idenya adalah untuk mengekstrak patch di sekitar titik kunci pada setiap gambar, dan
menghitung rata-rata hasilnya. Average_patch ini kemudian dapat digunakan sebagai
masker untuk mencari titik kunci pada citra uji.
Memulai mendefinisikan beberapa parameter:

coord

<- "left_eye_center" patch_size <- 10

coord adalah titik kunci yang akan dikerjakan, dan patch_size adalah jumlah piksel
yang akan mengekstrak di setiap arah pada pusat titik kunci tersebut. Nilai 10
merepresentasi panjangnya persegi 21x21 piksel (10 +1 +10).
Lihat proses di bawah ini untuk lebih jelas:

41

coord_x <- paste(coord, "x", sep="_") coord_y <- paste(coord, "y",


sep="_") patches <- foreach (i = 1:nrow(d.train), .combine=rbind)
%do% {

im

<- matrix(data = im.train[i,], nrow=96, ncol=96)

<- d.train[i, coord_x]


patch_size)
y2

x2

<- d.train[i, coord_y]

<- (x+patch_size)

<- (y+patch_size)

y1

x1

<- (x-

<- (y-patch_size)

if ( (!is.na(x)) && (!is.na(y)) && (x1>=1)

&& (x2<=96) && (y1>=1) && (y2<=96) )


as.vector(im[x1:x2, y1:y2])

{
else

NULL

} }

mean.patch <- matrix(data = colMeans(patches), nrow=2*patch_size+1,


ncol=2*patch_size+1)

Setiap loop ini akan mendapatkan masing-masing gambar dan:


-

Ekstrak koordinat keypoint: x dan y

Hasil penghitungan koordinat patch: x1, y1, x2 dan y2

Lalu memeriksa apakah koordinat tersebut tersedia (is.na) dan berada di dalam
gambar. Jika ya, maka patch citra sebagai vektor; Jika tidak, kembali ke
NULL.
Semua vektor non-NULL kemudian akan dikombinasikan dengan Rbind, lalu

merangkai mereka sebagai baris. Hasil patch akan menjadi matriks di mana setiap
baris adalah patch dari suatu gambar. Pengguna kemudian dapat menghitung rata-rata
dari semua gambar dengan menggunakan colMeans, dimasukkan kembali dalam
format matriks dan simpan di mean.patch.
Anda kemudian dapat memvisualisasikan hasilnya dengan perintah image:
image(1:21, 1:21, mean.patch[21:1,21:1], col=gray((0:255)/255))

42

Gambar 3.2.3.1. Patch citra mata

Maka akan terlihat citra mata. Ini adalah mata kiri hasil penghitungan dengan rata-rata
dari seluruh gambar yang 7049.
Sekarang pengguna dapat menggunakan average_patch ini untuk mencari titik kunci
yang sama dalam citra uji. Langkah pertama adalah mendefinisikan parameter lain:

search_size <- 2

search_size menunjukkan banyaknya rentang piksel yang akan dicari titik kuncinya.
Dalam proses ini, akan pencarian akan dipusatkan pada rata-rata lokasi titik kunci,
pada titik nilai piksel search_size di setiap arah:

mean_x <- mean(d.train[, coord_x], na.rm=T) mean_y <- mean(d.train[,


coord_y], na.rm=T) x1

<- as.integer(mean_x)-search_size x2

<-

43

as.integer(mean_x)+search_size y1
search_size y2

<- as.integer(mean_y)-

<- as.integer(mean_y)+search_size

Dalam kasus ini pencarian akan dimulai dari rentang (64,35) ke (68,39). Kita bisa
menggunakan expand.grid untuk membangun sebuah data frame dengan semua
kombinasi x dan y itu:

params <- expand.grid(x = x1:x2, y = y1:y2) params


2

65 35 3

66 35 4

67 35 5

68 35 6

64 36 7

65 36 8

y 1

64 35

66 36 9

67

36 10 68 36 11 64 37 12 65 37 13 66 37 14 67 37 15 68 37 16 64 38 17
65 38 18 66 38 19 67 38 20 68 38 21 64 39 22 65 39 23 66 39 24 67 39
25 68 39

Mengingat citra uji, pengguna perlu mencoba semua kombinasi ini, dan melihat mana
average_patch yang tepat untuk digunakan pada proses tersebut. Pada proses
selanjutnya akan dilakukan pegambilan pada patch dari citra uji di sekitar titik-titik
tersebut, lalu mengukur korelasinya dengan average_patch tersebut.
Ambil gambar tes pertama sebagai contoh:

im <- matrix(data = im.test[1,], nrow=96, ncol=96)

1:nrow(params), .combine=rbind) %dopar% {

<- params$x[j]

<- params$y[j]

<- im[(x-patch_size):(x+patch_size),

(y-patch_size):(y+patch_size)]
as.vector(mean.patch))

<- foreach(j =

score <- cor(as.vector(p),

score <- ifelse(is.na(score), 0, score)

data.frame(x, y, score) }

Di dalam proses loop, mengingat koordinatnya, maka proses selanjutnya adalah


mengekstrak patch gambar p dan membandingkannya dengan average_patch dengan

44

cor. Kondisi If else ini diperlukan untuk kasus-kasus di mana semua piksel Patch
pada citra memiliki intensitas yang sama, seperti dalam kasus ini cor kembali NA.
Hasilnya akan terlihat seperti ini:

0.1376269 4

score 1

64 35 0.1017430 2

67 35 0.1351847 5

65 36 0.2884035 8

65 35 0.1198157 3

68 35 0.1119015 6

66 36 0.2923847 9

66 35

64 36 0.2769096 7

67 36 0.2741814 10 68 36

0.2333830 11 64 37 0.4410122 12 65 37 0.4560440 13 66 37 0.4520532 14


67 37 0.4189839 15 68 37 0.3632465 16 64 38 0.5559125 17 65 38
0.5715887 18 66 38 0.5675701 19 67 38 0.5317430 20 68 38 0.4711673 21
64 39 0.6115627 22 65 39 0.6131023 23 66 39 0.6063069 24 67 39
0.5794715 25 68 39 0.5276036

Sekarang semua yang perlu di lakukan adalah mengembalikan koordinat dengan nilai
tertinggi:

best <- r[which.max(r$score), c("x", "y")] best

y 22 65 39

3.2.5. Algoritma eksperimental dengan R


Pada algoritma eksperimental ini kami akan mencoba pendekatan model yang
customable. Proses ini sangat mudah, yaitu mengganti blok kode yang ada di bawah:

d.train

<- read.csv(train.file, stringsAsFactors=F) d.test

read.csv(test.file,

stringsAsFactors=F) im.train

<-

<- foreach(im =

d.train$Image, .combine=rbind) %dopar% {


as.integer(unlist(strsplit(im, " "))) } im.test

<- foreach(im =

d.test$Image, .combine=rbind) %dopar% {

45

as.integer(unlist(strsplit(im, " "))) } d.train$Image <- NULL


d.test$Image

<- NULL

dengan ini:

<- read.csv(train.file, stringsAsFactors=F) im <- foreach(im =

d$Image, .combine=rbind) %dopar% {

as.integer(unlist(strsplit(im,

" "))) } d$Image <- NULL set.seed(0) idxs


nrow(d)*0.8) d.train
im[idxs,] im.test

<- d[idxs, ] d.test

<- sample(nrow(d),
<- d[-idxs, ] im.train <-

<- im[-idxs,] rm("d", "im")

Blok kode ini ditujukan untuk melakukan perbaikan pada pseudo random number
untuk menghasilkan bilangan tetap yang seksama, sehingga di kemudian hari Anda
dapat mereproduksi hal tersebut dengan hasil yang akurat jika diperlukan. Blok kode
yang lainnya tetap sama.

p <- matrix(data=colMeans(d.train, na.rm=T), nrow=nrow(d.test),


ncol=ncol(d.train), byrow=T)

Setelah Anda memiliki prediksi yang tepat, Anda kemudian dapat menghitung hasil
RMSE pada set pengujiannya:

sqrt(mean((d.test-p)^2, na.rm=T))

[1] 3.758999

46

3.3. Perancangan penggunaan tapis pada Library Constraint Local Models


(CLM)
Keakuratan dalam mengukur lokasi fitur wajah merupakan langkah penting
dalam banyak algoritma pengenalan wajah. Setiap wajah yang unik yang berarti
lokalisasi harus toleran terhadap perbedaan antara subyek individu. Selain itu,
mengubah pencahayaan, fokus, dan deformasi karena perubahan ekspresi
memperumit masalah. Pada library CLMTRacker di implementasi sebuah metode
untuk mencari fitur wajah yang menggunakan output Minimum Sum Squared Error
(MOSSE) yaitu korelasi tapis untuk penampilan obyek dan dikombinasikan dengan
Robust Active Shape Model (ASM) untuk diterapkan pada model geometri wajah.
Hal ini menunjukkan bahwa korelasi tapis MOSSE mengungguli STASM (sebuah
implementasi open source ASM), Gabor Jets dan dalam beberapa kasus bahkan
melebihi mekanisme pengenalan wajah oleh kinerja natural mata manusia.

3.3.1. Tapis Korelasi MOSSE


Parameter constructor yang digunakan:
-

DrawResponse {canvasElement} : menarik output tapis korelasi pada elemen


kanvas yang diberikan (default adalah none)

PsrThreshold {number}: ambang puncak titik rasio yang digunakan ketika


memperbarui pelacakan tapis sementara (default adalah 10).

eta {number}: menyesuaikan berapa banyak masukan baru mempengaruhi


tapis MOSSE, ketika memperbarui pelacakan tapis sementara

Number harus antara 0 dan 1 (default adalah 0.1)

47

ConvertToGrayscale {boolean}: mengubah output kanvas untuk menjadi tipe


grayscale (default adalah true) . Jika ini diatur ke false, dapat di asumsikan
semua channel mempunyai nilai yang sama dan hanya akan mengambil nilai
dari channel merah.

Implementasi pada blok kode:


[Lihat Lampiran Blok Kode 1]

3.3.2. Transformasi Fourier Cepat


Transformasi Fourier cepat (biasa disingkat FFT) adalah suatu algoritma
untuk menghitung transformasi Fourier diskrit (Bahasa Inggris: Discrete Fourier
Transform, DFT) dengan cepat dan efisien. Transformasi Fourier Cepat diterapkan
dalam beragam bidang, mulai dari pengolahan sinyal digital, memecahkan persamaan
diferensial parsial, dan untuk algoritma untuk mengalikan bilangan bulat besar.
Misalkan ''x0, ...., xN-1 merupakan bilangan kompleks. Transformasi Fourier Diskret
didefinisikan oleh rumus:

Menghitung deret ini secara langsung memerlukan operasi aritmetika


sebanyak O(N2). Sebuah algoritma FFT hanya memerlukan operasi sebanyak O(N log
N) untuk menghitung deret yang sama. Secara umum algoritma tersebut tergantung
pada pemfaktoran N.

48

Setiap algoritma FFT, dengan penyesuaian, dapat diterapkan pula untuk


menghitung DFT invers. Ini karena DFT invers adalah sama dengan DFT, namun
dengan tanda eksponen berlawanan dan dikalikan dengan faktor 1/N.

Implementasi pada blok kode:


[Lihat Lampiran Blok Kode 2]

3.3.3. Tracker Titik Kunci (Keypoints)


Kode pemrograman ini dibuat unutuk merepresentasi model trek wajah
dengan output berupa gabungan verteks dengan posisi koordinat dari model wajah
sebagai array, verteks tersebut menghasilkan untaian garis yang saling membentuk
melingkari wajah.
Implementasi pada blok kode:
/*
*

starts the tracker to run on a regular interval

*/
this.start = function(element, box) {
// check if model is initalized, else return false
if (typeof(model) === "undefined") {
console.log("tracker needs to be initalized
before starting to track.");
return false;
}
//check if a runnerelement already exists, if not,
use passed parameters
if (typeof(runnerElement) === "undefined") {

49

runnerElement = element;
runnerBox = box;
}
// start named timeout function
runnerTimeout = requestAnimFrame(runnerFunction);
}

/*
*

stop the running tracker

*/
this.stop = function() {
// stop the running tracker if any exists
cancelRequestAnimFrame(runnerTimeout);
}

3.3.4. Implementasi Eigenvalues dan Eigenvector


Yang dimaksud dengan eigenvalue adalah sebuah bilangan skalar dan
eigenvector adalah sebuah matriks yang keduanya dapat mendifinisikan matriks A.
Dimana matriks A adalah matriks bujur sangkar dengan ukuran nxn. Namun, tidak
semua matriks bujur sangkar memiliki eigenvalue dan eigenvector. Untuk lebih
jelasnya, perhatikan ilustrasi berikut:
Untuk contoh pertama, terdapat sebuah matriks A dengan ukuran 2x2:

50

dan sebuah matriks (atau vektor) :

Catatan:
1. Jumlah eigenvalue yang tidak sama dengan nol pada matriks A adalah jumlah
rank matriks tersebut. Dari contoh di atas dapat dilihat bahwa rank dari
matriks A adalah 2 (eigenvalue yang tidak sama dengan nol ada 2)
2. Bila salah satu eigenvalue = 0, maka rank (A) = n-1
3. Bila rank (A) = n, disebut full rank, maka A adalah matriks non_singular (bisa
dibuktikan dengan determinan (A) tidak sama dengan 0) dan vektor-vektornya
disebut linearly independent/berdiri sendiri/bukan kelipatan dari vektor lain
dalam matriks tersebut.

3.3.5. Implementasi Jacobian Matriks


Metode Iterasi Jacobi merupakan salah satu bidang analisis numerik yang
digunakan untuk menyelesaikan permasalahan persamaan linear dan sering dijumpai
dalam berbagai disiplin ilmu. Metode Iterasi Jacobi merupakan salah satu metode tak
langsung, yaitu bermula dari suatu hampiran penyelesaian awal dan kemudian
berusaha memperbaiki hampiran dalam tak berhingga namun langkah konvergen.
Metode Iterasi Jacobi ini digunakan untuk menyelesaikan persamaan linear berukuran
besar dan proporsi koefisien nolnya besar.
Implementasi pada blok kode:
[Lihat Lampiran Blok Kode 3]

51

BAB IV
IMPLEMENTASI PROGRAM

4.1. Implementasi pada WebGL


CLMTrackr adalah sebuah library javascript yang digunakan untuk mengenali
pemindaian model wajah pada sebuah citra atau video. Library ini merupakan
pemodelan matematika dari Constrained Local Models dengan dasar pendekatan dari
metode regularized landmark mean-shift, seperti yang telah di jelaskan pada paper
Jason M. Saragih yang berjudul Deformable Model Fitting by Regularized
Landmark Mean-Shift. CLMTrackr merepresentasi trek wajah dengan output
berupa gabungan verteks dengan posisi koordinat dari model wajah sebagai array,
verteks tersebut menghasilkan untaian garis yang saling membentuk melingkari
wajah, untuk lebih jelas lihat penomoran dari model di bawah ini:

Gambar 4.1.1. Kordinat Penomoran CLMTracker

52

Library ini menyediakan beberapa model wajah umum yang di training pada database
MUCT. Penggunaan library ini membutuhkan jsfeat.js (untuk deteksi wajah awal)
dan numeric.js (untuk matriks matematika).
Untuk pelacakan video, dianjurkan untuk menggunakan browser dengan
dukungan WebGL, karena library ini hanya dapat bekerja pada browser modern.

4.1.1. Implementasi Constraint Local Models pada gambar


Input :
test_bumper.jpg

Membutuhkan:
<script src="./ext_js/utils.js"></script>
<script src="./ext_js/dat.gui.min.js"></script>
<script src="./ext_js/jsfeat-min.js"></script>
<script src="./ext_js/frontalface.js"></script>
<script src="./ext_js/jsfeat_detect.js"></script>
<script src="./ext_js/numeric-1.2.6.min.js"></script>
<script src="./ext_js/mosse.js"></script>
<script src="./ext_js/left_eye_filter.js"></script>
<script src="./ext_js/right_eye_filter.js"></script>
<script src="./ext_js/nose_filter.js"></script>
<script src="../models/model_pca_20_svm.js"></script>
<script src="../js/clm.js"></script>
<script src="../js/svmfilter_webgl.js"></script>
<script src="../js/svmfilter_fft.js"></script>
<script src="../js/mossefilter.js"></script>
<script src="./ext_js/Stats.js"></script>
<link rel="stylesheet" type="text/css" href="./styles/imgareaselectdefault.css" />
<script src="./ext_js/jquery.min.js"></script>
<script src="./ext_js/jquery.imgareaselect.pack.js"></script>
<script src="./ext_js/BlobBuilder.min.js"></script>
<script src="./ext_js/Filesaver.min.js"></script>

53

Proses :
[Lihat Lampiran Blok Kode 4]
Output :

4.1.2. Substitusi Wajah


Input :
Real Time Video via Webcam.
Membutuhkan:
<script
<script
<script
<script
<script
<script
<script
<script

src="../js/dat.gui.min.js"></script>
src="../js/utils.js"></script>
src="../js/clmtrackr.js"></script>
src="../models/model_pca_20_svm.js"></script>
src="../js/Stats.js"></script>
src="../js/face_deformer.js"></script>
src="../js/jquery.min.js"></script>
src="./js/poisson_new.js"></script>

Proses :
[Lihat Lampiran Blok Kode 5]

54

Output :

4.1.3. Masking Wajah


Input :
Real Time Video via Webcam.
Membutuhkan:
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script

src="./ext_js/dat.gui.min.js"></script>
src="./ext_js/utils.js"></script>
src="./ext_js/jsfeat-min.js"></script>
src="./ext_js/frontalface.js"></script>
src="./ext_js/jsfeat_detect.js"></script>
src="./ext_js/numeric-1.2.6.min.js"></script>
src="./ext_js/mosse.js"></script>
src="./ext_js/left_eye_filter.js"></script>
src="./ext_js/right_eye_filter.js"></script>
src="./ext_js/nose_filter.js"></script>
src="../models/model_pca_20_svm.js"></script>
src="../js/clm.js"></script>
src="../js/svmfilter_webgl.js"></script>
src="../js/svmfilter_fft.js"></script>
src="../js/mossefilter.js"></script>
src="./ext_js/Stats.js"></script>
src="../js/face_deformer.js"></script>

55

Proses :
[Lihat Lampiran Blok Kode 6]
Output :

4.1.4. Deformasi Realtime Wajah


Input :
Real Time Video via Webcam.
Membutuhkan:
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script
<script

src="./ext_js/dat.gui.min.js"></script>
src="./ext_js/utils.js"></script>
src="./ext_js/jsfeat-min.js"></script>
src="./ext_js/frontalface.js"></script>
src="./ext_js/jsfeat_detect.js"></script>
src="./ext_js/numeric-1.2.6.min.js"></script>
src="./ext_js/mosse.js"></script>
src="./ext_js/left_eye_filter.js"></script>
src="./ext_js/right_eye_filter.js"></script>
src="./ext_js/nose_filter.js"></script>
src="../models/model_pca_20_svm.js"></script>
src="../js/clm.js"></script>
src="../js/svmfilter_webgl.js"></script>
src="../js/svmfilter_fft.js"></script>
src="../js/mossefilter.js"></script>
src="./ext_js/Stats.js"></script>
src="../js/face_deformer.js"></script>

Proses :
[Lihat Lampiran Blok Kode 7]

56

Output :

4.1.4. Deteksi Emosi Wajah


Input :
Real Time Video via Webcam.
Membutuhkan:
<script src="../js/utils.js"></script>
<script src="../js/clmtrackr.js"></script>
<script
src="../models/model_pca_20_svm_emotionDetection.js"></script>
<script src="../js/Stats.js"></script>
<script src="./js/d3.min.js"></script>
<script src="./js/emotion_classifier.js"></script>
<script src="./js/emotionmodel.js"></script>

Proses :
[Lihat Lampiran Blok Kode 8]

57

Output :

58

BAB V
SIMPULAN DAN SARAN

Pada BAB terakhir ini diuraikan mengenai kesimpulan yang dapat ditarik dari
pengerjaan penulisan ini. Selain itu juga diuraikan mengenai saran-saran yang dapat
diperhatikan untuk pengembangan selanjutnya.

5.1. Kesimpulan
Kesimpulan yang diperoleh berdasarkan ujicoba dan analisa hasil yang telah
dilakukan adalah sebagai berikut :
1. Deteksi wajah dapat dilakukan dengan menggunakan metode Constraint Local
Models, dimana akurasi didapatkan sebesar 86%.
2. Skala citra wajah bisa mempengaruhi hasil dari deteksi wajah.
3. Deteksi fitur wajah dengan histogram proyeksi mampu mencapai akurasi 77%,
namun metode ini tidak mampu mengatasi masalah intensitas cahaya.

5.2. Saran
Beberapa saran yang hendak disampaikan terkait dengan pengerjaan tugas
akhir ini adalah sebagai berikut:
1. Dikembangkan suatu metode paling optimal untuk ekstraksi fitur Wajah.
2. Diperlukan algoritma untuk dapat mendeteksi posisi fitur wajah dengan
kemiringan hampir 90 derajat.

59

(halaman ini dibiarkan kosong)

60

DAFTAR PUSTAKA
[1]

[2]

[3]
[4]

[5]
[6]
[7]

[8]

[9]

Bahlmann, C., Bernard Haasdonk, and Hans Burkhardt.,


2002. Online hand writing recognition using support
vector machines a kernel approch. Niagara-on-the-Lake,
In Int. Workshop on Frontiers in Hadwriting Recognition.
Bennett, K.P., D.H. WU, and L. Auslender., 1998. On
Support Vector Decission Trees for Database Marketing.
New York. Technical report, Rensselaer Polytechnic
Institute.
Bertsekas, Dimitri P., 1999. Nonlinear programming.
Athena scientific; 2nd edition.
Brown, M., Grundy, W., Lin, D., Christianini, N., Sugnet,
C. , Jr, M., and Haussler, D., 1999. Support vector
machines classification of microarry gene expression data.
Technical support UCSC CRL 99-09, University
California Santa Cruz, Departemen of Computer Science,
California, USA.
Cortes, C., and Vapnik, V., 1995. Support-vector
networks. Machine Learning 273-297.
Drucker, H., Wu, D., andVapnik, V.N., 1999. Support
vector machines for spam categorization. IEEE
Transaction on Neural Network, 10(5):1048-1054.
Dumais, A., Plat, J., Heckerman, D., and Sahami, M., 1998.
Inductive learning algoritms and representation for text
categorization. CIKM-98, 7th ACM International
Conference on Information and Knowledge Management,
148-155.
Guyon, I., Boser, B.E., and Vapnik, V.N., 1992. A training
algorithm for optimal margin classifiers. In the annual
workshop of computational learning theory, pages 144
152. ACM.
A. W. Tucker H. W. Kuhn., 1951. Non-linear
programming. In 2nd on Mathmatical Statistics and

61

[10]
[11]

[12]

[13]
[14]
[15]
[16]

[17]
[18]

Probability, 481492, Berkley, University of California


Press.
T. Jaakkola, M. Diekhans, and Haussler, D., 1998 A
discriminative framework for detecting remote protein
homologies.
Joachims, Thorsten., 1998. Text categorization with
support vector machines: learning with many relevant
features. In Celine Rouveirol Claire Nedellec, editor,
(ECML)-98, 10th European Conference on Machine
Learning, number 13 in 98, 137142, Chemnitz, DE, 1998.
Springer Verlag, Heidelberg, DE.
Joachims, Thorsten., 1999. Transductive inference for text
classification using support vector machines. In Saso
Dzeroski Ivan Bratko, editor, Proceedings of ICML-99,
16th International Conference on Machine Learning, pages
200209, Bled, SL. Morgan Kaufmann Publishers, San
Francisco,US.
Kim, H. and Park, H., 2003. Prediction of protein relative
solvent accessibility with support vector machines and
long-range interaction 3d local descriptor.
Kim, H. and Park, H., 2003. Protein secondary structure
prediction by support vector machines and position-specific
scoring matrices.
Lee, Yuh-Jye and Mangasarian, O. L., 2000. Ssvm:
Smooth support vector machine for classification.
Computational Optimization and Applications, 20(1):522.
Lee, Yuh-Jye, Mangasarian, O. L., and Wolberg, W. H.,
2000. Breast cancer survival and chemotherapy: A support
vector machine analysis. DIMACS Series in Discrete
Mathematics and Theoretical Computer Science, 55:110.
Lee, Yuh-Jye, Mangasarian, O. L., and Wolberg, W. H.,
2001. Survival-time classification of breast cancer
patients. In Data Mining Institute Technical Report 01-03.
Lyu, S., and Farid, H., 2002. Detecting hidden messages
using higher-order statistics and support vector machines.

62

[19]

[20]

[21]

[22]
[23]

[24]

[25]

[26]

In 5th International Workshop on Information Hiding,


Noordwijkerhout, The Netherlands.
Mangasarian, Olvi L., Street, W. Nick, and Wolberg,
William H., 1994. Breast cancer diagnosis and prognosis
via linear programming. Technical Report MP-TR-199410, MP-TR.
Mller, K.R., Smola, A., Rtsch, G., Schlkopf, B.,
Kohlmorgen, J., and Vapnik, V., 1997. Predicting time
series with support vector machines. In M. Hasler W.
Gerstner, A. Germond and J.D. Nicoud, editors, Articial
Neural Networks - ICANN97, pages 9991004. Springer
Lecture Notes in Computer Science.
Mller, K.R., Smola, A., Rtsch, G., Schlkopf, B.,
Kohlmorgen, J., and Vapnik, V., 1999. Using support
vector machines for time series prediction. In B. Schlkopf,
C.J.C. Burges, and A.J. Smola, editors, Advances in Kernel
Methods, pages 242253. MIT Press.
Mohan, Anuj., 1999. Object detection in images by
components.
Rychetsky, M., Ortmann, S., and Glesner, M., 1999.
Construction of a support vector machine with local
experts. In Workshop on Support Vector Machines at the
International Joint Conference on Artificial Intelligence
(IJCAI 99), Stockholm, Sweden.
Rychetsky, M., Ortmann, S., and Glesner, M., 1999.
Support vector approaches for engine knock detection. In
International Joint Conference on Neural Networks (IJCNN
99), Washington, USA.
Mukherjee, Sayan, Osuna, Edgar, and Girosi, Frederico.,
1997. Nonlinear prediction of chaotic time series using
support vector machines. In IEEE NNSP 97, Amelia Island,
Florida, USA.
Mukkamala, Srinivas and Sung, Andrew H., 2003. A
comparative study of techniques for intrusion detection. In
15th IEEE International Conference on Tools with

63

[27]
[28]
[29]
[30]
[31]
[32]
[33]
[34]

[35]
[36]

Artificial Intelligence (ICTAI03), Sacramento, California,


USA.
Cristianini, John Shawe-Taylor Nello., 2000. An
Intoduction to Support Vector Machines and other kernalbased learning methods. Cambridge University Press.
Osuna, E., Freund, R., and Girosi, F., 1997. Training
support vector machines:an application to face detection.
In CVPR97, Puerto Rico.
Pal, Mahesh and Mather, Paul M., 2003. Support vector
classifiers for land cover classification. In Map India 2003
Image Processing and Interpretation.
Papageorgiou, C., Evgeniou, T., and Poggio, T., 1998. A
trainable pedestrian detection system. In Intelligent
Vehicles, pages 241246.
Papageorgiou, Constantine and Poggio, Tomaso. 1999. A
pattern classification approach to dynamical object
detection. In Proceedings of ICCV, pages 12231228.
Papageorgiou, Constantine P., Oren, Michael, and Poggio,
Tomaso, 1998. A general framework for object detection.
In ICCV, pages 555562.
Pontil, Massimiliano and Verri, A., 1997. Direct aspectbased 3-d object recognition. In Int. Conf on Image
Analysis and Processing, Firenze.
Raudys, S. J. and Jain, A. K., 1991. Small sample size
effects in statistical pattern recognition: Recommendations
for practitioners. In IEEE Trans. on Pattern Analysis and
Machine Intelligence, volume 13, pages 252264.
Roobaert, Danny and Hulle, Marc M. Van, 1999. Viewbased 3d object recognition with support vector machines.
In IEEE Neural Networks for Signal Processing.
Schlkopf, B., O Burges, and Vapnik, V, 1996.
Incorporating invariances in support vector learning
machines. In Articial Neural Networks ICANN96,
volume 1112, pages 4752, Berlin. Springer Lecture Notes
in Computer Science.

64

[37] Tong, Simon and Chang, Edward, 2001. Support vector


machine active learning for image retrieval. In ACM
multimedia 2001, Ontario, Canada.
[38] Vannerem, P., Mller, K.R., Schlkopf, B., Smola, A., and
Sldner-Rembold, S, 1999. Classifying lep data with
support vector algorithms. In AIHENP99.
[39] Vapnik, V, 1982. Estimation of dependencies based on
empirical data. New York. Springer-Verlag.
[40] Vapnik, V, 1995. The nature of statistical learning theory.
Berlin,. Springer-Verlag.
[41] Zhao, Qun and Principe, Jose, 1998. Automatic target
recognition with support vector machines. In NIPS-98
Workshop on Large Margin Classifiers.
[42] Zien, Ratsch, Mika, Scholkopf, Lengauer, and Muller.,
2000. Engineering support vector machine kernels that
recognize
translation
initiation
sites.
BIOINF:
Bioinformatics, 16.
[43] Hastie, T., Rosset, S., Tibshirani, R., and Zhu, J., 2004.
The Entire Regularization Path for the Support Vector
Machine. J. Machine Learning Research, vol. 5, pp. 13911415.
[44] Jain, A.K., and Vailaya, A. 1998. Shape-Based Retrieval:
A Case Study with Trademark Image Database. Pattern
Recognition, vol. 9, pp. 1369-1390.
[45] Manjunath, B., Wu, P., Newsam, S., and Shin, H., 2000. A
Texture Descriptor for Browsing and Similarity Retrieval.
J. Signal Processing: Image Comm., vol. 16, pp. 33-42.
[46] Rocchio, J., 1971. Relevance Feedback in Information
Retrieval. The SMART Retrieval System: Experiments in
Automatic Document Processing, pp. 313-323.
[47] Rui, Y., Huang, T.S., Ortega, M., and Mehrotra, S. , Sept.
1998. Relevance Feedback: A Power Tool in Interactive
Content-Based Image Retrieval. IEEE Trans. Circuits and
Systems for Video Technology, vol. 8, no. 5, pp. 644-655.

65

[48] Salton, G., and McGill, M.J., 1983. Introduction to


Modern Information Retrieval. McGraw-Hill.
[49] Smeulders, A.W.M., Worring, M., Santini, S., Gupta, A.,
and Jain, R., Dec. 2000. Content-Based Image Retrieval
at the End of the Early Years. IEEE Trans. Pattern
Analysis and Machine Intelligence, vol. 22, no. 12, pp.
1349-1380.
[50] Smith, J., and Chang, S.-F., Nov. 1996. Automated Image
Retrieval Using Color and Texture. IEEE Trans. Pattern
Analysis and Machine Intelligence, vol. 18, no. 11.
[51] C.-C. Chang and C.-J. Lin, 2001. LIBSVM: A Library for
Support Vector Machines,
http://www.csie.ntu.edu.tw/~cjlin/libsvm.

66

BLOK KODE 1:
Tapis Korelasi MOSSE

function mosseFilter(params) {
var
var
var
var
var
var
var

_filter, _top, _bottom;


_fft;
_w,_h;
_im_part;
_arrlen;
_cc;
_image_array;

this.psr_prev = undefined;
this.peak_prev = undefined;
var peak = 0.0;
var updateable = false;
if (!params) params = {};
// setup of canvas for drawing responses, if given
if (params.drawResponse === undefined) {
params.drawResponse = false;
} else {
if (params.drawResponse.tagName != 'CANVAS') {
params.drawResponse = false;
} else {
var responseContext =
params.drawResponse.getContext('2d');
}
}
if (params.psrThreshold === undefined) params.psrThreshold = 10;
if (params.eta === undefined) params.eta = 0.10;
if (params.convertToGrayscale === undefined)
params.convertToGrayscale = true;
this.load = function(filter) {
// initialize filter width and height
_w = filter.width;
_h = filter.height;
_arrlen = _w*_h;
_filter = [filter.real, filter.imag];
// handling top and bottom when they're not present
if (filter.top && filter.bottom) {
updateable = true;
_top = [filter.top.real, filter.top.imag];
_bottom = [filter.bottom.real, filter.bottom.imag];
}
// initialize fft to given width
_fft = new FFT();
_fft.init(filter.width);
// set up temporary variables
if(typeof Float64Array !== 'undefined') {
_im_part = new Float64Array(_arrlen);
_image_array = new Float64Array(_arrlen);
} else {

67

_im_part = new Array(_arrlen);


_image_array = new Array(_arrlen);
}
var canvas = document.createElement("canvas");
canvas.setAttribute('width', _w);
canvas.setAttribute('height', _h);
_cc = canvas.getContext('2d');
}
this.init = function(w,h) {
// initialize filter width and height for a blank filter
_w = w;
_h = h;
_arrlen = _w*_h;
_filter = [[],[]];
_top = [[],[]];
_bottom = [[],[]];
for (var i = 0;i < _arrlen;i++) {
_filter[0][i] = 0;
_filter[1][i] = 0;
_top[0][i] = 0;
_top[1][i] = 0;
_bottom[0][i] = 0;
_bottom[1][i] = 0;
}
updateable = true;
// initialize fft to given width
_fft = new FFT();
_fft.init(w);
// set up temporary variables
if(typeof Float64Array !== 'undefined') {
_im_part = new Float64Array(_arrlen);
} else {
_im_part = new Array(_arrlen);
}
var canvas = document.createElement("canvas");
canvas.setAttribute('width', _w);
canvas.setAttribute('height', _h);
_cc = canvas.getContext('2d');
}
// fft function
this.fft = function(array) {
// not in-place
var cn = new Array(_arrlen);
for (var i = 0;i < _arrlen;i++) {
cn[i] = 0.0;
}
_fft.fft2d(array,cn)
return [array, cn];
}
// fft function
this.fft_inplace = function(array) {
// in-place

68

for (var i = 0;i < _arrlen;i++) {


_im_part[i] = 0.0;
}
_fft.fft2d(array,_im_part)
return [array, _im_part];
}
this.ifft = function(rn, cn) {
// in-place
_fft.ifft2d(rn, cn);
return rn;
}
// peak to sidelobe ratio function (optional)
this.psr = function(array) {
// proper
var sum = 0;
var max = 0;
var maxpos = [];
var sdo = 0;
var val;
for (var x = 0;x < _w;x++) {
for (var y = 0;y < _h;y++) {
val = array[(y*_w)+x];
sum += val;
sdo += (val*val);
if (max < val) {
max = val;
maxpos = [x,y];
}
}
}
// subtract values around peak
for (var x = -5;x < 6;x++) {
for (var y = -5;y < 6;y++) {
if (Math.sqrt(x*x+y*y) < 5) {
val = array[((maxpos[1]+y)*_w)+(maxpos[0]+x)]
sdo -= (val*val);
sum -= val;
}
}
}
var mean = sum/array.length;
var sd = Math.sqrt((sdo/array.length)-(mean*mean));
// get mean/variance of output around peak
var psr = (max-mean)/sd;
return psr;
}
this.getResponse = function(imageData) {
// in-place
// preprocess
var prepImage = preprocess(imageData);
prepImage = cosine_window(prepImage);
// filter

69

var res = this.fft_inplace(prepImage);


// elementwise multiplication with filter
complex_mult_inplace(res, _filter);
// do inverse 2d fft
var filtered = this.ifft(res[0],res[1]);
return filtered;
}
this.track = function(input, left, top, width, height,
updateFilter, gaussianPrior, calcPSR) {
// finds position of filter in input image
if (!_filter) {
console.log("Mosse-filter needs to be initialized or
trained before starting tracking.");
return false;
}
if (input.tagName == "VIDEO" || input.tagName == "IMG") {
// scale selection according to original source image
var videoLeft =
Math.round((left/input.width)*input.videoWidth);
var videoTop =
Math.round((top/input.height)*input.videoHeight);
var videoWidth =
Math.round((width/input.width)*input.videoWidth);
var videoHeight =
Math.round((height/input.height)*input.videoHeight);
_cc.drawImage(input, videoLeft, videoTop, videoWidth,
videoHeight, 0, 0, _w, _h);
} else if (input.tagName == "CANVAS") {
_cc.drawImage(input, left, top, width, height, 0, 0, _w,
_h);
}
var image = _cc.getImageData(0,0,_w,_h);
var id = image.data;
if (params.convertToGrayscale) {
// convert to grayscale
for (var i = 0;i < _arrlen;i++) {
_image_array[i] = id[(4*i)]*0.3;
_image_array[i] += id[(4*i)+1]*0.59;
_image_array[i] += id[(4*i)+2]*0.11;
}
} else {
// use only one channel
for (var i = 0;i < _arrlen;i++) {
_image_array[i] = id[(4*i)];
}
}
// preprocess
var prepImage = preprocess(_image_array);
prepImage = cosine_window(prepImage);
// filter
var res = this.fft_inplace(prepImage);
// elementwise multiplication with filter

70

var nures = complex_mult(res, _filter);


// do inverse 2d fft
var filtered = this.ifft(nures[0],nures[1]);
// find max and min
var max = 0;
var min = 0;
var maxpos = [];
//method using centered gaussian prior
if (gaussianPrior) {
var prior, dx, dy;
var variance = 128;
for (var x = 0;x < _w;x++) {
for (var y = 0;y < _h;y++) {
dx = x - _w/2;
dy = y - _h/2;
prior = Math.exp(-0.5*((dx*dx)+(dy*dy))/variance)
if ((filtered[(y*_w)+x]*prior) > max) {
max = filtered[(y*_w)+x]*prior;
maxpos = [x,y];
}
if (filtered[(y*_w)+x] < min) {
min = filtered[(y*_w)+x];
}
}
}
} else {
for (var x = 0;x < _w;x++) {
for (var y = 0;y < _h;y++) {
if (filtered[(y*_w)+x] > max) {
max = filtered[(y*_w)+x];
maxpos = [x,y];
}
if (filtered[(y*_w)+x] < min) {
min = filtered[(y*_w)+x];
}
}
}
}
this.peak_prev = max;
if (params.drawResponse) {
// draw response
var diff = max-min;
var dc = document.createElement('canvas');
dc.setAttribute('width', 32);
dc.setAttribute('height', 32);
var dcc = dc.getContext('2d');
var psci = dcc.createImageData(32, 32);
var pscidata = psci.data;
for (var j = 0;j < 32*32;j++) {
//draw with priors
//var val = filtered[j]*Math.exp(-0.5*(((j%_w _w/2)*(j%_w -_w/2))+((Math.floor(j/_h)-(_h/2))*(Math.floor(j/_h)(_h/2))))/128);
var val = filtered[j];
val = Math.round((val+Math.abs(min))*(255/diff));
pscidata[j*4] = val;
pscidata[(j*4)+1] = val;
pscidata[(j*4)+2] = val;

71

pscidata[(j*4)+3] = 255;
}
dcc.putImageData(psci, 0, 0);
responseContext.drawImage(dc, left, top, width, width);
}
if (calcPSR) {
this.psr_prev = this.psr(filtered);
}
if (updateFilter) {
if (!updateable) {
console.log("The loaded filter does not support
updating. Ignoring parameter 'updateFilter'.");
} else {
if (calcPSR) {
var psr = this.psr_prev;
} else {
var psr = this.psr(filtered);
}
if (psr > params.psrThreshold) {
// create target
var target = [];
var nux = maxpos[0];
var nuy = maxpos[1];
for (var x = 0;x < _w;x++) {
for (var y = 0;y < _h;y++) {
target[(y*_w)+x] = Math.exp(-(((xnux)*(x-nux))+((y-nuy)*(y-nuy)))/(2*2));
}
}
//fft target
target = this.fft(target);
// create filter
var res_conj = complex_conj(res);
var fuTop = complex_mult(target,res_conj);
var fuBottom = complex_mult(res,res_conj);
// add up
var eta = params.eta;
for (var i = 0;i < _arrlen;i++) {
_top[0][i] = eta*fuTop[0][i] + (1eta)*_top[0][i];
_top[1][i] = eta*fuTop[1][i] + (1eta)*_top[1][i];
_bottom[0][i] = eta*fuBottom[0][i] + (1eta)*_bottom[0][i];
_bottom[1][i] = eta*fuBottom[1][i] + (1eta)*_bottom[1][i];
}
_filter = complex_div(_top,_bottom);
}
}
}
/*if (psr < 5) {
maxpos = [_w/2,_h/2];

72

}*/
maxpos[0] = maxpos[0]*(width/_w);
maxpos[1] = maxpos[1]*(width/_h);
// check if output is strong enough
// if not, return false?
if (max < 0) {
return false;
} else {
return maxpos;
}
}
this.train = function(input, left, top, width, height) {
if (!updateable) {
console.log("The loaded filter does not support updating.
Unable to do training.");
return false;
}
if (input.tagName == "VIDEO" || input.tagName == "IMG") {
// scale selection according to original source image
var videoLeft =
Math.round((left/input.width)*input.videoWidth);
var videoTop =
Math.round((top/input.height)*input.videoHeight);
var videoWidth =
Math.round((width/input.width)*input.videoWidth);
var videoHeight =
Math.round((height/input.height)*input.videoHeight);
_cc.drawImage(input, videoLeft, videoTop, videoWidth,
videoHeight, 0, 0, _w, _h);
} else if (input.tagName == "CANVAS") {
_cc.drawImage(input, left, top, width, height, 0, 0, _w,
_h);
}
var image = _cc.getImageData(0,0,_w,_h);
var id = image.data;
// convert to grayscale
for (var i = 0;i < _arrlen;i++) {
_image_array[i] = id[(4*i)]*0.3;
_image_array[i] += id[(4*i)+1]*0.59;
_image_array[i] += id[(4*i)+2]*0.11;
}
// preprocess
var prepImage = preprocess(_image_array);
prepImage = cosine_window(prepImage);
// create target
var target = [];
var nux = _w/2;
var nuy = _h/2;
for (var x = 0;x < _w;x++) {
for (var y = 0;y < _h;y++) {
target[(y*_w)+x] = Math.exp(-(((x-nux)*(x-nux))+((ynuy)*(y-nuy)))/(2*2));

73

}
}
//fft target
target = this.fft(target);
// filter
var res = this.fft(prepImage);
// create filter
var res_conj = complex_conj(res);
var fuTop = complex_mult(target,res_conj);
var fuBottom = complex_mult(res,res_conj);
// add up
var eta = params.eta;
for (var i = 0;i < _arrlen;i++) {
_top[0][i] = eta*fuTop[0][i] + (1-eta)*_top[0][i];
_top[1][i] = eta*fuTop[1][i] + (1-eta)*_top[1][i];
_bottom[0][i] = eta*fuBottom[0][i] + (1eta)*_bottom[0][i];
_bottom[1][i] = eta*fuBottom[1][i] + (1eta)*_bottom[1][i];
}
_filter = complex_div(_top,_bottom);
return true;
}
var preprocess = function(array) {
// in-place
// log adjusting
for (var i = 0;i < _arrlen;i++) {
array[i] = Math.log(array[i]+1);
}
// normalize to mean 0 and norm 1
var mean = 0;
for (var i = 0;i < _arrlen;i++) {
mean += array[i];
}
mean /= _arrlen;
for (var i = 0;i < _arrlen;i++) {
array[i] -= mean;
}
var norm = 0.0;
for (var i = 0;i < _arrlen;i++) {
norm += (array[i]*array[i]);
}
norm = Math.sqrt(norm);
for (var i = 0;i < _arrlen;i++) {
array[i] /= norm;
}
return array;
}
var cosine_window = function(array) {
// calculate rect cosine window (in-place)

74

var pos = 0;
for (var i = 0;i < _w;i++) {
for (var j = 0;j < _h;j++) {
//pos = (i%_w)+(j*_w);
var cww = Math.sin((Math.PI*i)/(_w-1))
var cwh = Math.sin((Math.PI*j)/(_h-1))
array[pos] = Math.min(cww,cwh)*array[pos];
pos++;
}
}
return array;
}
var complex_mult = function(cn1, cn2) {
// not in-place
var re_part = new Array(_w);
var im_part = new Array(_w);
var nucn = [re_part, im_part];
for (var r = 0;r < _arrlen;r++) {
nucn[0][r] = (cn1[0][r]*cn2[0][r]) (cn1[1][r]*cn2[1][r]);
nucn[1][r] = (cn1[0][r]*cn2[1][r]) +
(cn1[1][r]*cn2[0][r]);
}
return nucn;
}
var complex_mult_inplace = function(cn1, cn2) {
// in-place
var temp1, temp2;
for (var r = 0;r < _arrlen;r++) {
temp1 = (cn1[0][r]*cn2[0][r]) - (cn1[1][r]*cn2[1][r]);
temp2 = (cn1[0][r]*cn2[1][r]) + (cn1[1][r]*cn2[0][r]);
cn1[0][r] = temp1;
cn1[1][r] = temp2;
}
}
var complex_conj = function(cn) {
// not in-place (TODO)
var nucn = [[],[]];
for (var i = 0;i < _arrlen;i++) {
nucn[0][i] = cn[0][i]
nucn[1][i] = -cn[1][i];
}
return nucn;
}
var complex_div = function(cn1, cn2) {
// not in-place (TODO)
var nucn = [[],[]];
for (var r = 0;r < _arrlen;r++) {
nucn[0][r] =
((cn1[0][r]*cn2[0][r])+(cn1[1][r]*cn2[1][r])) /
((cn2[0][r]*cn2[0][r]) + (cn2[1][r]*cn2[1][r]));
nucn[1][r] = ((cn1[1][r]*cn2[0][r])(cn1[0][r]*cn2[1][r])) / ((cn2[0][r]*cn2[0][r]) +
(cn2[1][r]*cn2[1][r]));
}
return nucn;

75

}
}

BLOK KODE 2:
Transformasi Fourier Cepat

function FFT() {
var _n = 0,
_bitrev = null,
_cstb = null;
var _tre, _tim;

// order
// bit reversal table
// sin/cos table

this.init = function (n) {


if(n !== 0 && (n & (n - 1)) === 0) {
_n = n;
_setVariables();
_makeBitReversal();
_makeCosSinTable();
} else {
throw new Error("init: radix-2 required");
}
}
// 1D-FFT
this.fft1d = function (re, im) {
fft(re, im, 1);
}
// 1D-IFFT
this.ifft1d = function (re, im) {
var n = 1/_n;
fft(re, im, -1);
for(var i=0; i<_n; i++) {
re[i] *= n;
im[i] *= n;
}
}
// 2D-FFT
this.fft2d = function (re, im) {
var i = 0;
// x-axis
for(var y=0; y<_n; y++) {
i = y*_n;
for(var x1=0; x1<_n; x1++) {
_tre[x1] = re[x1 + i];
_tim[x1] = im[x1 + i];
}
this.fft1d(_tre, _tim);
for(var x2=0; x2<_n; x2++) {
re[x2 + i] = _tre[x2];
im[x2 + i] = _tim[x2];
}
}
// y-axis

76

for(var x=0; x<_n; x++) {


for(var y1=0; y1<_n; y1++) {
i = x + y1*_n;
_tre[y1] = re[i];
_tim[y1] = im[i];
}
this.fft1d(_tre, _tim);
for(var y2=0; y2<_n; y2++) {
i = x + y2*_n;
re[i] = _tre[y2];
im[i] = _tim[y2];
}
}
}
// 2D-IFFT
this.ifft2d = function (re, im) {
var i = 0;
// x-axis
for(var y=0; y<_n; y++) {
i = y*_n;
for(var x1=0; x1<_n; x1++) {
_tre[x1] = re[x1 + i];
_tim[x1] = im[x1 + i];
}
this.ifft1d(_tre, _tim);
for(var x2=0; x2<_n; x2++) {
re[x2 + i] = _tre[x2];
im[x2 + i] = _tim[x2];
}
}
// y-axis
for(var x=0; x<_n; x++) {
for(var y1=0; y1<_n; y1++) {
i = x + y1*_n;
_tre[y1] = re[i];
_tim[y1] = im[i];
}
this.ifft1d(_tre, _tim);
for(var y2=0; y2<_n; y2++) {
i = x + y2*_n;
re[i] = _tre[y2];
im[i] = _tim[y2];
}
}
}
// core operation of FFT
function fft(re, im, inv) {
var d, h, ik, m, tmp, wr, wi, xr, xi,
n4 = _n >> 2;
// bit reversal
for(var l=0; l<_n; l++) {
m = _bitrev[l];
if(l < m) {
tmp = re[l];
re[l] = re[m];
re[m] = tmp;
tmp = im[l];
im[l] = im[m];
im[m] = tmp;

77

}
}
// butterfly operation
for(var k=1; k<_n; k<<=1) {
h = 0;
d = _n/(k << 1);
for(var j=0; j<k; j++) {
wr = _cstb[h + n4];
wi = inv*_cstb[h];
for(var i=j; i<_n; i+=(k<<1)) {
ik = i + k;
xr = wr*re[ik] + wi*im[ik];
xi = wr*im[ik] - wi*re[ik];
re[ik] = re[i] - xr;
re[i] += xr;
im[ik] = im[i] - xi;
im[i] += xi;
}
h += d;
}
}
}
// set variables
function _setVariables() {
if(typeof Uint8Array !== 'undefined') {
_bitrev = new Uint8Array(_n);
} else {
_bitrev = new Array(_n);
}
if(typeof Float64Array !== 'undefined') {
_cstb = new Float64Array(_n*1.25);
_tre = new Float64Array(_n*_n);
_tim = new Float64Array(_n*_n);
} else {
_cstb = new Array(_n*1.25);
_tre = new Array(_n*_n);
_tim = new Array(_n*_n);
}
}
// make bit reversal table
function _makeBitReversal() {
var i = 0,
j = 0,
k = 0;
_bitrev[0] = 0;
while(++i < _n) {
k = _n >> 1;
while(k <= j) {
j -= k;
k >>= 1;
}
j += k;
_bitrev[i] = j;
}
}
// make trigonometric function table
function _makeCosSinTable() {
var n2 = _n >> 1,

78

n4 = _n >> 2,
n8 = _n >> 3,
n2p4 = n2 + n4,
t = Math.sin(Math.PI/_n),
dc = 2*t*t,
ds = Math.sqrt(dc*(2 - dc)),
c = _cstb[n4] = 1,
s = _cstb[0] = 0;
t = 2*dc;
for(var i=1; i<n8; i++) {
c -= dc;
dc += t*c;
s += ds;
ds -= t*s;
_cstb[i] = s;
_cstb[n4 - i] = c;
}
if(n8 !== 0) {
_cstb[n8] = Math.sqrt(0.5);
}
for(var j=0; j<n4; j++) {
_cstb[n2 - j] = _cstb[j];
}
for(var k=0; k<n2p4; k++) {
_cstb[k + n2] = -_cstb[k];
}
}
}

BLOK KODE 3:
Iterasi Jacobian Matriks

var createJacobian = function(parameters, eigenVectors) {


var jacobian = numeric.rep([2*numPatches, numParameters+4],0.0);
var j0,j1;
for (var i = 0;i < numPatches;i ++) {
// 1
j0 = meanShape[i][0];
j1 = meanShape[i][1];
for (var p = 0;p < numParameters;p++) {
j0 += parameters[p+4]*eigenVectors[i*2][p];
j1 += parameters[p+4]*eigenVectors[(i*2)+1][p];
}

79

jacobian[i*2][0] = j0;
jacobian[(i*2)+1][0] = j1;
// 2
j0 = meanShape[i][1];
j1 = meanShape[i][0];
for (var p = 0;p < numParameters;p++) {
j0 += parameters[p+4]*eigenVectors[(i*2)+1][p];
j1 += parameters[p+4]*eigenVectors[i*2][p];
}
jacobian[i*2][1] = -j0;
jacobian[(i*2)+1][1] = j1;
// 3
jacobian[i*2][2] = 1;
jacobian[(i*2)+1][2] = 0;
// 4
jacobian[i*2][3] = 0;
jacobian[(i*2)+1][3] = 1;
// the rest
for (var j = 0;j < numParameters;j++) {
j0 = parameters[0]*eigenVectors[i*2][j] parameters[1]*eigenVectors[(i*2)+1][j] + eigenVectors[i*2][j];
j1 = parameters[0]*eigenVectors[(i*2)+1][j] +
parameters[1]*eigenVectors[i*2][j] + eigenVectors[(i*2)+1][j];
jacobian[i*2][j+4] = j0;
jacobian[(i*2)+1][j+4] = j1;
}
}
return jacobian;
}

80

BLOK KODE 4:
Script Implementasi Constraint Local Models pada gambar

<script>
var cc =
document.getElementById('image').getContext('2d');
var overlay =
document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');
var img = new Image();
img.onload = function() {
cc.drawImage(img,0,0,625, 500);
};
img.src = './media/test_bumper.jpg';
var ctrack = new
clm.tracker({stopOnConvergence : true});
ctrack.init(pModel);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild(
stats.domElement );
var drawRequest;
function animate(box) {
ctrack.start(document.getElementById('image'), box);
drawLoop();
}
function drawLoop() {
drawRequest =
requestAnimFrame(drawLoop);
overlayCC.clearRect(0, 0, 720, 576);
if (ctrack.getCurrentPosition()) {
ctrack.draw(overlay);
}
}
// detect if tracker fails to find a face
document.addEventListener("clmtrackrNotFound", function(event)
{
ctrack.stop();
alert("The tracking had problems with
finding a face in this image. Try selecting the face in the image
manually.")
}, false);
// detect if tracker loses tracking of face

81

document.addEventListener("clmtrackrLost",
function(event) {
ctrack.stop();
alert("The tracking had problems
converging on a face in this image. Try selecting the face in the
image manually.")
}, false);
// detect if tracker has converged
document.addEventListener("clmtrackrConverged", function(event)
{
document.getElementById('convergence').innerHTML = "CONVERGED";
document.getElementById('convergence').style.backgroundColor =
"#00FF00";
// stop drawloop
cancelRequestAnimFrame(drawRequest);
}, false);
// update stats on iteration
document.addEventListener("clmtrackrIteration", function(event)
{
stats.update();
}, false);
// manual selection of faces (with jquery
imgareaselect plugin)
function selectBox() {
overlayCC.clearRect(0, 0, 720, 576);
document.getElementById('convergence').innerHTML = "";
ctrack.reset();
$('#overlay').addClass('hide');
$('#image').imgAreaSelect({
handles : true,
onSelectEnd : function(img,
selection) {
// create box
var box = [selection.x1,
selection.y1, selection.width, selection.height];
// do fitting
animate(box);
$('#overlay').removeClass('hide');
},
autoHide : true
});
}
// function to start showing images
function loadImage() {
if (fileList.indexOf(fileIndex) < 0) {
var reader = new FileReader();
reader.onload =
(function(theFile) {
return function(e) {

82

// check if positions
already exist in storage
// Render thumbnail.
var canvas =
document.getElementById('image')
var cc =
canvas.getContext('2d');
var img = new
Image();
img.onload =
function() {
if (img.height
> 500 || img.width > 700) {
var rel =
img.height/img.width;
var neww
= 700;
var newh
= neww*rel;
if (newh
> 500) {
newh = 500;
neww = newh/rel;
}
canvas.setAttribute('width', neww);
canvas.setAttribute('height', newh);
cc.drawImage(img,0,0,neww, newh);
} else {
canvas.setAttribute('width', img.width);
canvas.setAttribute('height', img.height);
cc.drawImage(img,0,0,img.width, img.height);
}
}
img.src =
e.target.result;
};
})(fileList[fileIndex]);
reader.readAsDataURL(fileList[fileIndex]);
overlayCC.clearRect(0, 0, 720,
576);
document.getElementById('convergence').innerHTML = "";
ctrack.reset();
}
}
// set up file selector and variables to hold
selections
var fileList, fileIndex;

83

if (window.File && window.FileReader &&


window.FileList) {
function handleFileSelect(evt) {
var files = evt.target.files;
fileList = [];
for (var i = 0;i <
files.length;i++) {
if
(!files[i].type.match('image.*')) {
continue;
}
fileList.push(files[i]);
}
if (files.length > 0) {
fileIndex = 0;
}
loadImage();
}
document.getElementById('files').addEventListener('change',
handleFileSelect, false);
} else {
$('#files').addClass("hide");
$('#loadimagetext').addClass("hide");
}
</script>

BLOK KODE 5:
Script Substitusi Wajah
<script>
// when everything is ready, automatically
start everything ?
var vid = document.getElementById('videoel');
var overlay =
document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');
/*********** Setup of video/webcam and
checking for webGL support *********/
var videoReady = false;
var imagesReady = false;
function enablestart() {
if (videoReady && imagesReady) {
var startbutton =
document.getElementById('startbutton');
startbutton.value = "start";
startbutton.disabled = null;
}
}
$(window).load(function() {
imagesReady = true;

84

enablestart();
});
var insertAltVideo = function(video) {
if (supports_video()) {
if (supports_ogg_theora_video())
{
video.src =
"../media/cap13_edit2.ogv";
} else if
(supports_h264_baseline_video()) {
video.src =
"../media/cap13_edit2.mp4";
} else {
return false;
}
//video.play();
return true;
} else return false;
}
// check whether browser supports webGL
var webGLContext;
var webGLTestCanvas =
document.createElement('canvas');
if (window.WebGLRenderingContext) {
webGLContext =
webGLTestCanvas.getContext('webgl') ||
webGLTestCanvas.getContext('experimental-webgl');
if (!webGLContext ||
!webGLContext.getExtension('OES_texture_float')) {
webGLContext = null;
}
}
if (webGLContext == null) {
alert("Your browser does not seem to
support WebGL. Unfortunately this face mask example depends on WebGL,
so you'll have to try it in another browser. :(");
}
navigator.getUserMedia =
navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL
|| window.msURL || window.mozURL;
// check for camerasupport
if (navigator.getUserMedia) {
// set up stream
// chrome 19 shim
var videoSelector = {video : true};
if
(window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
var chromeVersion =
parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1],
10);
if (chromeVersion < 20) {
videoSelector = "video";
}
};

85

navigator.getUserMedia(videoSelector,
function( stream ) {
if (vid.mozCaptureStream) {
vid.mozSrcObject = stream;
} else {
vid.src = (window.URL &&
window.URL.createObjectURL(stream)) || stream;
}
vid.play();
}, function() {
insertAltVideo(vid);
alert("There was some problem
trying to fetch video from your webcam, using a fallback video
instead.");
});
} else {
insertAltVideo(vid);
alert("Your browser does not seem to
support getUserMedia, using a fallback video instead.");
}
vid.addEventListener('canplay', function()
{videoReady = true;enablestart();}, false);
/*********** Code for face substitution
*********/
var animationRequest;
var positions;
var ctrack = new clm.tracker();
ctrack.init(pModel);
document.getElementById('selectmask').addEventListener('change'
, updateMask, false);
function updateMask(el) {
currentMask = parseInt(el.target.value,
10);
var positions =
ctrack.getCurrentPosition(vid);
if (positions) {
switchMasks(positions);
}
}
function startVideo() {
// start video
vid.play();
// start tracking
ctrack.start(vid);
// start drawing face grid
drawGridLoop();
}
var fd = new faceDeformer();
fd.init(document.getElementById('webgl'));

86

var wc1 =
document.getElementById('webgl').getContext('webgl') ||
document.getElementById('webgl').getContext('experimental-webgl')
wc1.clearColor(0,0,0,0);
var fd2 = new faceDeformer();
fd2.init(document.getElementById('webgl2'));
var wc2 =
document.getElementById('webgl2').getContext('webgl') ||
document.getElementById('webgl2').getContext('experimental-webgl')
wc2.clearColor(0,0,0,0);
var masks = {
"average" : [[26.416248681267973,
69.287261104729708], [24.481184011083002, 109.1589911732479],
[29.947934496257105, 148.57677024306452], [40.60811914491601,
185.45355598250219], [58.738097832656997, 216.6373204614957],
[81.913770252207783, 237.8126294428132], [109.98606755351314,
257.32753166261085], [146.73017889094805, 264.20702756677571],
[176.39901111159972, 257.35535351543069], [205.55603543434725,
238.34973455076488], [230.2355979713912, 210.41080746713624],
[246.42195156813636, 177.61588628182037], [256.27933737115922,
136.43585286772219], [257.59862842161016, 101.26962757170907],
[254.73574762861881, 63.296736154716768], [231.99351427704215,
39.831219799322724], [211.74886735135794, 29.357561061634286],
[185.76946624427666, 32.692120457915841], [164.22794828410485,
39.057255405015212], [46.913242738637145, 44.216922272932521],
[67.285057768685547, 32.598869110365555], [94.508786161963428,
34.746232646423401], [114.82786184548833, 39.533999746268229],
[65.935953298843103, 69.239210402794683], [84.787589310043472,
58.321913189471772], [107.1385272571674, 69.051184056088701],
[84.265668561805413, 74.447322016970119], [86.02844527485162,
66.55652441349649], [215.49276321482714, 66.02198446506911],
[194.41225043477402, 56.580567518322354], [173.10349613934835,
67.506651798297085], [193.89655333472706, 70.825843235112714],
[194.97190332017632, 64.213669799586413], [140.21544525228168,
50.532541524375866], [115.12210668936649, 112.86816444161286],
[106.91733219119472, 128.11159519340237], [116.15332322527513,
140.65598165170533], [143.55679637420633, 142.73810254422773],
[167.66884888729888, 137.95626733353842], [177.01070972200523,
125.94118566337217], [167.72534960722709, 111.07005102224311],
[141.09391638922847, 89.711267100602939], [125.01121871692496,
134.01776882451776], [158.83114482022663, 132.84441173561655],
[98.530013119819074, 181.49830160240677], [114.57531577249451,
172.88988327185314], [130.69321885263625, 168.51487947819879],
[140.91575863744487, 170.62230018050224], [150.99524791299294,
168.10359663640762], [166.86355823591094, 171.92886610080987],
[186.52748819945225, 179.57395522560827], [172.54811810821857,
193.62104452332397], [161.34374255744575, 203.55652478332667],
[143.04951921782722, 206.98995295806665], [122.71362572694508,
202.88542194975037], [109.36831831524565, 194.44995485842813],
[121.30529318118789, 187.44959256875671], [141.15688782807084,
190.12567632986739], [161.94486681509784, 187.9983882494468],
[161.78346166803792, 178.31913412814549], [141.60005262336557,
178.73596022750081], [121.19014424606702, 179.74550271876572],
[142.06000674291235, 125.94776468631429], [74.161858259749053,
61.982126979168953], [99.563603953011338, 61.887044688264439],
[97.202478466508737, 72.650836394381287], [74.199064214851546,
73.344884154018885], [204.65317864223729, 59.203268807746532],
[180.45823699179422, 60.544222235843449], [183.20168844348697,
70.667846856664895], [204.99820389502713, 70.525790218266522]],

87

"monalisa" : [[21.539778613571002,
52.843788988728249], [21.30390975615768, 83.302233189555977],
[26.193573294663452, 114.35387895079327], [33.713954352167377,
143.15573844972926], [48.157124973567761, 166.98090240157057],
[67.641939741413239, 187.09850232246515], [77.133435876412534,
196.36636012092117], [91.98589850664348, 199.49456958745145],
[111.87519225850986, 196.53764992548162], [137.97232156668036,
189.79752653535775], [176.61286401088506, 171.50434543677886],
[203.74322775690695, 142.02599538106227], [219.77440099078314,
108.71915538180275], [223.27759332415951, 70.224119840661501],
[221.74514645738424, 45.204926829063027], [170.26964981149064,
23.837055025056486], [145.13712322351404, 20.0], [116.92175039938184,
18.258227338970613], [97.273435613850779, 30.048346359260734],
[22.762490392814925, 34.008738851528051], [35.886077213728242, 27.0],
[58.903367725863291, 26.0], [71.696536019219309, 32.203693146398479],
[36.57998031880885, 52.779718566314955], [53.953459306751995,
44.216413703340322], [70.75345517431316, 52.451616524265091],
[51.663136137968706, 56.36486568494297], [56.63327656416925,
50.02399260975119], [153.27491865673994, 47.895434696675409],
[135.22403819342355, 41.835842816957268], [112.98660716766716,
51.531195401816717], [133.25469629277825, 53.995153369412776],
[137.61394659073221, 47.643327423184189], [83.0, 51.0],
[69.737945399362161, 99.757722929817021], [64.852131167360142,
112.67975493041121], [68.150737076897315, 119.49940769140733],
[80.204731591906352, 125.87953636258146], [105.12317959249509,
122.54252162681382], [113.37839466290973, 114.67172527740343],
[107.7986254362873, 97.551951798767789], [81.0, 80.0],
[69.756744873013361, 116.32005216616164], [98.0322275619273,
117.28199170077062], [62.875143926336932, 144.03469795323042],
[71.689261179819141, 140.91320569661593], [76.732039918708722,
139.45780089974846], [82.855831651040489, 141.56649844038935],
[91.184232315061251, 139.74737597014604], [106.00603891713007,
140.25605273754718], [122.88222498993025, 142.36607174274792],
[112.30505361714199, 152.45834288106249], [98.57616688568919,
156.8848818975423], [83.820014199000752, 157.10518323651632],
[75.361906367460449, 156.71759346010083], [67.617149756063043,
151.56250078178363], [73.498856629406305, 146.17442547934229],
[83.640659992846395, 147.73460503451736], [105.24803537963362,
147.68311332012382], [104.57542347435162, 147.53621455839362],
[84.325579467524449, 147.67345155068153], [73.225375667881906,
145.9222277142419], [79.49642775725988, 113.63122813643895],
[43.266309016571256, 46.998908993330446], [64.353645535131875,
46.83485523505226], [62.707535291980378, 54.409785609479741],
[43.620326080711664, 56.573683367978902], [145.2498028902113,
42.866393256838194], [123.10477962337723, 45.18427292360775],
[123.62079313091925, 53.764489759734829], [145.76553123073842,
52.446469912373288]],
"clooney2" : [[19.65959653975213,
58.927187574350853], [19.059936741854031, 84.069187035296466],
[26.364149346947656, 116.00569220317783], [34.339224596136916,
150.19366409567897], [51.949088586144939, 181.34522063329388],
[73.638843171470569, 200.2313071611942], [104.9963894743268,
212.04560334015787], [130.32250615166865, 213.84925849480038],
[158.47042744325807, 206.01251760804871], [179.68180939317455,
189.87495266661051], [195.53125724625511, 170.05389773335617],
[207.87916287667588, 150.263348854009], [211.60311756946669,
117.20491197917517], [215.1470951154223, 84.821473309459435],
[211.28414850045669, 52.323401046109325], [191.07721405137181,
30.707410618465985], [178.7969744809098, 22.95445734151545],
[153.07107270051728, 27.766421832907099], [135.8716261860317,
32.270221237428331], [40.797793860118304, 39.293939439043243],

88

[60.586268390363102, 30.045790597286697], [83.66233092249044,


31.510753402473881], [101.7675287849857, 34.611095156640886],
[55.196872088033274, 53.769827607374282], [73.294529697216632,
45.286958022232], [89.789514153589607, 52.475732958470758],
[72.029799616216138, 54.79702256052326], [73.546514815544526,
48.155860928669142], [179.57558029610016, 46.278523901086771],
[164.08951473989504, 39.553052148086266], [145.25477360830024,
47.559030577914911], [161.67137911336948, 47.743228605976327],
[164.5570321919293, 42.316490011681282], [118.51043662636579,
41.615242195145811], [96.145654614985858, 89.83443556968848],
[94.3004276388547, 101.2777184101229], [101.14232928754529,
107.81832135048145], [122.23729175986463, 111.54568657278116],
[141.40084172004063, 108.09394746664645], [147.43968596286589,
98.605209918840785], [141.38241141848675, 86.81434583236927],
[120.24759131986298, 71.477475584982272], [105.22693390782734,
102.2511538638106], [135.71453675842949, 102.69239102174873],
[82.106944247692269, 143.22308347546931], [94.109143846121839,
139.40149577652141], [106.89618312823151, 136.60699903750498],
[124.88130883248715, 140.90523844977974], [134.21351586850218,
137.56831409555417], [149.88840562683427, 138.81679306685891],
[163.03665611069363, 137.94602751042942], [149.12971996396905,
143.88566574722165], [138.33054643604166, 147.00248023661715],
[124.44218910312256, 149.23925548490803], [109.37911171081555,
149.45999223240068], [96.652978590522281, 146.671300600503],
[107.6988534718862, 143.24503220634898], [125.16408321171812,
142.98263526928565], [143.47086754124314, 141.3936752079527],
[150.2625022256851, 140.14425743374363], [124.86889327286275,
143.03426613514421], [107.71038700817618, 140.22310608370606],
[121.13865545746836, 97.831789384933728], [63.746229482356711,
47.529221261778929], [83.542252517622927, 46.881351751053245],
[80.910117350035449, 53.637093872553805], [63.111222164868025,
54.283991811834312], [173.83311856200004, 41.917012775126381],
[152.17209160945234, 42.056325934275009], [153.46358946670941,
47.653634652561493], [171.12694131217529, 47.51275441245707]],
"bieber" : [[19.53711459170038,
54.444293102992319], [22.410358417930311, 81.323108571931471],
[32.401607743685382, 122.14228794382235], [40.548237569709926,
160.95800363740622], [55.830864519376661, 195.08306428683375],
[81.385287393438929, 223.19377613278513], [112.80248099038053,
245.70922521138434], [143.66759219912683, 248.19456654705792],
[170.97838880302498, 243.80815503839696], [202.54366882314216,
219.80900163327027], [229.12024016664279, 189.13313409839208],
[244.51837898295568, 147.82841415594618], [248.62248099284733,
110.09427599568797], [252.16065269095574, 69.022615327489461],
[251.1869106001711, 38.073482825891446], [223.77766201515098,
30.263843596126286], [197.68549009500683, 27.366877637166382],
[172.02508396552125, 31.480903122367078], [150.59332989209975,
39.090254247657896], [38.741981623011633, 42.588528571746735],
[54.958919220427802, 38.439293690791018], [80.326672773709362,
36.802767512800102], [105.79165522546174, 40.753572250309261],
[59.731070080437199, 61.374403460631441], [82.0248909472554,
52.792320852576772], [102.98174927891796, 61.588233179208871],
[81.291210273721063, 63.763521680101718], [82.102587870122846,
57.509244186188191], [202.9918057560875, 54.365166608239129],
[183.35185317803828, 47.157748497015682], [161.8385137789503,
57.656333304586035], [183.83907055868855, 57.557394332838136],
[183.42545741727207, 52.010032452550263], [131.686076554246,
53.909282900234132], [107.69799915829482, 106.47273945500959],
[103.11407801720561, 120.60153702065169], [110.43523698455824,
130.94952817956354], [134.4500665704968, 133.04683073943445],
[159.64146874757529, 129.78570852986701], [166.7487844961837,

89

117.81662059272365], [160.1901896709515, 104.45704674681713],


[132.8335797372176, 85.328251842395701], [119.90596285959741,
128.2845201373249], [146.94103038566482, 127.18023554236562],
[95.191706081438895, 169.00217518307196], [107.74010091792692,
162.93726104569006], [120.53732776801282, 157.36305081327322],
[134.36346005292657, 158.19042577349052], [149.06532629960918,
156.03333668322352], [167.53754920890682, 160.14750809785232],
[181.68075634048043, 166.51055859230061], [169.22867544048322,
177.30535719977763], [152.98958831541205, 185.89315973650133],
[136.352332183502, 190.0381828867574], [120.88426223614132,
185.79922898421083], [107.35465833211961, 179.72589047488501],
[114.79299794468891, 169.92000421669977], [135.13370299082726,
171.30173772478196], [158.39876693773857, 168.34925679955404],
[158.23752239371439, 168.04209911043037], [134.80406768396711,
171.32584974562951], [115.32751612180201, 169.70233460348607],
[132.43152742593281, 118.83318930228684], [69.123085034678766,
54.985576193750248], [94.253510496854048, 54.393003960509063],
[92.485452013800042, 63.026429370670705], [70.154658366398536,
62.923362768598608], [194.57561889878309, 49.363550336040007],
[170.8445542308101, 50.310130450256054], [172.48925643335903,
57.608921571249979], [193.42216119777584, 55.967660359955829]],
"kim" : [[26.392953623213501,
74.847347679657105], [26.527141369604511, 113.68851836791519],
[37.850280396733659, 153.34202975546106], [48.463148502888259,
198.41912707786042], [68.036605940850848, 230.63187132257846],
[93.393921931707482, 256.18460712943767], [125.54962553340661,
277.0006892560142], [159.76888265265634, 283.50936210722568],
[190.86251528873004, 273.21633240176328], [215.4823452806404,
246.84486234022947], [236.0322931252845, 221.15226043028213],
[250.6507850464711, 189.90684387337964], [258.98554243442391,
147.8303429835579], [265.61657423486696, 111.82570412985555],
[263.82649874587986, 67.66214176561175], [254.94521256635076,
37.757625912971747], [235.79466011571427, 28.645231408254602],
[204.91596627739196, 32.48320193484367], [178.87856926846536,
45.012565822225127], [42.981527327852305, 45.1931744008115],
[65.798535249115119, 30.205697217705545], [104.20469447938497,
38.014705489906277], [132.76130440395275, 47.358258842651956],
[65.732837436644772, 73.313719718526713], [91.09303435966045,
62.44640989897627], [117.81003667247734, 77.588938967093213],
[91.455791107898818, 78.157832338525793], [91.462070264092233,
70.129658655089131], [237.49694309020128, 70.204758493119016],
[212.00252085043883, 60.741643699902738], [186.28991752012382,
75.480800750925113], [213.38992085780873, 75.700650938318205],
[211.28408082179848, 66.628969802711069], [155.31681846547161,
61.723254148350158], [131.79242360681408, 132.03519502324014],
[125.21093316902153, 145.05754431578387], [131.88896031053739,
158.30278486585388], [159.78089633124134, 160.7729628498802],
[182.60204348750557, 155.22867538213509], [188.06987132384856,
142.36052040680599], [182.50935337688247, 131.17112912726614],
[157.92771083963791, 101.9554747029501], [139.68757897346234,
150.2800567907548], [174.91470138004024, 149.77535693426591],
[108.20772330971123, 199.82539585852084], [127.27495019814955,
190.57647699976485], [143.43128670979286, 183.79198573228979],
[157.48346624056376, 187.99166515485183], [169.06090197834246,
183.92606098499843], [183.34853446393896, 189.45691649529616],
[199.86559748534597, 195.95084259678697], [189.71112448658715,
213.68218280440522], [178.41365542672253, 224.07658144186891],
[158.74710148750472, 231.45074591989936], [138.79163021123412,
228.1686029366403], [118.5034950367303, 215.59047900510384],
[134.39528308805779, 203.05726622213831], [159.30274323745374,
209.15248016464469], [175.89464505418053, 201.96972700502886],

90

[176.97487381747911,
198.13847443352608],
[160.61948984308634,
65.783911161963701],
[104.63389091894381,
77.141208919791538],
[197.74571106481017,
75.244684951836774],

198.90143676014918], [156.30097058265304,
[134.20235365838741, 199.40444860590469],
139.11949191775341], [76.663536017602837,
[109.70319643529164, 68.269206273210557],
76.826187107600873], [79.295001366702479,
[228.9531335582283, 64.425761944937264],
63.914007487070201], [200.53834682135945,
[226.14466575989266, 72.954228841629359]],
"bill" : [[27.840096322632149,
76.368615990185191], [30.154816021430406, 109.06063400353474],
[39.379878405162572, 137.75576812530437], [49.720971343106442,
165.56006971830811], [69.685918962455162, 188.83062502686539],
[91.136611503567053, 197.11213236968024], [114.01369602338886,
200.28928696425578], [137.67505607580313, 198.99464477027379],
[162.00533931387088, 194.67502878665346], [183.59957539615169,
183.86171397188139], [200.64843069277788, 169.12249458895553],
[212.74882015279246, 146.59654529811888], [216.19464878771885,
117.51545219326954], [219.7054153227329, 82.920303627910158],
[216.55736851626409, 52.500598145987141], [195.29140690264768,
33.844288891203831], [182.10450082040984, 28.047753816454644],
[160.04559543130165, 28.487796821539263], [142.86240187537408,
30.124466843837581], [40.405647296470676, 54.374170928106054],
[56.295673096305649, 43.873060994871253], [76.723373554797661,
38.650838700640719], [95.621661762561274, 38.363822770704132],
[60.297118828516858, 70.475169555111961], [78.651718472233313,
59.224037348059483], [99.573440037293096, 65.250504005881226],
[82.29544502828054, 70.300901108009271], [79.134179987698502,
64.227444036123558], [184.89706951713521, 56.365831102188366],
[165.52473664328181, 47.770967481018118], [146.32998667504086,
58.324349203503402], [164.82643203538686, 60.04407203414334],
[164.39886888106582, 52.778806963733672], [120.52365835160424,
52.521477554028849], [101.06903113447152, 95.354177230792828],
[97.706278577909302, 108.83642847893361], [102.04351853018306,
115.05243108012365], [125.99992209867958, 112.0236401737053],
[148.45902991311357, 108.96260829647667], [152.23777198445976,
100.26761218015756], [147.33366694378407, 93.695762370380891],
[122.28850921293144, 76.101379473190349], [111.44116718235543,
108.35150088493117], [138.55187585038368, 104.45109866815397],
[89.123185296043147, 151.19072505820475], [101.70113856203162,
143.16269317848082], [114.55904368474734, 137.03596375729882],
[127.5260977252027, 136.62440720393903], [142.15015468594385,
134.33539281866416], [154.35000323575321, 135.82860430555473],
[164.20085849796595, 139.78224358677733], [152.9774542793399,
142.98379202064962], [141.73178221104934, 145.86324454310341],
[129.89339680864276, 146.89033084663646], [116.84788403543834,
149.04075275643936], [106.82191699109006, 149.14242258364681],
[114.60339284933946, 143.21586094656988], [128.31056675771958,
139.4452901718596], [148.33878241574769, 140.53480603779201],
[147.93332321344963, 137.89989048828988], [128.69585663786603,
139.90709643494949], [114.63118953141685, 140.63329768649351],
[123.81172998652696, 98.785958550314348], [66.474208747599363,
63.358122307976885], [89.613458219896927, 60.741998702521187],
[90.438207912343842, 67.780375024366094], [73.297736628896502,
71.388966880916655], [176.21292587446089, 49.577879569149928],
[152.92815791080079, 51.050952892124485], [156.57901529439357,
60.189126505911844], [175.86218001261233, 60.708989122215144]],
"connery2" : [[38.892083339257844,
40.568761472443001], [29.90159331543386, 77.650979095829243],
[23.528785192881184, 115.12981090320817], [28.511131183389089,
158.48255423521496], [36.942695419670031, 190.0233172264432],
[54.458575857371784, 222.14890063102555], [83.272696884783187,

91

241.32312566364817], [112.34558466601413, 254.34619861333098],


[144.58533461942631, 250.67758868401037], [172.20420363672687,
233.81852073557391], [196.39312100566269, 211.34357793943363],
[213.39744139863737, 184.73519809603738], [225.21562242547819,
151.80094676818908], [237.24370618259738, 111.68508532117359],
[245.37037238466385, 76.747156060247008], [233.37702308878991,
66.751881991182429], [217.53786714161851, 58.032768064935894],
[190.31676158270122, 52.308575780288855], [169.41334844892879,
51.226316810323091], [56.207445417444667, 33.067483014583026],
[76.722796932348402, 29.047185245786149], [105.73804935320115,
31.249505073127093], [129.41744120282408, 37.429432344589621],
[76.681963278187865, 58.350090907959633], [94.19972974921599,
54.756572031752867], [112.85419644295345, 64.415693298960278],
[92.812398165291782, 62.397598103038298], [93.655368395257653,
58.161653341144778], [210.96205026792569, 78.004343128986662],
[195.75238522801715, 68.76760748433108], [176.43642892509493,
70.224445619890886], [193.68109207192683, 77.087571441960634],
[194.70712087330261, 72.862005768658676], [148.20208672391288,
58.342590915631767], [111.1666788930213, 106.63701529362415],
[101.34747511120258, 119.12987300043589], [104.18303077659665,
129.20360281985296], [133.37279277423349, 142.748980146029],
[157.93432226268496, 141.55894442135795], [168.96130581416642,
132.07242708249322], [164.20633959835496, 118.18083518929345],
[144.65602166235658, 92.397726364522015], [115.40494645905375,
126.40789286820008], [157.79608269264335, 134.75702279793697],
[85.980010160822758, 162.15639224332949], [101.64943872830327,
158.38505258879277], [118.67438165368489, 160.35871309389356],
[130.25722607258859, 165.38673650507471], [143.15742329539017,
165.77052618136571], [157.70242299467066, 172.33499834295802],
[169.65543648993273, 175.78855371525023], [160.12055822257562,
188.16869070735714], [148.14213249766502, 194.82664029567607],
[123.6042849464561, 194.88227565731569], [107.47564886902663,
189.02099163974216], [92.083113590444754, 178.87228804990815],
[107.8070847076981, 175.41059890627554], [127.02743901200465,
178.34303343927226], [145.81970631097616, 178.37106140001052],
[152.5287145895322, 172.6301131395058], [130.33035941222428,
168.52457058376751], [107.7206420350132, 162.47051940192065],
[139.33872973963111, 126.60083436107105], [83.34288190802836,
55.8538320861296], [106.32865532584162, 59.237712272335273],
[104.93444701975285, 63.759204900543274], [84.046862139237973,
61.775258429145531], [205.45785499618236, 72.338141123931806],
[185.39496033403927, 66.696155105024673], [185.06364946271444,
74.709457364532881], [201.62551705633905, 78.249786099181634]],
"cage3" : [[38.357056558682224,
60.736490607874416], [23.341327901797936, 107.25014599667472],
[18.296846321559066, 148.23051012644805], [19.372695643526168,
188.65305377967664], [29.154876750304378, 215.96034564242314],
[45.134310349980488, 244.36531182613257], [70.519067923334447,
267.83847469488006], [101.68753084001821, 281.0922742741248],
[140.7331873207979, 285.88371876848129], [170.9390562968122,
277.08040962953862], [197.87163563750002, 261.59418146285884],
[223.42845954976377, 241.97378591315569], [245.0650088791653,
210.18543074803304], [261.10462533802968, 172.38255310709295],
[273.10872642190981, 123.91021190431911], [250.76635857684363,
84.600787431964889], [234.09351530198521, 72.517706680712692],
[208.74167260911511, 64.247660836061527], [187.81514700728363,
58.544297226870881], [74.131483122576284, 36.136870472111582],
[95.844126758687452, 32.281398321513123], [122.56035690731997,
37.962543427439527], [148.22450319574315, 44.249023213088549],
[85.223771071744906, 58.544422052615509], [108.44657180031147,
54.503014392356079], [128.71885243916009, 71.094947200089337],

92

[102.01015040453876, 69.872705287553586], [106.35614075069611,


61.135360036022256], [231.12788939629235, 99.795903411403984],
[213.49537287525797, 83.776879991946686], [191.26433579749491,
88.068739788561743], [208.74485262843476, 100.64749621743501],
[210.3902447700176, 91.745721437553414], [165.11333999594746,
65.233933098272132], [118.44177482082158, 118.67444264582296],
[104.43633090065161, 134.36522676928988], [107.97325108027587,
153.94854060017767], [135.14700490709532, 162.46176003224451],
[158.25542163066774, 168.81168710778437], [171.23871364437443,
157.8702716949802], [170.99524963368106, 136.00154408059339],
[153.17970711274839, 104.6512535923592], [121.24856419365493,
146.72319602458541], [155.03701415731447, 155.47015160678404],
[78.466354770855915, 196.06457566218131], [91.746762577873142,
190.71906729876349], [115.16530841874146, 190.9990107540126],
[124.15308474531936, 197.67472452041352], [136.50232294953494,
199.494779982621], [154.59531097066568, 207.60344956896392],
[165.2203651574051, 220.13387490642199], [152.12241005492899,
222.37254974396703], [136.95812099553518, 224.79934977608076],
[118.62579187860695, 222.04126374309647], [101.43461433730506,
213.44877444745077], [91.126562884160748, 208.42063503351378],
[103.31382289348142, 200.40641231858996], [123.70959937134573,
209.25298000999445], [144.3127346555429, 213.11037420816461],
[145.01373850122738, 210.64398695827401], [124.5966930093344,
206.77316937277249], [104.34585866228781, 198.00179369859504],
[140.87145828311228, 140.52728839936404], [94.034520017012127,
53.724169619451033], [121.73270003511465, 62.449610686083915],
[115.01374220523665, 71.184949762616284], [90.815596125430076,
66.659246627086432], [225.11169678544977, 91.787112952908473],
[199.92938089835985, 84.173222767668918], [198.25457269780782,
94.35966863611155], [222.73697143561492, 104.07355685539949]],
"rihanna" : [[26.138899461407689,
92.244179099265835], [30.150033619898522, 129.0592834006242],
[35.996054826216913, 157.99930474933535], [45.509781735478924,
187.12127271304053], [60.51024161514006, 210.41325200694192],
[86.310688149068426, 227.46971998938116], [107.85974681746808,
236.69500599276591], [136.57644554048775, 238.10708866312754],
[165.62648705221295, 231.57806683999053], [188.3608395007787,
214.39011511507942], [207.93248607083333, 196.0814225694686],
[219.89916920545826, 168.58008860014098], [224.49883040486739,
138.90264901250617], [228.58281464622078, 106.91416429657839],
[224.58252481471797, 70.933146993653779], [203.3774978319762,
28.028820808172352], [181.58472787599737, 19.435310158112408],
[156.86417294526154, 24.460306030063659], [135.73914402023993,
31.456797488595342], [32.047262797597298, 50.543719104317915],
[40.464089467706167, 38.381365394715388], [66.342397552413019,
34.321110135743673], [88.515953347009969, 36.93324860750586],
[46.733268642989657, 78.712499539135578], [66.449686483581431,
65.373420492141349], [90.173907195079082, 74.9121559129796],
[66.233854603446957, 78.415688222479957], [68.270574612475599,
71.660416916015635], [190.65898690318929, 64.810998305632253],
[168.20638484997923, 55.804190409734566], [147.43315449749568,
68.626928898045307], [168.22673344465349, 67.61289342187888],
[166.51021546156483, 61.875220550023961], [118.92897147566528,
60.280657952102231], [96.897767488546208, 103.97035633816941],
[89.664096235805445, 122.34811624311288], [98.833438666909871,
128.43822554362711], [123.81326752339046, 129.33942642442472],
[151.23906851910579, 124.56706552807259], [160.80260431887578,
112.48823512650107], [149.53543511254858, 101.14056094329058],
[119.91425590973432, 81.776934802513281], [107.10091816874086,
119.93543263950561], [139.89073855497173, 114.97527848530341],
[86.039156734614494, 163.79526897618302], [100.31550207547357,

93

151.95465454080531], [115.33537786053085, 145.67621375202529],


[128.49927701873415, 149.08891090011926], [136.82856091872964,
144.23636993467616], [156.20890091990211, 147.83178979124301],
[174.55301109182807, 155.65761972225934], [164.99975808270366,
165.63417075097752], [149.04314047426175, 174.12550564044938],
[129.91702711147209, 174.845305670843], [113.34708735522268,
176.24295559630082], [101.03175759253789, 172.44295639648487],
[105.93344735335506, 160.34735779820977], [127.43487958488878,
160.81933686724085], [149.58356968953328, 156.11918541420829],
[149.5114621251295, 156.3177299583827], [126.90564735939108,
160.6358515740547], [105.55243401686153, 160.0615670038776],
[122.24009751272602, 109.67347000836308], [54.593084788445459,
70.431269150370369], [79.107238894532827, 66.533611837568742],
[80.595062712249302, 75.052674625787859], [57.682176074481895,
78.957592891796779], [183.02872671333918, 57.096961590684487],
[155.0208679018707, 60.611070713694659], [157.0325640646339,
68.513983801624093], [181.04275593545705, 66.607854469117726]],
"queen" : [[23.505386602589198,
50.457444393308663], [23.770997513824113, 79.750010592355807],
[27.113644647783133, 107.05392377626163], [35.321303628622132,
136.44305205172321], [47.334549538017711, 159.18765164959615],
[64.199292851437008, 177.03373895127152], [84.765625678051379,
191.83108912146804], [109.28402179239941, 196.45906084532959],
[135.9359304546071, 190.54807551773638], [160.92638460512586,
174.43015267056262], [180.10178679830051, 153.97905507448695],
[192.41726401346494, 126.67359148115031], [197.16242118270173,
101.15454548575792], [197.64413760608852, 70.312868465894098],
[192.53172579302651, 41.967007222640632], [169.31080503903837,
22.162418347767982], [154.0273734545479, 18.374726602295368],
[133.42613502058202, 22.96266560761353], [120.45410689424983,
25.502895906530568], [31.44546511558309, 31.945208272929221],
[46.768848813254607, 23.581632433649531], [66.673207984269141,
24.172974522013021], [81.626067130688511, 27.638789633838883],
[47.947701102202586, 47.681543362179184], [60.623376724198778,
41.633656006991998], [79.36915359618331, 45.721067869780654],
[62.330186344080488, 51.371860492471512], [62.745750219507102,
45.599559964606215], [158.19258779162885, 45.300672194745914],
[140.60340929518344, 38.45229892703685], [125.7806082208532,
46.347477725027204], [142.34288582277316, 50.698235503409762],
[142.60871772009955, 44.437882664899462], [99.97940419106925,
41.514879333955264], [82.213624624444435, 82.354789460933432],
[75.65401524869975, 96.278063325340668], [82.508445343639551,
102.11984542944111], [101.60744302836173, 105.94037459973111],
[122.63043456337431, 99.592250218637901], [129.62786603125369,
93.957718348243077], [118.99818032302022, 81.401385613867888],
[100.04956768903412, 67.861677148659396], [86.313389423664717,
98.430691407496624], [115.53309045382008, 97.1560811012248],
[70.196138989073745, 129.52006520479512], [82.774122202456056,
125.37454913886643], [95.124174822972009, 124.78123204792121],
[103.90869760615385, 126.2571438963663], [111.25150881410894,
123.17288375183074], [127.28656888633316, 124.55474856966089],
[144.31109846428922, 128.65315176422104], [133.34586280219827,
140.30073546752016], [120.84012623666604, 147.41887856217244],
[107.03519115747525, 149.60767216282352], [91.740550885270409,
146.68583392233438], [80.326767974424286, 141.46630043417008],
[88.568623957901309, 136.39444745405399], [105.46004677224801,
140.46140391578234], [123.31897526995601, 138.15333836238494],
[122.70288882671514, 128.17663770168849], [103.81577906858274,
129.49492394511066], [86.215486592429272, 129.49235140135801],
[100.17418968456138, 92.838046187331713], [53.784991837303153,
43.657281631162277], [70.495495697799754, 42.176471952281418],

94

[72.847366600432451, 48.547152030252391], [54.136195115745608,


50.027845814704847], [150.39702665408328, 39.876052149764064],
[131.19169764996349, 40.900020983495949], [133.56176420233407,
49.52351354943147], [149.76874192232191, 48.5000219314216]],
"obama4" : [[20.483665550074608,
53.183692860767394], [24.361922673852241, 95.737273870516105],
[30.400959413822353, 130.45754077869711], [41.242349718827768,
173.04726502529044], [58.105008569484156, 203.7660013530558],
[76.869655382911503, 226.34291300753259], [99.369341611341881,
255.0713395857554], [139.74120550264209, 263.76162554942738],
[171.32947217998174, 255.46957428093305], [199.946894095613,
226.62339957345694], [221.49837040108935, 199.79835948444554],
[240.08516723936782, 168.18189730988399], [252.08395469198265,
131.21374537265351], [258.36170743521484, 90.380588166058288],
[255.10754458650274, 42.584944707292443], [231.75249195960055,
45.327439832074035], [208.7290513846105, 33.264165113810314],
[182.45184021795453, 34.887902751598574], [163.08711212720985,
36.03634039159865], [45.239265084152109, 48.306833774880189],
[61.461858247924326, 37.834099965504009], [86.827961811524062,
37.197019300749332], [105.91824585785361, 37.88368161363735],
[62.860924946003244, 61.188846253618586], [80.619662775077074,
51.747190870172624], [103.93398842852524, 59.997457002440939],
[81.751456803195623, 64.255501456018763], [84.004294538216001,
57.077229167297531], [211.98838032569785, 57.593772126059918],
[191.5778679580265, 47.983763125242731], [170.38855049276546,
58.461369542688253], [191.9441136281869, 60.225926779697986],
[191.92669412372422, 52.579307802528767], [134.66117725008127,
47.998802609275117], [100.70375436244497, 117.18170772223409],
[96.359586237232236, 130.97608621290914], [104.08684841884893,
141.69896624605406], [131.24128684772495, 143.97185685417674],
[164.76450358310424, 138.26000471129672], [176.92626974984935,
126.08237618839462], [167.22572255493887, 112.72928720583801],
[134.0611802462972, 85.717075270380818], [114.33387220509169,
133.05178089828468], [153.76794949662624, 131.67190072058332],
[88.866522295425142, 180.54393261075492], [104.46692763753509,
175.38305552650226], [121.43438355304571, 169.84539945272661],
[132.37535179506003, 171.81705846390579], [149.18563061624394,
166.35416111906289], [167.16644078199599, 170.78387842411823],
[189.16695843585643, 176.57652671573587], [171.83553768789335,
187.7115867136792], [156.33804805643729, 195.81101875373039],
[134.27563409833002, 201.38739357915634], [117.15337885298841,
196.70731823359964], [103.96847180524558, 188.68352736101971],
[116.76487739956575, 181.44052669308485], [135.74530154751699,
182.90627748639344], [153.63331858186731, 179.62109542567683],
[151.88019838003063, 178.74543573334981], [135.17389732718308,
183.56591812464339], [115.77196402700586, 181.24528883502023],
[132.4588789817806, 125.30097836947944], [70.691361409540519,
55.425799087708185], [95.074744482330715, 52.724441664122146],
[91.093459751654223, 62.828111718395917], [70.206999478716284,
63.420717668699439], [204.23047792617393, 51.746876200870737],
[177.48356609989082, 50.074372448180128], [183.61325430243852,
59.696924337487069], [203.36282510792634, 59.961322827348759]],
"picasso1" : [[36.250450718573873,
79.124566327720288], [35.119608310582322, 96.597861806811181],
[36.404659318616737, 113.76840192150527], [38.224159134985243,
131.11062469484807], [44.454529797225646, 154.1814209057838],
[58.375246123280007, 169.49596919632819], [72.97988779636654,
180.23977668215664], [87.756188367409294, 185.56552853643095],
[105.03241234408378, 180.51444743653224], [122.265469633262,
174.06398165224769], [135.31714855705121, 162.76762378894259],
[146.88777632654526, 149.70727178445324], [150.20000560168543,

95

129.10862928363522], [152.56739151849726, 107.17828639825538],


[157.91289561898384, 85.214768152427581], [153.62665196335627,
77.105422620440464], [141.61928142399029, 70.524665935976373],
[126.595892772441, 69.905523578840757], [116.49010775841327,
73.31386968143282], [49.0086575832958, 70.235265794279542],
[62.701753537480243, 60.550337510943265], [82.1035199652176,
62.144635165724765], [94.457612858326257, 69.990264611588202],
[55.814352473139024, 86.02727936226367], [71.316173892786423,
81.800811911371824], [88.080400330799591, 88.20180782468745],
[70.246724559943019, 94.071810094606263], [71.121648446471397,
85.582545703028842], [148.10348497461655, 92.462063312908725],
[133.05192015872387, 83.73718604655916], [116.27558519146325,
91.192600450046228], [131.88263279775612, 98.993646865368106],
[131.78123048704896, 89.404774477148408], [105.51315626215361,
81.569662962447211], [96.191534478817118, 120.50668746252984],
[90.199164697849596, 125.37517630957703], [93.463243841115599,
129.51593720857423], [103.40246819387983, 129.77184869247793],
[112.65390571265101, 129.56664287134106], [113.58273157049868,
125.83472002370991], [112.97511629728987, 120.82815243119251],
[106.03098831604788, 102.16807129228334], [98.211706690369823,
127.97534492896636], [107.00121682175407, 128.76139115375773],
[81.658108662587608, 148.26923759836396], [92.806273612808184,
144.41797262560891], [98.041354041956538, 142.78033417226806],
[102.38978597981389, 145.68476515395253], [106.77039887493248,
144.55888963561441], [111.2028829073426, 146.72397791119556],
[118.41047414259552, 151.37431914236606], [114.09050148249918,
153.5845427811754], [108.26749560913638, 155.60812550724742],
[101.03855866647899, 155.85689374282265], [94.667308403540687,
154.21614129562002], [88.606207885913079, 152.3634368283987],
[94.799176802224451, 147.78175686140321], [101.61589425206924,
148.37134474983333], [110.19810766615751, 149.17710215768849],
[110.00140558086673, 149.42392294958483], [101.78004560465695,
147.81385618194679], [94.666393329457804, 147.88634305613706],
[104.96348601661472, 123.47557663615419], [63.067424126991767,
83.412995811464754], [79.698359035226673, 82.50077801608326],
[80.163162608568456, 92.634906745609783], [62.531657767831675,
91.548319806853101], [142.57740074574272, 88.097933442704544],
[123.16502620504644, 85.963352957311599], [123.58158606810653,
97.591877049766168], [140.99420788006387, 96.726951520247638]],
"scream" : [[31.036290655849882,
57.432857152986685], [36.834032422703402, 76.616090763423301],
[44.144879197624306, 91.506035663960802], [56.746870626966768,
106.12350665968165], [63.525573844882473, 121.99269842503458],
[69.2934094352062, 141.18816557433274], [79.116034591995231,
158.27345628505338], [95.444768276521444, 157.85798622717158],
[112.1506100202503, 149.53119369985041], [120.19223108149427,
133.77442783766503], [120.98364439956012, 118.34214249063547],
[126.09006592863452, 102.16079319696235], [136.11638867777555,
90.042725252145431], [143.07386026688062, 75.600333966055501],
[143.83480182971522, 54.469443259083619], [133.78044168407791,
38.927078049915451], [116.88883196831546, 29.805997108581423],
[100.37012716461871, 31.831740142580585], [85.39723434749834,
42.341129078554331], [40.717793723347995, 43.305563127634542],
[48.744681128699852, 37.771923766655192], [57.448931896748704,
36.028754590906701], [67.464345519404787, 36.944607085351322],
[45.385363552887199, 58.225754147134666], [54.363960101074014,
47.630931768034003], [68.011017790419004, 54.583990783711471],
[58.120050008047329, 62.745638214068549], [55.616718436597296,
53.995790698964527], [122.66684453667131, 54.6831401033742],
[110.90016888640474, 45.569147756531351], [96.234198458489033,
53.677715067572848], [108.49190790972344, 62.644313336393992],

96

[110.33329194240295, 54.935130623390222], [80.887741592339665,


51.027213274581243], [76.364796231779138, 68.40676367915853],
[71.204026202304306, 77.172050050826158], [75.730620606370721,
82.644032983592723], [87.363757439691426, 80.118716444055792],
[98.704261825861266, 80.021192400105463], [100.92981427616351,
75.460833622671146], [93.832797746290964, 66.709039647758487],
[82.448627671183701, 59.880239108276982], [78.635928103659296,
73.849587320332546], [92.627257877148452, 73.43767426025039],
[79.131242507468116, 114.47649461874275], [77.082061781015526,
104.8161820064411], [76.86256899541047, 91.51976352151155],
[84.492130686253887, 87.376289229573757], [89.954070974658805,
90.754539182117583], [96.555921994018263, 100.64436225867991],
[98.440888036356, 112.45487645254397], [99.900677251741001,
118.69433160303333], [97.588402646172568, 124.71623282477302],
[91.597980889907518, 126.41777298016024], [84.533931967288538,
127.61556713904764], [79.240345390611509, 121.19778971162847],
[83.178935170207694, 120.97334887551744], [90.622988915812243,
121.32946906512535], [95.211974749360394, 119.17107481925299],
[90.610722471562042, 96.597036966133828], [85.032665543272103,
94.424007443444765], [80.833795006309913, 101.09683414893499],
[85.305504524124245, 72.452653823137268], [48.8748794470348,
52.429091513207823], [63.68702721228027, 48.108214917609644],
[66.062515145830616, 60.166087383119986], [51.2501982134619,
62.489540249221989], [117.78390022622665, 48.625670298558617],
[103.06761868980499, 48.623588434563402], [101.36381278664584,
59.660098601097076], [117.07959483560742, 60.662984572138043]],
"terminator" : [[29.076884732031772,
71.67890495708096], [27.66651993257193, 111.97958383082613],
[32.905495727938842, 143.74759287325199], [41.548602943722187,
184.11191523512548], [57.134123028769864, 212.96132714313779],
[85.982596883100427, 233.23682483532389], [116.34553106231533,
252.07189468414344], [153.54377487815492, 254.19994252292111],
[184.09352786394243, 250.19280744913965], [210.84006513830786,
231.78958626538036], [230.33265432712187, 207.95546707713771],
[242.54473105521458, 181.16454996007155], [245.32603716786156,
139.23222747588432], [253.95701774571654, 105.75356333489501],
[250.16872236069304, 65.614622446558542], [234.42162441623111,
41.376144700389091], [218.06038382338016, 36.763971825401342],
[195.01785757186678, 35.830381277151389], [173.22532214596566,
34.948429471706561], [54.903911233483029, 46.44126936726903],
[74.831645200221715, 38.453426351873134], [97.147393013378746,
35.780078496224263], [124.15086404891906, 35.195299880035805],
[66.35520762891224, 68.235316884765297], [88.846275187033712,
57.941876489833845], [109.10692456289365, 65.835365585188669],
[89.15198347590956, 71.177597719421669], [88.362391942502256,
64.59180321109983], [223.52418336992747, 66.464653942855051],
[200.72181416528224, 58.073962248085365], [180.51423847597891,
65.002569315598549], [201.60598302791442, 70.107080712007587],
[201.4188717262528, 64.775640131702488], [151.03576003916953,
45.081162477481598], [123.46403491514627, 106.14140125029522],
[119.73138344106076, 117.43345384315626], [125.15573426423208,
129.00558710238695], [156.06226938811682, 127.12365384578027],
[178.19840010320991, 126.83676679574947], [183.26702924895841,
115.66950743874682], [175.51141450984255, 106.54676093041451],
[151.75947907777766, 76.366817652668487], [133.66421579983097,
119.32339634260134], [172.1834824765383, 119.87854085001544],
[107.48695740367185, 177.84786130901512], [119.72239618002311,
163.21478187250497], [140.4464890346631, 155.71112137112985],
[155.86678473236145, 157.98177593573888], [167.21471198020845,
154.86495601683998], [180.68374974978832, 159.73999260624254],
[190.76005528035921, 174.67434883370834], [180.73253431596419,

97

176.39562238973116], [169.53742410945182, 178.06866551441919],


[155.53681594702357, 179.73851637572324], [141.80213459545843,
178.11191356675113], [126.33903348640217, 177.0074496842052],
[132.38439794118267, 166.9144754158774], [154.18525275215882,
167.75142144628433], [171.26254237748122, 167.51576938990513],
[172.534822324375, 166.51169079958765], [154.17356764276303,
166.77640382116056], [132.74611931034815, 165.54314795883778],
[153.13151808703924, 107.35065481861218], [75.600007764156032,
61.08502670255362], [100.47692695245246, 59.887169821044154],
[99.128136594613807, 69.002790596812332], [76.251785226012998,
71.202785857452454], [213.62188629502043, 60.266713925593479],
[190.61716649430633, 59.53824381943511], [190.06078776389984,
69.052650607094705], [212.06614469025487, 68.784081158860744]],
"chuck" : [[23.985805140787811,
59.253092736495404], [27.152914142356281, 93.63850488776103],
[34.01220073959206, 124.65777588132323], [43.185644242726241,
161.9772579423547], [61.209744322279292, 192.42432570956339],
[81.37821841704411, 220.37100316087003], [107.92580934104717,
237.80975318878194], [140.88839198974878, 241.278807347677],
[167.70469646738874, 234.01970282186772], [186.12365924246313,
213.70594260547796], [202.80437939194087, 190.64053826009655],
[217.69508138129819, 155.70072689125635], [221.02696388149508,
119.50512599746469], [227.99422254386025, 81.43151669889221],
[227.11130532385494, 46.18417717200532], [207.21555625045997,
33.175332640476], [194.56294229742934, 28.937253432404674],
[174.00649178397012, 27.028488506511849], [156.47566594458243,
32.350419791450179], [47.532877369699492, 42.421078138488781],
[63.923256040387145, 34.721870564834518], [84.521999671791235,
28.68707065058706], [101.15791969739783, 30.213188331517443],
[70.764074281840976, 51.416777160605335], [86.002488801591127,
44.424929334942277], [102.96119178404712, 53.160641855627574],
[85.60397397751052, 55.234740063145978], [86.010308656883879,
49.899172374324678], [190.92358255141565, 49.397451262299313],
[175.1523746520156, 41.900642395463876], [158.44345834031955,
52.154661706767172], [176.47309137989373, 53.014180036617432],
[174.43308832832275, 47.307219358571558], [132.46182130918601,
45.48437589722576], [108.69786009928927, 99.545905831905316],
[103.11665337522604, 113.75249817536462], [111.34508738112095,
123.58043415652844], [140.30363074789989, 128.37262124829522],
[163.09709355203404, 119.0354984962861], [168.93097359374573,
108.93962862026251], [163.17674412901442, 97.84644989180623],
[136.28156859047635, 77.887545322684673], [121.70408833473726,
123.07084388960436], [155.85885440334405, 121.00625017414006],
[95.996752168226521, 161.32424774652623], [110.17525522629637,
156.4703757753677], [124.30175841524158, 153.55515190825861],
[138.00204524415497, 153.64274134883692], [150.79297368282508,
150.23231929252609], [162.7406848240513, 149.85132514087474],
[176.07303322566077, 151.81058946642867], [168.83777545300831,
164.0342671400889], [155.10895519199389, 171.80029333476506],
[138.09166004169032, 175.18545713793497], [123.90094363765843,
175.40470843963408], [108.39952344275034, 170.40601225857262],
[119.72606830073107, 167.28994293469788], [137.95384981384524,
168.64939698384137], [158.54405813052577, 165.50059529860471],
[157.88012349108675, 151.99297197119006], [138.30132055467104,
157.65544747958882], [117.83502139036227, 157.58320456094589],
[138.43867461393214, 113.41758462162812], [75.885110165472895,
46.920392101397766], [96.982049671082919, 46.292338804561751],
[93.782070842166888, 54.197829817186403], [77.685715189360593,
54.825324576762569], [183.53723703826685, 44.14812614348557],
[166.29837686271119, 44.526609395251143], [167.45958694297553,
52.084354270786775], [183.69784620690714, 51.704878940413039]],

98

"walter2" : [[21.060764903593935,
23.625922265374243], [24.306589250104111, 82.418736978583837],
[29.887480558415291, 123.52324050386761], [39.831216823892362,
169.58896662877407], [56.335070257713795, 208.02264871738436],
[80.83703098412272, 239.09972028159933], [112.71581076572778,
260.86442641371349], [148.15849351544631, 266.69887307481594],
[187.92956781495144, 259.94808309698487], [224.28242219428836,
232.92409488998584], [248.61360434331704, 197.4132216415324],
[267.6255386426007, 159.22848713841142], [274.06946800796993,
115.04205523453288], [279.57264995946605, 75.577994810142314],
[274.8147191886797, 27.93465035602847], [243.21321805049308,
34.977887137176154], [222.77074074138181, 27.896989700591064],
[190.0620481119081, 30.307609477713669], [159.27010163455151,
35.824855447032391], [51.033153870664592, 38.112001064409583],
[75.392081525881991, 35.207713004503645], [102.74022206320058,
37.331330371284338], [124.56616025441463, 38.787179979952285],
[67.451381950900242, 57.279940574514285], [90.044614607889713,
50.578228454933793], [111.78861952878373, 57.042466275764184],
[90.903644751441476, 61.901327302928138], [90.715389774152072,
55.427091197335699], [223.99115821955013, 52.230403503055442],
[205.18136904851377, 47.795771446298119], [184.90200898390299,
54.36443314080293], [204.67995257670333, 57.277939005103178],
[204.92195881859544, 50.712535873236902], [146.50907007729293,
46.432109337738268], [115.95255333726485, 107.46593045529727],
[109.22792349913794, 119.47849063536196], [117.00821443824393,
134.84341026421072], [145.67296091894715, 139.65462387898862],
[173.67398162073596, 137.75538299827045], [185.00619633858076,
121.44588720141769], [180.64955597511778, 108.4547161320798],
[147.27934367148265, 85.136485659341048], [124.32188592953989,
129.20306658959251], [167.29393856301289, 130.98984492081911],
[101.59640357940233, 178.49694962096316], [118.21488930910681,
170.49617831223611], [139.18293919359641, 169.52754924913722],
[151.13320163675684, 173.77693897734923], [167.32315821430757,
170.41084550370888], [182.37144722622213, 172.04427561978318],
[198.17756373260085, 178.48935722147763], [184.440295252439,
186.17852019611308], [168.46308888233028, 189.07826517145685],
[149.98168191113766, 189.67271148067312], [131.94804230553046,
187.67924933109754], [115.53452060145878, 185.3486212656689],
[126.11701238101571, 180.30913427171828], [151.51451552828283,
182.42858464837599], [175.33473635294803, 181.769054498201],
[176.96189091245589, 177.03898480289513], [151.40990278903843,
177.58200927291426], [127.15568541835768, 176.24970135595123],
[147.26055194223767, 122.55189537474888], [74.747311503817315,
52.428814802906686], [103.91716767645684, 51.310986682531166],
[102.84404568037712, 59.974636811905299], [76.675078380855666,
60.093874542162325], [216.58585024902322, 47.512012033316537],
[190.54061564242585, 48.580342228676585], [191.79112935486376,
55.322342001097468], [214.83596488608993, 56.255513236279938]],
"audrey" : [[29.74201740403646,
63.58838131299683], [32.135740245991599, 98.613580728522948],
[39.926486700973527, 142.66741859878613], [46.051376346280165,
185.19751106090678], [63.623885970848306, 221.21082623221213],
[92.686071409745011, 246.75195165866961], [124.31266068980059,
268.32269819176895], [159.08115584618832, 276.8182094669599],
[193.01372611356055, 271.19451253588267], [220.73964850426626,
251.23315855606597], [249.37653785044409, 220.99473411123051],
[262.56272926082778, 184.02931054521218], [274.46785237450297,
145.09243674243754], [286.71422071660493, 100.2191807024135],
[287.7724614993711, 67.093735883445845], [273.08419909909355,
58.949447547158684], [250.35119471727239, 46.547177746833199],
[227.88483875688155, 51.863141039656796], [201.92763554902524,

99

54.635918821225715], [50.207093876417957, 43.532664996747542],


[78.106228477816103, 39.524315405279566], [110.54774174250323,
45.635392409130048], [135.80324104447095, 54.83859321342041],
[80.208953800441719, 83.486704599142797], [103.2843062554636,
71.77563604011084], [130.37335751351947, 93.351828892065782],
[101.37155395907916, 97.268693939422747], [103.77768051230873,
78.554240071733545], [246.69639088723869, 90.839855800811847],
[225.25431248616547, 79.371020311284838], [200.21435196089101,
98.005155765703194], [227.73999275494873, 103.13681628226215],
[226.06528007794577, 84.737881341868274], [170.2704842069295,
87.241173044027562], [136.73140157570418, 155.55089637183414],
[132.09382016348263, 166.28137163294355], [141.43437220076765,
179.71853115783472], [168.84018353954804, 185.51893631975383],
[195.57024175323983, 180.96444682513931], [200.63701169781223,
171.50291787670471], [196.03834636609736, 155.55926335687627],
[171.53575860945466, 129.05860619902546], [151.91223102812063,
171.32412239283428], [186.99889102154822, 171.94139857304066],
[117.36179100195926, 210.57248720067804], [132.24409741439899,
205.79192498435566], [151.95455263416062, 203.25064014467529],
[165.61565000621329, 208.18658812822247], [181.73633661629219,
204.11786374216797], [194.71091994807995, 208.09809058994574],
[208.15078953905629, 212.57790820835453], [193.07898694502654,
226.67843340292291], [179.59750146882573, 236.19115922247897],
[163.22005286691325, 238.45845823523985], [145.14731000170292,
234.92524246489165], [132.35629580062368, 227.3232920714367],
[145.46895415593832, 215.5609803328374], [164.98592388769322,
216.32998112652183], [182.14032562432749, 217.3077976017484],
[183.73772138569666, 217.00947047307966], [164.55379748244519,
216.51396287362655], [145.7179313684785, 215.79854206584145],
[171.13908085531165, 165.20445766092308], [88.246693449260022,
75.136292959533421], [119.33001418358253, 80.065297266301059],
[116.37014577148472, 95.815825381060108], [88.287291370337073,
92.88465259927068], [240.47641466360238, 82.609923128584455],
[208.73309300337735, 86.192129111264819], [212.47694784065465,
102.57941207015807], [240.22165570085622, 99.99430087462639]]
};
var images = ["average", "terminator",
"walter2", "clooney2", "bieber", "kim", "rihanna", "audrey", "bill",
"connery2","cage3", "queen", "obama4", "chuck", "monalisa",
"picasso1", "scream"];
var currentMask = 0;
// canvas for copying the warped face to
var newcanvas =
document.createElement('CANVAS');
newcanvas.width = vid.width;
newcanvas.height = vid.height;
// canvas for copying videoframes to
var videocanvas =
document.createElement('CANVAS');
videocanvas.width = vid.width;
videocanvas.height = vid.height;
// canvas for masking
var maskcanvas =
document.createElement('CANVAS');
maskcanvas.width = vid.width;
maskcanvas.height = vid.height;
// create canvases for all the faces
var imageCanvases = {};
for (var i = 0;i < images.length;i++) {
$("#"+images[i]).load(function(obj) {

100

var elementId = obj.target.id;


// copy the images to canvases
imagecanvas =
document.createElement('CANVAS');
imagecanvas.width =
obj.target.width;
imagecanvas.height =
obj.target.height;
imagecanvas.getContext('2d').drawImage(obj.target,0,0);
imageCanvases[elementId] =
imagecanvas;
});
}
var extended_vertices = [
[0,71,72,0],
[0,72,1,0],
[1,72,73,1],
[1,73,2,1],
[2,73,74,2],
[2,74,3,2],
[3,74,75,3],
[3,75,4,3],
[4,75,76,4],
[4,76,5,4],
[5,76,77,5],
[5,77,6,5],
[6,77,78,6],
[6,78,7,6],
[7,78,79,7],
[7,79,8,7],
[8,79,80,8],
[8,80,9,8],
[9,80,81,9],
[9,81,10,9],
[10,81,82,10],
[10,82,11,10],
[11,82,83,11],
[11,83,12,11],
[12,83,84,12],
[12,84,13,12],
[13,84,85,13],
[13,85,14,13],
[14,85,86,14],
[14,86,15,14],
[15,86,87,15],
[15,87,16,15],
[16,87,88,16],
[16,88,17,16],
[17,88,89,17],
[17,89,18,17],
[18,89,90,18],
[18,90,22,18],
[22,90,21,22],
[21,90,91,21],
[21,20,91,21],
[20,91,92,20],
[20,92,19,20],
[19,92,93,19],

101

[19,93,71,19],
[19,0,71,19],
[44,61,56,44],
[60,61,56,60],
[60,56,57,60],
[60,59,57,60],
[58,59,57,58],
[58,59,50,58]
];
function drawGridLoop() {
// get position of face
positions =
ctrack.getCurrentPosition(vid);
overlayCC.clearRect(0, 0, 500, 375);
if (positions) {
// draw current grid
ctrack.draw(overlay);
}
// check whether mask has converged
var pn = ctrack.getConvergence();
if (pn < 0.4) {
switchMasks(positions);
} else {
requestAnimFrame(drawGridLoop);
}
}
function switchMasks(pos) {
videocanvas.getContext('2d').drawImage(vid,0,0,videocanvas.widt
h,videocanvas.height);
// we need to extend the positions with
new estimated points in order to get pixels immediately outside mask
var newMaskPos =
masks[images[currentMask]].slice(0);
var newFacePos = pos.slice(0);
var extInd =
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,22,21,20,19];
var newp;
for (var i = 0;i < 23;i++) {
newp = [];
newp[0] =
(newMaskPos[extInd[i]][0]*1.3) - (newMaskPos[62][0]*0.3);// short for
((newMaskPos[extInd[i]][0]-newMaskPos[62][0])*1.1)+newMaskPos[62][0]
newp[1] =
(newMaskPos[extInd[i]][1]*1.3) - (newMaskPos[62][1]*0.3);
newMaskPos.push(newp);
newp = [];
newp[0] =
(newFacePos[extInd[i]][0]*1.3) - (newFacePos[62][0]*0.3);
newp[1] =
(newFacePos[extInd[i]][1]*1.3) - (newFacePos[62][1]*0.3);
newFacePos.push(newp);
}
// also need to make new vertices
incorporating area outside mask
var newVertices =
pModel.path.vertices.concat(extended_vertices);

102

// deform the mask we want to use to


face form
fd2.load(imageCanvases[images[currentMask]], newMaskPos,
pModel, newVertices);
fd2.draw(newFacePos);
// and copy onto new canvas
newcanvas.getContext('2d').drawImage(document.getElementById('w
ebgl2'),0,0);
// create masking
var tempcoords = positions.slice(0,18);
tempcoords.push(positions[21]);
tempcoords.push(positions[20]);
tempcoords.push(positions[19]);
createMasking(maskcanvas, tempcoords);
/*document.body.appendChild(newcanvas);
document.body.appendChild(videocanvas);
document.body.appendChild(maskcanvas);
debugger;*/
// do poisson blending
Poisson.load(newcanvas, videocanvas,
maskcanvas, function() {
var result = Poisson.blend(30, 0,
0);
// render to canvas
newcanvas.getContext('2d').putImageData(result, 0, 0);
// get mask
var maskname =
Object.keys(masks)[currentMask];
fd.load(newcanvas, pos, pModel);
requestAnimFrame(drawMaskLoop);
});
}
function drawMaskLoop() {
// get position of face
positions =
ctrack.getCurrentPosition();
/*for (var i = 0;i <
positions.length;i++) {
positions[i][1] += 1;
}*/
overlayCC.clearRect(0, 0, 400, 300);
if (positions) {
// draw mask on top of face
fd.draw(positions);
}
animationRequest =
requestAnimFrame(drawMaskLoop);
}
function createMasking(canvas, modelpoints) {

103

// fill canvas with black


var cc = canvas.getContext('2d');
cc.fillStyle="#000000";
cc.fillRect(0,0,canvas.width,
canvas.height);
cc.beginPath();
cc.moveTo(modelpoints[0][0],
modelpoints[0][1]);
for (var i = 1;i <
modelpoints.length;i++) {
cc.lineTo(modelpoints[i][0],
modelpoints[i][1]);
}
cc.lineTo(modelpoints[0][0],
modelpoints[0][1]);
cc.closePath();
cc.fillStyle="#ffffff";
cc.fill();
}
/*********** Code for stats **********/
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild(
stats.domElement );
document.addEventListener("clmtrackrIteration", function(event)
{
stats.update();
}, false);
</script>

BLOK KODE 6:
Script Masking Wajah
<script>
var vid =
document.getElementById('videoel');
overlay = document.getElementById('overlay');
overlayCC = overlay.getContext('2d');
var ctrack = new clm.tracker();
ctrack.init(pModel);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild(
stats.domElement );
function enablestart() {
startbutton = document.getElementById('startbutton');
startbutton.value = "start";
startbutton.disabled = null;
}
var insertAltVideo =
function(video) {
if (supports_video()) {

var
var

var

104

if (supports_ogg_theora_video()) {
video.src = "./media/cap13_edit2.ogv";
} else if (supports_h264_baseline_video()) {
video.src =
"./media/cap13_edit2.mp4";
} else {
return false;
}
//video.play();
return true;
} else return false;
}
// check
whether browser supports webGL
var
webGLContext;
var webGLTestCanvas =
document.createElement('canvas');
if
(window.WebGLRenderingContext) {
webGLContext = webGLTestCanvas.getContext('webgl') ||
webGLTestCanvas.getContext('experimental-webgl');
if (!webGLContext ||
!webGLContext.getExtension('OES_texture_float')) {
webGLContext = null;
}
}
if (webGLContext ==
null) {
alert("Your browser does not seem
to support WebGL. Unfortunately this face mask example depends on
WebGL, so you'll have to try it in another browser. :(");
}
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
window.URL =
window.URL || window.webkitURL || window.msURL || window.mozURL;
// check for camerasupport
if (navigator.getUserMedia) {
// set up stream
// chrome 19 shim
var videoSelector = {video : true};
if (window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
var chromeVersion =
parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1],
10);
if (chromeVersion < 20) {
videoSelector = "video";
}
};
navigator.getUserMedia(videoSelector, function( stream ) {
if (vid.mozCaptureStream) {
vid.mozSrcObject = stream;
} else {
vid.src = (window.URL && window.URL.createObjectURL(stream)) ||
stream;
}
vid.play();
}, function()
{
insertAltVideo(vid);
document.getElementById('gum').className =
"hide";
document.getElementById('nogum').className = "nohide";
alert("There was some problem trying to
fetch video from your webcam, using a fallback video instead.");
});
} else {
insertAltVideo(vid)
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className =
"nohide";
alert("Your browser does not seem
to support getUserMedia, using a fallback video instead.");
}
vid.addEventListener('canplay', enablestart, false);

105

document.getElementById('selectmask').addEventListener('change'
, updateMask, false);
function updateMask(el) {
currentMask = parseInt(el.target.value,
10);
switchMasks();
}
function startVideo() {
// start video
vid.play();
// start tracking
ctrack.start(vid);
// start
drawing face grid
drawGridLoop();
}
var positions;
var fd = new faceDeformer();
fd.init(document.getElementById('webgl'));
//var bieberpos =
[[115.9752686028232,328.6220466908972],[119.22873121946967,374.408588
52922236],[131.1565130945076,417.23833371292824],[147.46691862513703,
458.8532123608701],[169.12631494681284,491.1972025630235],[195.439042
17855416,516.328978933631],[225.12865446493407,535.9062523012337],[26
2.04556382915666,540.3069324850155],[300.94141109040174,527.850239914
7961],[332.9603108915372,502.45220152142446],[358.8360460728861,471.1
9379837598467],[376.30594053223126,432.7368076223554],[382.6701756289
5774,386.092455079847],[382.9572691840467,340.6309871594118],[373.921
8117623584,294.7317621266673],[336.1771287095879,277.33615469931993],
[309.0591744841313,265.48318334798023],[280.18008080721654,270.411336
08650136],[256.43572723795205,288.00624486316775],[132.78340927208725
,302.3508622540975],[152.12755213329575,285.64501141366554],[179.0052
1938859092,283.71128940592473],[205.2906738672715,295.0025921899086],
[153.280095626718,326.6176205427562],[173.66825536827957,312.37635516
179034],[200.5039461913669,321.80135395397144],[176.4252911165302,331
.5053440165448],[175.60476729990694,320.7103852530686],[320.095493690
69657,304.98353187039095],[293.8708067688545,296.76097677136033],[271
.58562891677826,313.04623730551765],[297.0041924786207,316.0129930023
768],[295.5198902690135,305.2334114426537],[219.39189145138596,322.52
490657195426],[213.12903160458814,372.68944673895106],[204.2537852794
3315,395.19379951207986],[216.42423446106187,407.4119870829318],[242.
53049164091706,409.5633258220383],[271.44166574243314,400.85944063662
67],[281.0747413420262,385.33753840829905],[264.93761588662034,366.00
82686027026],[248.4222279939238,318.65718124206103],[221.196960503533
86,400.1917656470539],[261.194844263039,394.3039377608819],[205.58562
543311808,454.0404194376248],[219.45570688767742,443.2933320382955],[
235.11772368281123,437.7856722052561],[247.04484871943168,439.0481001
020766],[258.89570167366736,434.78235106489905],[278.09912572601576,4
36.0808959514672],[299.3034775622639,442.54677422653293],[287.1187997
918484,455.81576684891434],[271.34249957002703,465.51172329290904],[2
51.61268198682447,470.44097715445434],[232.73570674290363,470.1580146
696677],[218.10425477812518,464.10041259051224],[228.1409097022435,45
3.68187695329203],[249.6936987242403,453.78342049724876],[272.6989984
571775,448.2156278276872],[272.0110524437053,444.79167221837804],[248
.77651531852348,448.8688363646738],[227.509537176152,450.245536680183
],[237.9908602824163,390.1923398762123],[160.91646595859757,317.33744
947123716],[188.7840782811474,313.8256705835899],[189.05067958859877,
327.25046064429824],[163.55409188544704,330.4344482791597],[308.53763
65048648,298.0766114500345],[279.84528286898836,302.2825309865559],[2
83.62066631586,315.20905218987537],[309.749050119264,311.666377393752
5]];
//var bieberpos2 =
[[101.56864876894927,233.18862451146063],[103.94483672830893,264.7046
059637433],[111.5648760614713,292.9868982438346],[121.60817984472148,
320.6033955384772],[135.51459988174054,341.80331615737293],[152.82503
856414286,357.93865673417645],[172.7334093282495,369.7555151544583],[
197.69694806265264,372.8908642984119],[222.8053964543867,365.21949767
570914],[242.40546640781133,350.0527677685787],[258.17324630755496,33

106

0.75942632456844],[268.98805835003753,306.7477470070455],[273.6754505
271187,277.0196300321007],[275.3901710230929,247.48473861432882],[271
.2714775656604,215.8934681217882],[251.15119877990037,198.36333212940
198],[234.28326532533939,188.2676120581345],[214.91026985241555,190.4
0117460122602],[198.6679929928869,201.45023631633967],[113.2443890637
6074,211.8970185132382],[126.5955563101671,199.09262449063715],[145.3
1468314556042,197.486438742565],[163.09221764806279,205.1520683730701
],[127.17964196061948,227.10992859881242],[141.38730169612836,217.420
84144199345],[159.0209030325747,224.43130850214425],[142.884335850969
88,230.26811984682448],[142.42801267524905,223.0112485658692],[239.82
517193206303,215.72308282543185],[223.10722684166518,209.153556990042
94],[207.6055747620924,219.65927517951022],[224.48567680757435,222.06
304887372107],[223.6233827552315,214.8262871250668],[172.946417137235
2,224.49975510380557],[168.72197585961794,258.1441109647948],[162.133
07850736825,273.39440853283276],[170.24957359495303,281.7458593241563
6],[187.8016126508577,282.47959683615136],[206.1033075074291,278.2917
7031601284],[212.68125741263046,268.3132850122465],[202.6324139081545
8,254.72497416605486],[192.46120586027132,222.49630587027653],[173.85
800402580105,275.18188385366227],[200.1381924457317,272.3152852765038
],[162.80837519080728,315.13375207511854],[171.69700670251132,306.312
4074117097],[182.24834265233773,302.09650928467386],[190.090159225313
39,303.10443614370354],[197.76209119445363,300.5509316338526],[209.73
158516418792,302.5808407858005],[221.70573066253746,309.3661952909322
],[214.09639912349064,316.65502145001835],[204.49078700810347,321.963
6345043299],[192.41227407051437,324.6228636856393],[180.4845109239334
4,324.28794135030637],[170.93617926975094,320.82799785356144],[177.53
238855284724,313.61914714385057],[191.3906735080654,313.8169220281628
],[205.5802836644213,310.8720277253901],[205.38508820468905,308.14362
791021006],[190.91511553259915,309.92223533784073],[177.0527695156715
,310.91723936457345],[185.79856965529362,268.6105621853759],[132.6255
950975479,220.70726211735987],[151.44519898035702,218.73721954002326]
,[151.293077203678,227.62310217433833],[134.17185610938265,229.518605
87354747],[232.66973446011252,210.5605768611877],[213.57982756654985,
212.53706063982744],[215.69031953459682,221.18112181145614],[233.0419
228385137,219.58164400157239]];
//var averagec
=
[[121.92799191984679,184.19216240419755],[118.74113263254269,253.7017
373484083],[128.07732840700828,314.0651648786312],[145.50341586402052
,377.3404382903117],[175.0470179047746,428.3720278198884],[216.262683
10246033,469.2344402538887],[267.42588166495466,502.128073946532],[32
3.6864139765614,512.5053811316307],[381.1889691089136,499.48530971536
445],[429.71357990120225,463.4214900408549],[467.1292936657478,421.53
7754329594],[493.2308725208873,370.6466670145585],[507.3945907183312,
305.3965374123],[514.1098885852615,238.51000761747102],[507.200994416
2471,174.7364492942625],[465.59705810723074,136.75665747531139],[432.
10874975324265,113.03896523029233],[384.15174446143584,115.6885672142
1743],[351.54488594535763,135.22963355336668],[162.16177451030518,144
.72103952617107],[194.70376235949394,118.93611387780797],[247.3313775
6767314,121.17559172494758],[277.5198647210173,137.82992220884094],[1
92.5627380181407,182.35373455399292],[225.1658086004223,166.858171672
85668],[262.9021389237093,184.72604899079232],[224.82421319031323,193
.62679469584918],[224.9386274222809,179.73191446260716],[443.75218061
508883,177.1556294105885],[407.36102478935464,162.1785032964798],[367
.3426762945685,181.37362678808685],[405.2498567443763,188.75927101523
848],[404.863153412407,173.65270066194788],[291.44098017957907,186.97
025659182341],[277.2539320006613,252.0592473714927],[258.790607031229
,284.0832945003201],[276.64778558874696,304.54255347445314],[317.4772
090972725,307.7859653833357],[364.4959193923387,299.6561959465791],[3
77.27275089177823,279.043842539653],[357.1140334647449,250.1496106147
1956],[337.0544440446092,184.37243898300898],[296.770695143374,295.63
31974142146],[350.24114846328195,290.942330984987],[248.8532880314441

107

,372.38004806995957],[272.1557077756945,356.35352520595814],[302.9902
196911147,350.59821534914704],[323.11457426149127,353.0358352022737],
[338.3055779254553,347.5427982113969],[366.49269601972713,353.1538257
295358],[392.63652105652415,368.4911974180641],[375.0778975047938,391
.4413420753004],[352.32935954043757,405.19247889714825],[320.19499419
206926,411.930992226806],[288.9192573286629,407.35752671668797],[267.
61253113280924,394.527019223827],[286.6817714614754,382.8266752613921
5],[320.16223074694074,385.86502934549657],[359.1212544588326,380.748
7964985724],[361.7270998810554,365.15603335898066],[322.9121033413516
7,367.2901736762333],[280.7920218316411,368.2798825278876],[320.66814
785515174,277.11007275979364],[206.36606604411398,171.6086547538323],
[247.5375468161923,170.29657636660522],[246.36866333618227,191.677294
10789994],[205.19888043799355,189.99033691329964],[429.0603263358775,
166.1691180598579],[386.8504393293843,166.2774220754911],[384.7938981
921405,186.5701136634426],[426.9983448269614,184.45786533091854]];
//var cat =
[[150.6001932850613,227.9951181570873],[141.89008850948386,284.755015
51729855],[146.93652175473133,330.2528119066194],[165.13643537016765,
370.2657204395882],[191.7602900198875,396.93549740902245],[222.863188
88606525,421.7338236701245],[250.10195974421907,438.00195284557867],[
285.9416362643025,454.8230092524781],[321.6791601361751,452.973613247
85925],[352.40851339212884,447.8287857701009],[391.9157950035136,433.
3937963293089],[424.7093533522854,408.2181919788503],[455.81590328086
514,373.8418166206772],[475.6696211189559,340.00598692776714],[489.62
856853297785,283.12036111598195],[458.7886246979456,264.0657344332377
],[429.08284937885685,242.70655476150478],[386.79722632189043,238.713
2662439077],[349.8876932795788,248.21633547184024],[178.2132927119690
7,225.22303282028489],[209.27712879577714,214.13835945729744],[256.51
936365207786,220.3341994097934],[281.85267569104127,240.0888555682899
],[199.50773843473326,263.87975325981057],[233.1001822944999,246.4622
7004616514],[260.41002678551536,279.8036051139961],[220.3355904593311
2,302.50425182036093],[231.41762845993,265.61175717123666],[432.30911
489812183,302.3805337088972],[409.3676999691845,278.5929603289348],[3
67.39241275855267,293.6484316660696],[396.7321664402125,331.655131347
3402],[400.5075763977512,297.7535345477887],[298.6740892060634,284.71
81934025275],[282.68382454097065,321.16350624526655],[259.65210209040
14,342.305734403727],[266.33322956544055,354.33559341751277],[296.909
7623749709,381.2106729730044],[334.45562946043754,365.4529264948747],
[343.63246793135585,357.22118594760343],[335.86436141618674,332.66790
67055157],[331.7902015246156,291.324842551962],[287.60066328698633,36
7.0549625165994],[313.9108542347557,368.49852421569886],[247.50074360
56582,417.6643167481912],[257.7333491252317,405.90810714935833],[276.
0164369955125,395.9485960986041],[294.27284228990516,391.920911124437
05],[306.4663169213994,400.6013046459878],[323.00925643524545,415.984
62467985274],[334.7606548113434,430.1608259195054],[318.4262833660398
,415.0800228641732],[304.94670103933333,407.03227374908556],[292.8749
32156233,403.35630505685776],[278.7771095071339,402.6239596600665],[2
64.15687945778745,408.19379145183206],[266.1987275233493,402.43370359
6171],[291.63717649802595,393.5654166069583],[316.0146798721538,410.7
3024314941136],[315.8070301011558,409.8320583467966],[293.43990504232
77,393.31185267965253],[267.1430933970747,400.5068413985279],[302.521
9480114296,353.8817190906611],[213.30383757995148,250.17117325135706]
,[254.25518448883656,260.1332214763917],[247.37254769207618,296.65451
513845477],[200.4210200644895,284.6926551210971],[427.3384882589094,2
87.98688185003783],[386.3798835564063,282.62080726070684],[370.562420
04280097,318.1523500775542],[419.52101636070836,322.51848086271053]];
//var jake =
[[234.38099345630354,123.42494719483474],[222.2214564461309,144.08728
35027847],[214.90510066091002,167.48766201665953],[213.16726435721944
,195.82670444827474],[223.6730979360211,222.59066272143866],[239.2336
5112154602,240.84500325231835],[268.4475076403672,259.28313630193605]

108

,[301.5998477644837,268.6952132952639],[338.8479887885296,271.3654028
0326324],[368.9870966348582,266.1683102123557],[396.0167719938352,254
.60676962364323],[417.346649654904,233.16407871805245],[433.386884713
7596,207.37069921006477],[436.1139763587346,168.63731307965494],[429.
0371231685856,147.85294070108733],[416.00040098296006,127.72186826432
07],[396.7536035787854,111.21810284287348],[370.18865770559034,98.446
39202675758],[347.5214963832025,109.7647606703939],[248.606213881761,
110.4915609544193],[267.8370087437634,99.12715769053584],[295.8907022
304993,92.53089931939547],[310.4711426895737,104.33854621500996],[264
.82208511042757,129.94888584507447],[272.5790833087474,123.7171262261
9187],[275.1280002948981,131.99557912678358],[267.32717008145914,139.
10583332803492],[269.8167396627076,131.2344512054223],[383.2829097072
338,146.82347566034022],[380.5693784576177,135.57292568928986],[372.5
857211923719,142.55687825159674],[374.766305369171,151.28250446417422
],[377.73237204412504,144.07565750838378],[313.85911658041044,133.705
85439048781],[312.2613882398354,138.33433176102892],[304.139773077363
66,141.4341849642005],[300.50038926523024,144.5527967536452],[318.923
87405804516,153.28441719693217],[337.7047544403404,152.2045384350659]
,[342.14662806333115,147.76186161149792],[332.3604223557127,142.20440
747717106],[332.56860277377314,137.3017458595702],[304.4495296381421,
148.5939356938822],[332.64841618884986,152.74223745844046],[281.91617
46791266,160.58501548422777],[288.81595107073787,153.68436484524014],
[304.9212258330618,158.96343148494978],[317.9013301906912,167.9076552
725944],[335.7503963246223,164.96793804180746],[351.92972980464725,16
5.0624691531191],[359.9002802244111,174.7911234594563],[353.233888523
5205,183.8054375458767],[330.7574571038555,188.30597330174191],[310.5
555404584375,188.52117656584892],[297.15805487910404,182.361326672868
7],[282.829485875428,172.75450158252914],[288.93800145709554,178.2493
168991062],[311.1525643029315,188.05523216204233],[346.4395139815897,
186.62042857639597],[345.5633832777238,163.5425977731078],[318.052993
63286065,166.90893750240946],[294.8261801090658,154.04898179800017],[
322.2491701153617,143.30196652241514],[267.19752987709984,126.3344942
2887833],[276.85129577529784,127.35638980980212],[272.2280492521963,1
38.0468370366501],[263.5697757835426,136.02737917378937],[383.9293952
904134,141.20056048779244],[376.07977812687676,137.56432355244687],[3
72.17687628009185,146.41433942556017],[380.0281817368749,150.05244216
639528]];
//var cage =
[[62.844249212286726,275.00253672977243],[67.55510662019353,328.44167
358535947],[75.11261772100842,377.3124712980347],[87.37774244481457,4
21.23173056086273],[113.9902951052712,453.1478586395097],[140.8317160
2345155,480.6373388543555],[167.5196005894719,501.2561788181624],[212
.18010120694998,510.2344196312023],[253.45675406514755,498.3276258268
832],[289.7215253857187,474.1530824891014],[312.6432334014449,446.457
1552178683],[334.31093551238234,413.47929218022904],[342.821417164626
15,367.06678718581435],[340.0787835321058,325.02433505948227],[344.03
477716066624,276.1610436162956],[311.3105334335752,219.25058272399014
],[281.1643998222319,201.85115398988745],[246.67360364777142,197.9101
5747771542],[221.74045178386638,211.73972584765107],[88.3968587196551
7,232.87057682782168],[119.65607817768387,206.69928143233432],[151.70
208724138473,200.6297795897709],[182.1988161275458,214.14891146210013
],[111.91291700126256,253.6797122349625],[136.92106035526825,239.9404
956893577],[162.91467393699673,250.032069765119],[136.0236656014504,2
58.28678236447894],[137.0026767970992,247.0968006580872],[290.9960881
4360033,248.5656270489297],[266.2858860116553,236.49556260291146],[23
9.12111916914662,245.91281243818258],[263.05529224671415,252.12781036
467007],[263.69541132990514,241.7440372965671],[185.79943781947387,25
2.86663379958435],[167.036525347904,300.10052708948666],[155.37988556
99212,325.9510914090657],[166.6432477420878,339.3972885867414],[201.1
8979122083596,342.620961855605],[233.77487769512172,332.7824005320247
],[245.46879766562955,319.97569840735036],[229.78121185656033,290.921
333048562],[215.36151007417078,249.848556046143],[176.833684867132,33

109

1.4510944914906],[219.51569663621888,329.5475580109928],[150.44691614
510197,393.9731247944999],[167.7923227215762,379.60307375221],[186.62
468414252686,374.8421900119016],[203.70712368575602,377.1041947321246
5],[215.69484299340166,374.7441013708148],[238.64983301680508,375.652
15297966955],[257.4458840569071,386.14371230397177],[248.023087363734
6,409.9327639477665],[231.32451079815257,426.5631075934497],[203.7714
090986988,430.95782701637],[175.9185408932064,427.7645785634805],[161
.36390098288757,411.96116683185153],[176.95087018336454,406.946758431
982],[204.01839602612762,408.2014093667243],[230.59006014506824,400.6
7533081324075],[227.96700934619196,382.1851505374937],[201.5722227074
383,385.03028865614806],[178.2788927365379,386.1691344889883],[199.93
330911993385,316.5892429114219],[121.91675481462666,244.8147557360786
4],[154.41505146086834,241.4873947901523],[150.9653978657209,255.6599
13009525],[121.46335898343057,255.98657922353812],[278.14173342084905
,239.53501630515916],[250.20579871533653,238.2047381204274],[249.5908
7518454686,250.51941670260177],[279.52918882565444,250.84811178896496
]];
var masks = {
"average" :
[[121.92799191984679,184.19216240419755],[118.74113263254269,253.7017
373484083],[128.07732840700828,314.0651648786312],[145.50341586402052
,377.3404382903117],[175.0470179047746,428.3720278198884],[216.262683
10246033,469.2344402538887],[267.42588166495466,502.128073946532],[32
3.6864139765614,512.5053811316307],[381.1889691089136,499.48530971536
445],[429.71357990120225,463.4214900408549],[467.1292936657478,421.53
7754329594],[493.2308725208873,370.6466670145585],[507.3945907183312,
305.3965374123],[514.1098885852615,238.51000761747102],[507.200994416
2471,174.7364492942625],[465.59705810723074,136.75665747531139],[432.
10874975324265,125],[384.15174446143584,125],[351.54488594535763,135.
22963355336668],[162.16177451030518,144.72103952617107],[194.70376235
949394,126],[241,130],[277.5198647210173,137.82992220884094],[192.562
7380181407,182.35373455399292],[225.1658086004223,166.85817167285668]
,[262.9021389237093,184.72604899079232],[224.82421319031323,193.62679
469584918],[224.9386274222809,179.73191446260716],[443.75218061508883
,177.1556294105885],[407.36102478935464,162.1785032964798],[367.34267
62945685,181.37362678808685],[405.2498567443763,188.75927101523848],[
404.863153412407,173.65270066194788],[314,
170],[277.2539320006613,252.0592473714927],[258.790607031229,284.0832
945003201],[276.64778558874696,304.54255347445314],[317.4772090972725
,307.7859653833357],[364.4959193923387,299.6561959465791],[377.272750
89177823,279.043842539653],[357.1140334647449,250.14961061471956],[32
4,222],[296.770695143374,295.6331974142146],[350.24114846328195,290.9
42330984987],[248.8532880314441,372.38004806995957],[272.155707775694
5,356.35352520595814],[302.9902196911147,350.59821534914704],[323.114
57426149127,353.0358352022737],[338.3055779254553,347.5427982113969],
[366.49269601972713,353.1538257295358],[392.63652105652415,368.491197
4180641],[375.0778975047938,391.4413420753004],[352.32935954043757,40
5.19247889714825],[320.19499419206926,411.930992226806],[288.91925732
86629,407.35752671668797],[267.61253113280924,394.527019223827],[286.
6817714614754,382.82667526139215],[320.16223074694074,385.86502934549
657],[359.1212544588326,380.7487964985724],[361.7270998810554,365.156
03335898066],[322.91210334135167,367.2901736762333],[280.792021831641
1,368.2798825278876],[320.66814785515174,277.11007275979364],[206.366
06604411398,171.6086547538323],[247.5375468161923,170.29657636660522]
,[246.36866333618227,191.67729410789994],[205.19888043799355,189.9903
3691329964],[429.0603263358775,166.1691180598579],[386.8504393293843,
166.2774220754911],[384.7938981921405,186.5701136634426],[426.9983448
269614,184.45786533091854]],
"monalisa" :
[[266.539778613571,254.84378898872825],[266.3039097561577,285.3022331
89556],[271.19357329466345,316.3538789507933],[278.7139543521674,345.
15573844972926],[293.15712497356776,368.9809024015706],[312.641939741
41324,389.09850232246515],[322.13343587641253,398.3663601209212],[336

110

.9858985066435,401.49456958745145],[356.87519225850986,398.5376499254
816],[382.97232156668036,391.79752653535775],[421.61286401088506,373.
50434543677886],[448.74322775690695,344.0259953810623],[464.774400990
78314,310.71915538180275],[468.2775933241595,272.2241198406615],[466.
74514645738424,247.20492682906303],[415.26964981149064,225.8370550250
565],[390.13712322351404,222],[361.92175039938184,220.2582273389706],
[342.2734356138508,232.04834635926073],[267.7624903928149,236.0087388
5152805],[280.88607721372824,229],[303.9033677258633,228],[316.696536
0192193,234.20369314639848],[281.57998031880885,254.77971856631495],[
298.953459306752,246.21641370334032],[315.75345517431316,254.45161652
42651],[296.6631361379687,258.36486568494297],[301.63327656416925,252
.0239926097512],[398.27491865673994,249.8954346966754],[380.224038193
42355,243.83584281695727],[357.98660716766716,253.53119540181672],[37
8.25469629277825,255.99515336941278],[382.6139465907322,249.643327423
1842],[328,253],[314.73794539936216,301.757722929817],[309.8521311673
6014,314.6797549304112],[313.1507370768973,321.4994076914073],[325.20
473159190635,327.87953636258146],[350.1231795924951,324.5425216268138
],[358.3783946629097,316.6717252774034],[352.7986254362873,299.551951
7987678],[326,282],[314.75674487301336,318.32005216616164],[343.03222
75619273,319.2819917007706],[307.87514392633693,346.0346979532304],[3
16.68926117981914,342.91320569661593],[321.7320399187087,341.45780089
974846],[327.8558316510405,343.56649844038935],[336.18423231506125,34
1.74737597014604],[351.00603891713007,342.2560527375472],[367.8822249
8993025,344.3660717427479],[357.305053617142,354.4583428810625],[343.
5761668856892,358.8848818975423],[328.82001419900075,359.105183236516
3],[320.36190636746045,358.71759346010083],[312.61714975606304,353.56
25007817836],[318.4988566294063,348.1744254793423],[328.6406599928464
,349.73460503451736],[350.2480353796336,349.6831133201238],[349.57542
34743516,349.5362145583936],[329.32557946752445,349.67345155068153],[
318.2253756678819,347.9222277142419],[324.4964277572599,315.631228136
43895],[288.26630901657126,248.99890899333045],[309.3536455351319,248
.83485523505226],[307.7075352919804,256.40978560947974],[288.62032608
071166,258.5736833679789],[390.2498028902113,244.8663932568382],[368.
1047796233772,247.18427292360775],[368.62079313091925,255.76448975973
483],[390.7655312307384,254.4464699123733]],
"ironman" :
[[54.132994582809886,330.2447406482356],[53.94983737338171,411.678694
7731232],[59.50117090734213,485.54290769879117],[69.05631570910228,57
7.6685769791815],[80.73400747239302,669.2047081882876],[156.522671928
78207,721.5706883991684],[224.03761978834723,739.1269072358452],[301.
4803537679236,738.2366874355024],[373.4196207112528,736.6185556997145
],[445.4373067968218,720.1452812831552],[517.3056114476371,670.547461
4197833],[531.7799053755264,574.1779931382804],[540.681172219442,487.
967223266098],[542.4032150608897,399.64595333584305],[541.50993695658
68,318.2177239885218],[484.00763535360403,311.3318445452918],[436.576
16449858205,326.12885038303966],[386.214847801106,333.2043197182652],
[344.39911403378784,336.7706741289662],[115.84864343665006,313.355252
43241443],[152.60840318917894,322.7145050535586],[201.39783835228144,
332.29526724516336],[249.58724826191298,336.53976562323317],[116.4802
3640991207,348.8633768136441],[167.9642886955806,350.9962302246727],[
231.6749647028165,359.48349174177827],[168.11831577303042,375.4865728
177492],[170.07462103025938,361.76575290725043],[480.7831200700384,34
8.57719399476593],[423.78106882269736,353.08381522791285],[369.585319
9174605,360.3348770905004],[429.2517105029677,374.978498189726],[428.
4672557696136,361.0310278167258],[298,363],[253.70821429640165,456.15
15630753871],[232.81854206254127,493.52915431030885],[250.27449264190
767,519.2760705851281],[294.9905749783811,522.6580485667231],[340.007
10866420684,520.8077271147647],[357.28424845402884,493.1349774295837]
,[336.03221275387335,457.7253897416814],[296,407],[270.69780042635847
,507.2277260957476],[320.8265507066314,506.90809731554305],[219.49207
600124322,603.6108989555861],[236.4148918469843,589.8509195222699],[2

111

67.0123175575189,590.2653879517876],[302.37639394449644,589.445633902
1824],[337.18338067155105,591.0755705685021],[366.9537080661368,591.1
696362146871],[383.17030058050824,601.5027761622135],[366.07822563380
967,614.8268645173376],[336.20759244137867,615.427540755917],[304.125
97029775543,615.4777558918809],[270.01910167830954,615.9331065732697]
,[240.4271869365151,614.9063722445486],[255.5183417994636,603.9175341
052295],[302.81892822034536,605.4895650711086],[350.74058301633727,60
4.2225054756758],[350.6655959742464,603.528118265738],[303.7844646391
6174,604.3090513544694],[256.409865954666,603.8790201634539],[298.251
75247557996,482.7822436696597],[141.22182216936852,346.4270057321846]
,[206.31948949078424,356.7387529836485],[202.39427275621864,368.98726
76086593],[136.2964448024117,368.67555898584044],[454.78000220898934,
348.3276075895992],[398.6821272555564,355.2080431875895],[398.9194910
642594,369.6579535284187],[466.01878775359233,368.7792910743897]],
"skull" :
[[94.36614797199479,301.0803014941178],[103.3112341317163,370.9442589
1220794],[120.32682383634102,423.44019820073913],[136.47515990999432,
479.5313526801685],[144.0368892689739,530.2345465095229],[172.3667115
8523987,580.3629853084399],[217.01976787749376,619.1929480747351],[26
9.34754914721543,625.5185645282593],[326.48254316405735,621.386147288
7296],[367.5697682338512,588.2815093455445],[396.3225813396373,544.52
41298700507],[423.17220298223486,485.34023789625417],[433.98432474543
75,424.6310467376783],[459.5753658677024,376.88741971189734],[465.687
1064619868,309.4410229689395],[439.2202424949693,261.17900856324786],
[404.95656878888406,237.16839138607617],[349.4475953084992,224.723368
16106127],[307.5262703136751,246.56374069983377],[111.59908955786085,
255.73818792771897],[140.77843006651088,236.25905776423554],[198.2561
4310392174,221.75964368670276],[238.0607640650076,244.705502740957],[
147.51722669161887,322.2920755920064],[179.96374258674177,303.2028355
7208495],[219.89652431504095,321.63741406437117],[181.93382178127874,
336.62855114616417],[181.67029281471235,321.84674383355735],[409.0888
7297158253,319.49332724817634],[372.08555159755235,302.6637205310945]
,[332.21673690859785,314.25212117506817],[371.9034386455536,336.79282
47239386],[370.73203771018734,318.2549362647991],[275,262],[241.49292
248091808,382.6509156918952],[228.65540058230079,403.67602315679153],
[246.4207645046435,428.633436281585],[281.6262637981823,429.710123085
0766],[320.3090052424696,429.4111504923561],[337.71957018298144,408.9
834145077307],[324.9443408840292,383.11655691739367],[277,336],[262.6
247652804272,418.02062856158705],[305.62131595904475,419.984904239174
9],[192.0888434079335,501.27870633434],[227.89330220055228,491.767986
224554],[254.82152484033276,488.28172522414377],[274.58325738122585,4
96.93117201682657],[298.6427918040954,490.9689564164321],[325.4832850
7490595,499.3328015524256],[350.42668910649365,508.3776245292422],[32
7.3034449428819,532.1604992353581],[302.413708672554,539.107834470101
7],[266.7645104587291,540.3023216343349],[237.0072802317868,530.32601
42620247],[215.71258213035736,519.4068856743318],[222.47713501183063,
502.96356939871526],[278.19882029298384,511.73001012850216],[321.8907
8331130554,511.2982898921548],[318.4792941712966,518.8634093151715],[
277.74782145336667,522.9574136207773],[230.31017878122015,512.4917843
225409],[281.2762389085891,407.8752450214805],[163.2415047021451,306.
7465365446632],[202.42996875366381,307.91977418268493],[204.913931382
79884,330.1328065429834],[161.72396129164846,332.9605656535211],[394.
08708850976745,308.0776176192674],[354.1514690637372,305.457188960850
43],[349.5616880820385,328.5223891568975],[391.4980892099413,331.1427
807886423]],
"sean" :
[[109.36614797199479,146.0803014941178],[113.3112341317163,166.944258
91220794],[119.32682383634102,192.44019820073913],[124.47515990999432
,218.53135268016848],[135.0368892689739,237.23454650952294],[153.3667
1158523987,258.3629853084399],[168.01976787749376,267.1929480747351],
[187.34754914721543,269.51856452825933],[208.48254316405732,266.38614
72887296],[230.56976823385122,254.28150934554446],[252.32258133963728

112

,228.52412987005079],[257.17220298223486,206.3402378962542],[258.9843
247454375,180.63104673767828],[258.5753658677024,155.88741971189734],
[257.6871064619868,133.44102296893945],[239.22024249496928,123.179008
56324786],[224,120],[202,129],[189.52627031367516,133.56374069983377]
,[117.59908955786086,139.73818792771897],[127.77843006651088,132],[14
6,132],[165.0607640650076,134.705502740957],[134.51722669161887,148.2
9207559200646],[147.96374258674177,143.20283557208495],[159.896524315
04095,147.63741406437117],[147.93382178127874,150.62855114616417],[14
7.67029281471235,145.84674383355735],[225.08887297158256,140.49332724
817637],[212.08555159755232,136.6637205310945],[200.21673690859785,14
3.2521211750682],[213.9034386455536,144.79282472393862],[212.73203771
018734,139.25493626479908],[176,143],[165.49292248091808,175.65091569
18952],[160.65540058230079,186.6760231567915],[167.4207645046435,192.
63343628158498],[183.62626379818232,194.71012308507662],[202.30900524
24696,190.41115049235611],[205.7195701829814,183.98341450773069],[198
.9443408840292,173.11655691739367],[179,161],[168.6247652804272,189.0
2062856158705],[197.62131595904475,185.9849042391749],[161.0888434079
335,217.27870633433994],[167.89330220055228,211.76798622455402],[176.
82152484033276,209.28172522414377],[183.58325738122588,209.9311720168
2657],[188.6427918040954,207.96895641643206],[201.48328507490595,210.
3328015524256],[211.42668910649365,215.3776245292422],[203.3034449428
8195,220.16049923535812],[195.41370867255398,222.10783447010172],[184
.76451045872906,223.302321634335],[174.00728023178684,223.32601426202
467],[167.71258213035736,222.40688567433176],[169.47713501183063,215.
96356939871526],[182.19882029298384,215.73001012850216],[195.89078331
130557,214.2982898921548],[195.47929417129663,213.86340931517145],[18
1.74782145336667,214.95741362077732],[170.31017878122015,216.49178432
254084],[182.2762389085891,184.8752450214805],[140.2415047021451,145.
7465365446632],[154.42996875366381,143.9197741826849],[154.9139313827
9884,149.13280654298345],[141.72396129164846,149.9605656535211],[220.
08708850976743,138.07761761926741],[205.15146906373715,139.4571889608
5043],[206.5616880820385,144.52238915689745],[219.4980892099413,143.1
427807886423]],
"audrey" :
[[153.74201740403646,257.58838131299683],[153.1357402459916,291.61358
072852295],[163.92648670097353,336.6674185987861],[169.05137634628016
,385.1975110609068],[187.6238859708483,421.2108262322121],[216.686071
409745,444.7519516586696],[252.3126606898006,465.32269819176895],[283
.0811558461883,470.8182094669599],[310.01372611356055,468.19451253588
267],[343.73964850426626,447.233158556066],[371.3765378504441,422.994
7341112305],[387.5627292608278,382.0293105452122],[398.46785237450297
,339.09243674243754],[410.7142207166049,294.2191807024135],[411.77246
14993711,261.09373588344585],[397.08419909909355,252.94944754715868],
[376,241],[347.88483875688155,246],[320.92763554902524,254.6359188212
2572],[174.20709387641796,237.53266499674754],[201,234],[231,239],[25
9.80324104447095,248.8385932134204],[203.20895380044172,279.486704599
1428],[228.2843062554636,263.77563604011084],[254.37335751351947,287.
3518288920658],[225.37155395907916,290.26869393942275],[227.777680512
30873,272.55424007173355],[373.6963908872387,283.83985580081185],[349
.2543124861655,273.37102031128484],[324.214351960891,292.005155765703
2],[352.73999275494873,296.13681628226215],[350.0652800779458,278.737
8813418683],[292,283],[262.7314015757042,344.55089637183414],[256.093
82016348263,360.28137163294355],[265.43437220076765,373.7185311578347
],[292.84018353954804,379.51893631975383],[319.5702417532398,374.9644
468251393],[324.6370116978122,365.5029178767047],[318.03834636609736,
339.5592633568763],[293,322],[275.91223102812063,365.3241223928343],[
310.9988910215482,365.94139857304066],[241.36179100195926,404.5724872
0067804],[256.244097414399,399.79192498435566],[275.9545526341606,397
.2506401446753],[289.6156500062133,402.18658812822247],[305.736336616
2922,398.11786374216797],[318.71091994807995,402.09809058994574],[332
.1507895390563,406.57790820835453],[317.07898694502654,420.6784334029
229],[303.5975014688257,430.191159222479],[287.22005286691325,432.458

113

45823523985],[269.1473100017029,428.92524246489165],[256.356295800623
7,421.3232920714367],[269.4689541559383,409.5609803328374],[288.98592
38876932,410.32998112652183],[306.1403256243275,411.3077976017484],[3
07.73772138569666,411.00947047307966],[288.5537974824452,410.51396287
362655],[269.7179313684785,409.79854206584145],[293.13908085531165,36
0.2044576609231],[210.24669344926002,268.1362929595334],[244.33001418
358253,272.06529726630106],[237.37014577148472,289.8158253810601],[21
2.28729137033707,286.8846525992707],[364.4764146636024,276.6099231285
8446],[332.73309300337735,280.1921291112648],[336.47694784065465,295.
57941207015807],[365.2216557008562,291.9943008746264]],
"cage2" :
[[96.81941282528646,268.6563333055432],[106.75675954633661,329.158740
5365555],[119.76815459937384,379.4896985493418],[136.07940076941458,4
25.9492772057105],[161.2808692110661,457.61169473264835],[186.0489485
2923297,485.6759001579113],[218.4426767235838,511.0714335097357],[260
.06499742347034,523.1545996578884],[300.06377090251993,510.6121679293
8615],[337.5694959005854,468.82896175985],[358.97922192378047,441.541
81864835476],[379.42084177310676,403.390743126405],[388.7955321567646
,351.3090658772298],[390.4262385647278,299.3698133324318],[384.118109
00892965,242.91856536650718],[348.70738406950056,224.9829932049514],[
321,222],[284,222],[248.86954256992664,228.19206802513366],[119.91233
030390185,255.38702736145385],[138,245],[175,236],[211.38447558444696
,237.17956241438634],[144.4884094882825,271.0334533280929],[166.20253
053976617,258.5182260687953],[190.76818628874074,264.72493789715475],
[166.3651367856651,273.4746395006701],[167.80450182394694,265.0556706
110155],[324.5406048528901,251.04296112395667],[299.7419762994943,241
.35048431345442],[272.0486344446429,254.37413342811146],[300.27799042
13152,258.21350699061486],[299.7261402367746,247.52288292547877],[230
,247],[202.82098590251388,333.63541920962166],[197.36529740216793,360
.6074799565433],[211.93043020653712,374.7216105521087],[243.914573429
32796,376.61574931741393],[273.7931176105319,368.54185553932047],[283
.1924422789671,346.10700000116907],[273.21255878744284,326.3419941919
277],[235,309],[216.08956463539755,366.1198047818831],[262.3815762526
8843,360.4765024368325],[200.65672420260339,425.7113072142362],[210.5
9591704137958,418.8310789950973],[226.72952280292276,414.158673602795
9],[245.26202591934208,416.9013315273323],[261.6743086310934,412.2506
112472961],[283.3509308337543,410.8975165060922],[302.2287007716769,4
14.3759049856237],[288.05687218005096,428.64611508851056],[272.904626
2998521,439.81519003757444],[251.37714128101143,448.0168626101829],[2
29.03794885867393,446.9574815880215],[217.27491143676224,438.10808744
290716],[225.27828463087235,425.86527765147576],[246.089531122415,426
.43509210786846],[272.14938117327404,421.7534010147635],[271.81608729
443224,421.5900960094701],[246.87299073434986,427.22889777615507],[22
5.65210985383266,426.21786917122313],[239.24882409629814,356.79235485
52414],[152.34433274214945,262.7826049480205],[179.48599280195447,258
.6243674505216],[180.06624281569137,269.6029915273643],[153.926296458
539,274.75536491866694],[312.6407607999811,242.7049854510107],[282.89
141140599133,245.36953091106633],[285.6577700037131,257.3045548089233
4],[314.4040909797777,256.634302341433]]
};
var currentMask = 0;
var
animationRequest;
function
drawGridLoop() {
// get position of face
positions =
ctrack.getCurrentPosition(vid);
overlayCC.clearRect(0, 0, 500, 375);
if (positions) {
// draw current
grid
ctrack.draw(overlay);
}
// check whether mask
has converged
var pn =
ctrack.getConvergence();
if (pn < 0.4)
{
switchMasks();

114

requestAnimFrame(drawMaskLoop);
} else {
requestAnimFrame(drawGridLoop);
}
}
function switchMasks() {
//
get mask
var maskname =
Object.keys(masks)[currentMask];
fd.load(document.getElementById(maskname), masks[maskname],
pModel);
}
function drawMaskLoop() {
//
get position of face
positions =
ctrack.getCurrentPosition();
overlayCC.clearRect(0, 0, 400, 300);
if (positions) {
// draw mask on
top of face
fd.draw(positions);
}
animationRequest = requestAnimFrame(drawMaskLoop);
}
document.addEventListener("clmtrackrIteration",
function(event) {
stats.update();
}, false);
</script>

BLOK KODE 7:
Script Deformasi Realtime Wajah

<script>
var vid =
document.getElementById('videoel');
var
overlay = document.getElementById('overlay');
var
overlayCC = overlay.getContext('2d');
var ctrack = new clm.tracker();
ctrack.init(pModel);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild(
stats.domElement );
function enablestart() {
var
startbutton = document.getElementById('startbutton');
startbutton.value = "start";
startbutton.disabled = null;
}
var insertAltVideo = function(video) {
if (supports_video()) {
if (supports_ogg_theora_video())
{
video.src =
"./media/franck.ogv";
} else if
(supports_h264_baseline_video()) {
alert("no mp4 video :(");
//video.src = "./media/capture4.mp4";
} else {
return
false;
}
//video.play();
return
true;
} else return false;
}
var
insertAltImage = function() {
var
canvas = document.getElementById('canvasel');
var cc = canvas.getContext('2d');
var

115

img = new Image();


img.onload =
function() {
cc.drawImage(img, 0,
0, 370, 288);
};
img.src = './media/franck_02221.jpg';
vid.className = "hide";
vid =
canvas;
canvas.className = "nohide";
var startbutton
= document.getElementById('startbutton');
startbutton.onclick = function() {
ctrack.start(vid);
drawLoop();
}
startbutton.value = "start";
startbutton.disabled = null;
}
// check whether browser supports
webGL
var webGLContext;
var webGLTestCanvas = document.createElement('canvas');
if (window.WebGLRenderingContext) {
webGLContext = webGLTestCanvas.getContext('webgl')
|| webGLTestCanvas.getContext('experimental-webgl');
if (!webGLContext ||
!webGLContext.getExtension('OES_texture_float')) {
webGLContext = null;
}
}
if (webGLContext ==
null) {
alert("Your browser does not seem
to support WebGL. Unfortunately this face deformation example depends
on WebGL, so you'll have to try it in another browser. :(");
}
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
window.URL =
window.URL || window.webkitURL || window.msURL || window.mozURL;
// check for camerasupport
if
(navigator.getUserMedia) {
// set up
stream
var
videoSelector = {video : true};
if
(window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
var chromeVersion =
parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1],
10);
if (chromeVersion < 20) {
videoSelector = "video";
}
};
navigator.getUserMedia(videoSelector, function( stream ) {
if (vid.mozCaptureStream) {
vid.mozSrcObject = stream;
} else {
vid.src = (window.URL && window.URL.createObjectURL(stream)) ||
stream;
}
vid.play();
}, function()
{
//insertAltVideo(vid);
insertAltImage();
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className = "nohide";
alert("There was some problem trying to
fetch video from your webcam, using a static image instead.");
});
} else {
insertAltImage();
//insertAltVideo(vid);
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className =

116

"nohide";
alert("Your browser does not seem
to support getUserMedia, using a static image instead.");
}
vid.addEventListener('canplay', enablestart, false);
function startVideo() {
// start video
vid.play();
// start tracking
ctrack.start(vid);
//start drawing
faces
drawLoop();
}
var positions;
var
fd = new faceDeformer();
fd.init(document.getElementById('webgl'));
document.addEventListener("clmtrackrIteration", function(event)
{
stats.update();
},
false);
function
drawLoop() {
// track in video
positions = ctrack.getCurrentPosition();
overlayCC.clearRect(0, 0, 720, 576);
if (positions) {
ctrack.draw(overlay);
}
// hide buttons
elem = document.getElementById('buttons');
elem.setAttribute('class', 'hide');
// show message
var scoreel = document.getElementById('score');
scoreel.innerHTML = "Please keep head still while
model fits";
var pn = ctrack.getConvergence();
if
(pn < 1.8) {
requestAnimFrame(setupFaceDeformation);
scoreel.innerHTML = "";
if (vid.tagName == "VIDEO") {
vid.pause();
}
} else {
requestAnimFrame(drawLoop);
}
}
var
ph, gui;
var rotation = 0;
var scale = 3;
var xOffset = -10;
var yOffset = 0;
function
setupFaceDeformation() {
// draw face
deformation model
positions =
ctrack.getCurrentPosition();
overlayCC.clearRect(0, 0, 720, 576);
ctrack.draw(overlay);
fd.load(vid,
positions, pModel);
fd.draw(positions);
// hide
video
var elem =
document.getElementById('container');
elem.setAttribute('class', 'hide');
// show facial deformation element
elem = document.getElementById('webglcontainer');
elem.setAttribute('class', 'nohide');
// hide message element
document.getElementById('score').setAttribute('class',
'hide');
// set up controls
ph = new parameterHolder();
gui = new dat.GUI();
var guiSelect =
gui.add(ph, 'presets', presets);
var gui1
= gui.add(ph, 'param1', -50, 50).listen();
var gui2 = gui.add(ph, 'param2', -20, 20).listen();

117

var gui3 = gui.add(ph, 'param3', -20,


20).listen();
var gui4 = gui.add(ph,
'param4', -20, 20).listen();
var gui5 =
gui.add(ph, 'param5', -20, 20).listen();
var
gui6 = gui.add(ph, 'param6', -20, 20).listen();
var gui7 = gui.add(ph, 'param7', -20, 20).listen();
var gui8 = gui.add(ph, 'param8', -20,
20).listen();
var gui9 = gui.add(ph,
'param9', -20, 20).listen();
var gui10 =
gui.add(ph, 'param10', -20, 20).listen();
var gui11 = gui.add(ph, 'param11', -20, 20).listen();
var gui12 = gui.add(ph, 'param12', -20,
20).listen();
var gui13 = gui.add(ph,
'param13', -20, 20).listen();
var gui14
= gui.add(ph, 'param14', -20, 20).listen();
var gui15 = gui.add(ph, 'param15', -20, 20).listen();
var gui16 = gui.add(ph, 'param16', -20,
20).listen();
var gui17 = gui.add(ph,
'param17', -20, 20).listen();
var gui18
= gui.add(ph, 'param18', -20, 20).listen();
var gui19 = gui.add(ph, 'param19', -20, 20).listen();
var gui20 = gui.add(ph, 'param20', -20,
20).listen();
var guiGrid = gui.add(ph,
'draw_grid', false);
var guiFace =
gui.add(ph, 'draw_face', true);
gui1.onChange(drawDeformedFace);
gui2.onChange(drawDeformedFace);
gui3.onChange(drawDeformedFace);
gui4.onChange(drawDeformedFace);
gui5.onChange(drawDeformedFace);
gui6.onChange(drawDeformedFace);
gui7.onChange(drawDeformedFace);
gui8.onChange(drawDeformedFace);
gui9.onChange(drawDeformedFace);
gui10.onChange(drawDeformedFace);
gui11.onChange(drawDeformedFace);
gui12.onChange(drawDeformedFace);
gui13.onChange(drawDeformedFace);
gui14.onChange(drawDeformedFace);
gui15.onChange(drawDeformedFace);
gui16.onChange(drawDeformedFace);
gui17.onChange(drawDeformedFace);
gui18.onChange(drawDeformedFace);
gui19.onChange(drawDeformedFace);
gui20.onChange(drawDeformedFace);
guiSelect.onChange(switchDeformedFace);
guiGrid.onChange(drawDeformedFace);
guiFace.onChange(drawDeformedFace);
drawDeformedFace();
}
function drawDeformedFace() {
//
draw model
var parameters =
ctrack.getCurrentParameters();
parameters[0] = scale*Math.cos(rotation)-1;
parameters[1] = scale*Math.sin(rotation);
parameters[2] = xOffset;
parameters[3] = yOffset;
parameters[0+4] = ph.param1;
parameters[1+4] = ph.param2;
parameters[2+4] = ph.param3;
parameters[3+4] = ph.param4;
parameters[4+4] = ph.param5;

118

parameters[5+4] = ph.param6;
parameters[6+4] = ph.param7;
parameters[7+4] = ph.param8;
parameters[8+4] = ph.param9;
parameters[9+4] = ph.param10;
parameters[10+4] = ph.param11;
parameters[11+4] = ph.param12;
parameters[12+4] = ph.param13;
parameters[13+4] = ph.param14;
parameters[14+4] = ph.param15;
parameters[15+4] = ph.param16;
parameters[16+4] = ph.param17;
parameters[17+4] = ph.param18;
parameters[18+4] = ph.param19;
parameters[19+4] = ph.param20;
positions = fd.calculatePositions(parameters, true);
fd.clear();
if
(ph.draw_face) fd.draw(positions);
if
(ph.draw_grid) fd.drawGrid(positions);
}
function switchDeformedFace() {
// draw model
var parameters
= ctrack.getCurrentParameters();
parameters[0] = scale*Math.cos(rotation)-1;
parameters[1] = scale*Math.sin(rotation);
parameters[2] = xOffset;
parameters[3] = yOffset;
var split
= ph.presets.split(",");
parameters[0+4]
= ph.param1 = parseInt(split[0],10);
parameters[1+4] = ph.param2 = parseInt(split[1],10);
parameters[2+4] = ph.param3 =
parseInt(split[2],10);
parameters[3+4] =
ph.param4 = parseInt(split[3],10);
parameters[4+4] = ph.param5 = parseInt(split[4],10);
parameters[5+4] = ph.param6 =
parseInt(split[5],10);
parameters[6+4] =
ph.param7 = parseInt(split[6],10);
parameters[7+4] = ph.param8 = parseInt(split[7],10);
parameters[8+4] = ph.param9 =
parseInt(split[8],10);
parameters[9+4] =
ph.param10 = parseInt(split[9],10);
parameters[10+4] = ph.param11 = parseInt(split[10],10);
parameters[11+4] = ph.param12 =
parseInt(split[11],10);
parameters[12+4] = ph.param13 = parseInt(split[12],10);
parameters[13+4] = ph.param14 =
parseInt(split[13],10);
parameters[14+4] = ph.param15 = parseInt(split[14],10);
parameters[15+4] = ph.param16 =
parseInt(split[15],10);
parameters[16+4] = ph.param17 = parseInt(split[16],10);
parameters[17+4] = ph.param18 =
parseInt(split[17],10);
parameters[18+4] = ph.param19 = parseInt(split[18],10);
parameters[19+4] = ph.param20 =
parseInt(split[19],10);
positions =
fd.calculatePositions(parameters, true);
if
(ph.draw_face) fd.draw(positions);
if
(ph.draw_grid) fd.drawGrid(positions);
}
var parameterHolder = function() {
this.param1 = 0.0001;
this.param2 = 0.0001;
this.param3 =

119

0.0001;

this.param4 = 0.0001;
this.param5 = 0.0001;
this.param6 = 0.0001;
this.param7 =
0.0001;
this.param8 = 0.0001;
this.param9 = 0.0001;
this.param10 = 0.0001;
this.param11 =
0.0001;
this.param12 = 0.0001;
this.param13 = 0.0001;
this.param14 = 0.0001;
this.param15 =
0.0001;
this.param16 = 0.0001;
this.param17 = 0.0001;
this.param18 = 0.0001;
this.param19 =
0.0001;
this.param20 = 0.0001;
this.presets = 0;
this.draw_face = true;
this.draw_grid
= false;
}
var presets =
{
"default" : [0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"oi mate"
: [0, 0, 13, 1.2, 0, -15, 0, 1, 8, -5, 0, 0, 0, 0, 0, 0, 0, 11.6, 0,
-7],
"unhappy" : [0, 0, 0, 0, 0, 0, 0, 0, 0,
-13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"greek" : [0, 0, 0, 1.6, 0, -6, 0, 0, 0, -13, 0, 4.7, 1, 0, 11,
-1, 8, 8, 0, 0],
"cheery" : [0, 0, 0, 0,
10.7, 0, 16.8, 0, 0, -5, 0, -4, 13, 0, 0, 0, 0, 0, 0, 0],
"luke" : [0, 0, -1.7, -8.7, -8, -4.8, 12.5, -1,
14.6, -11, 0, -2, -13, 0, 0, 0, 0, 7, 0, -3],
"chum" : [0, 0, 13, 1.2, 0, 2.5, 0, 1, 16.8, -5, 0, 0, 0, 0, 0,
0, 0, 11.6, 0, -7],
"disgust" : [-4, -14,
8, 2, 3, -5.6, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, 0, -5],
};
</script>

BLOK KODE 8:
Script Deteksi Emosi Wajah
<script>
var vid = document.getElementById('videoel');
var overlay =
document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');
/********** check and set up video/webcam
**********/
function enablestart() {
var startbutton =
document.getElementById('startbutton');
startbutton.value = "start";
startbutton.disabled = null;
}
/*var insertAltVideo = function(video) {
if (supports_video()) {
if (supports_ogg_theora_video())
{
video.src =
"../media/cap12_edit.ogv";
} else if
(supports_h264_baseline_video()) {

120

video.src =
"../media/cap12_edit.mp4";
} else {
return false;
}
//video.play();
return true;
} else return false;
}*/
navigator.getUserMedia =
navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL
|| window.msURL || window.mozURL;
// check for camerasupport
if (navigator.getUserMedia) {
// set up stream
var videoSelector = {video : true};
if
(window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
var chromeVersion =
parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1],
10);
if (chromeVersion < 20) {
videoSelector = "video";
}
};
navigator.getUserMedia(videoSelector,
function( stream ) {
if (vid.mozCaptureStream) {
vid.mozSrcObject = stream;
} else {
vid.src = (window.URL &&
window.URL.createObjectURL(stream)) || stream;
}
vid.play();
}, function() {
//insertAltVideo(vid);
alert("There was some problem
trying to fetch video from your webcam. If you have a webcam, please
make sure to accept when the browser asks for access to your
webcam.");
});
} else {
//insertAltVideo(vid);
alert("This demo depends on
getUserMedia, which your browser does not seem to support. :(");
}
vid.addEventListener('canplay', enablestart,
false);
/*********** setup of emotion detection
*************/
var ctrack = new clm.tracker({useWebGL :
true});
ctrack.init(pModel);

121

function startVideo() {
// start video
vid.play();
// start tracking
ctrack.start(vid);
// start loop to draw face
drawLoop();
}
function drawLoop() {
requestAnimFrame(drawLoop);
overlayCC.clearRect(0, 0, 400, 300);
//psrElement.innerHTML = "score :" +
ctrack.getScore().toFixed(4);
if (ctrack.getCurrentPosition()) {
ctrack.draw(overlay);
}
var cp = ctrack.getCurrentParameters();
var er = ec.meanPredict(cp);
if (er) {
updateData(er);
for (var i = 0;i < er.length;i++)
{
if (er[i].value > 0.4) {
document.getElementById('icon'+(i+1)).style.visibility =
'visible';
} else {
document.getElementById('icon'+(i+1)).style.visibility =
'hidden';
}
}
}
}
var ec = new emotionClassifier();
ec.init(emotionModel);
var emotionData = ec.getBlank();
/************ d3 code for barchart
*****************/
var margin = {top : 20, right : 20, bottom :
10, left : 40},
width = 400 - margin.left margin.right,
height = 100 - margin.top margin.bottom;
var barWidth = 30;
var formatPercent = d3.format(".0%");
var x = d3.scale.linear()
.domain([0,
ec.getEmotions().length]).range([margin.left, width+margin.left]);
var y = d3.scale.linear()

122

.domain([0,1]).range([0, height]);
var svg =
d3.select("#emotion_chart").append("svg")
.attr("width", width + margin.left +
margin.right)
.attr("height", height + margin.top +
margin.bottom)
svg.selectAll("rect").
data(emotionData).
enter().
append("svg:rect").
attr("x", function(datum, index) { return
x(index); }).
attr("y", function(datum) { return height y(datum.value); }).
attr("height", function(datum) { return
y(datum.value); }).
attr("width", barWidth).
attr("fill", "#2d578b");
svg.selectAll("text.labels").
data(emotionData).
enter().
append("svg:text").
attr("x", function(datum, index) { return
x(index) + barWidth; }).
attr("y", function(datum) { return height y(datum.value); }).
attr("dx", -barWidth/2).
attr("dy", "1.2em").
attr("text-anchor", "middle").
text(function(datum) { return
datum.value;}).
attr("fill", "white").
attr("class", "labels");
svg.selectAll("text.yAxis").
data(emotionData).
enter().append("svg:text").
attr("x", function(datum, index) { return
x(index) + barWidth; }).
attr("y", height).
attr("dx", -barWidth/2).
attr("text-anchor", "middle").
attr("style", "font-size: 12").
text(function(datum) { return
datum.emotion;}).
attr("transform", "translate(0, 18)").
attr("class", "yAxis");
function updateData(data) {
// update
var rects = svg.selectAll("rect")
.data(data)
.attr("y", function(datum) {
return height - y(datum.value); })
.attr("height", function(datum) {
return y(datum.value); });

123

var texts =
svg.selectAll("text.labels")
.data(data)
.attr("y", function(datum) {
return height - y(datum.value); })
.text(function(datum) { return
datum.value.toFixed(1);});
// enter
rects.enter().append("svg:rect");
texts.enter().append("svg:text");
// exit
rects.exit().remove();
texts.exit().remove();
}
/******** stats ********/
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild(
stats.domElement );
// update stats on every iteration
document.addEventListener('clmtrackrIteration', function(event)
{
stats.update();
}, false);
</script>

124

Anda mungkin juga menyukai