Anda di halaman 1dari 57

Fisherface Pengenalan Wajah OpenCV

Pengenalan Wajah

Secara umum sistem pengenalan citra wajah dibagi menjadi dua jenis, yaitu sistem feature-
based dan sistem image-based. Pada sistem pertama digunakan ciri yang diekstraksi dari
komponen citra wajah seperti mata, hidung, mulut, dan lain-lain yang kemudian dimodelkan
secara geometris hubungan antara ciri-ciri tersebut. Sedangkan pada sistem kedua menggunakan
informasi mentah dari piksel citra yang kemudian direpresentasikan dalam metode tertentu,
misalnya pada Principal Component Analysis (PCA) atau transformasi wavelet yang digunakan
untuk klasifikasi identitas citra.

Penelitian tentang deteksi wajah dan pengenalan wajah telah dilakukan sebelumnya, antara lain
dengan menggunakan algoritma Eigenface, dengan distribusi Gaussian dan Clustering, dengan
Support Vector Machine, dan dengan metode Statistic dan Wavelet.

Seorang peneliti bernama Alan Brooks pernah mengembangkan sebuah penelitian yang
membandingkan dua algoritma yaitu Eigenface dan Fisherface. Penelitian ini difokuskan pada
perubahan pose wajah apakah mempengaruhi akurasi pengenalan wajah. Diberikan database
latih berupa foto wajah manusia, kemudian digunakan untuk melatih sebuah sistem pengenalan
wajah, setelah proses latihan selesai, diberikan sebuah masukan image yang sebenarnya sama
dengan salah satu image wajah pada fase latihan tetapi dengan pose yang berbeda. Sistem juga
diharapkan punya sensitifitas minimal terhadap pencahayaan.

Sistem dikembangkan dengan dua algoritma yaitu Eigenface dan Fisherface, dan dibandingkan
hasilnya. Kedua teknik menghasilkan hasil yang memuaskan tetapi ada beberapa perbedaan.
Pada Eigenface kompleksitas komputasi lebih sederhana daripada Fisherface. Dari segi efektifitas
karena perubahan pose, Fisherface memberikan hasil yang lebih baik, bahkan dengan data yang
lebih terbatas. Teknik Eigenface juga lebih sensitif terhadap pencahayaan dibandingkan dengan
Fisherface.

Proses Pengenalan Wajah

Wajah merupakan bagian dari anggota tubuh manusia. Wajah memiliki keunikan sehingga setiap
wajah memiliki ciri atau karakteristik yang berbeda. Oleh karena itu, wajah dapat digunakan
sebagai pembeda antara wajah satu dengan wajah yang lainnya. Selain wajah, sidik jari, iris
mata, bentuk geometi telapang tangan juga bisa dijadikan pembeda. Secara umum sistem
pendeteksian dan pengenalan wajah di bagi menjadi 2 proses yaitu proses registrasi dan
identifikasi.

Proses Registrasi

Pada tahapan registrasi, citra wajah ditangkap (capture) oleh sebuah alat perekam (webcam)
kemudian pada citra tersebut akan dilakukan image preprocessing. Image preprocessing adalah
pengolahan awal suatu citra. Pada proses ini citra wajah akan dibersihkan dari gangguan seperti
gambar buram, bintik-bintik, kurang cahaya (noise). Proses berikutnya akan dilakukan lokalisasi
citra. Tujuannya adalah untuk mengetahui lokasi dari citra wajah. Tahapan berikutnya adalah
melakukan ekstraksi ciri dari citra wajah yang kemudian akan disimpan ke dalam database.

Proses Identifikasi

Pada tahapan identifikasi, proses yang dilakukan hampir sama dengan proses registrasi. Bedanya
adalah pada tahapan ini dilakukan pengukuran kemiripan antara data citra masukan dengan data
citra yang sudah disimpan di dalam database. Hal yang cukup sulit dari sistem pendeteksian dan
pengenalan wajah adalah bagaimana membuat sebuah sistem pendeteksi dan pengenalan wajah
yang cepat (mendekati waktu nyata) dan memiliki tingkat akurasi yang tinggi. Untuk mencapai
hal tersebut maka perlu dibuat sistem pengenalan wajah yang cepat dan tingkat akurasi yang
tinggi sehingga wajah dapat dikenali dengan cepat dan tepat.

Metode Fisherface

Fisherface Pengenalan Wajah OpenCV @ Wajah adl salah satu ukuran fisiologis yg paling
mudah & sering digunakan unt mem-bedakan indentitas individu yg satu dengan yg lainnya.
Manusia dapat membedakan wajah antara orang yg satu dengan yg lainnya & mengingat wajah
seseorang dengan cepat & mudah. Oleh krn itu, face recognition adl salah satu teknologi
biometrics yg banyak dipelajari & dikembangkan oleh para ahli.

Deteksi Wajah (Face Detection)

Langkah pertama pd pengenalan wajah scr otomatis adl mendeteksi keberadaan wajah dr gambar
masukan. Setelah wajah terdeteksi, tugas feature extraction adl unt memperoleh ciri-ciri dr wajah
yg diperlukan pd klasifikasi wajah. Bergantung pd tipe pengenalan wajahnya, ciri-ciri yg
diperlukan dapat berupa ciri-ciri lokal wajah seperti hidung, mata, mulut, & lainnya, maupun
ciri-ciri global wajah (seluruh bagian wajah). Metode fisherface memakai seluruh bagian wajah
sebagai data dlm pengenalannya.

Segmentasi Warna Kulit

Proses yg dilakukan pertama kali pd algoritma deteksi wajah yg digunakan adl membuang
sebanyak mungkin bagian bukan wajah dr gambar input. Hal ini dapat dilakukan dengan
memberikan batasan pd nilai intensitas warna (color thres-holding) pd gambar input krn pd
dasarnya seluruh manusia memiliki range atau cakupan nilai warna (chrominance value) yg
hampir sama unt warna kulitnya. Yang membedakannya adl variasi pd nilai intensitas cahayanya
(luminance value).

Salah satu cara memisahkan nilai intensitas cahaya dr komponen warna gambar masukan adl
dengan mentransformasi komponen warna gambar masukan yg adl gambar berwarna (RGB) ke
dlm komponen warna YCbCr (Iluminance, Chrominance-blue, Chrominance-red). Jika pd
komponen warna RGB masih terdapat informasi mengenai intensitas pencahayaan pd setiap
komponen warnanya (Red, Green, Blue), unt komponen warna YCbCr, komponen Cb & Cr adl
komponen warna yg bebas dr intensitas cahaya, krn seluruh informasi mengenai cahaya pd
gambar disimpan pd komponen Y

Metode Fisherface Pengenalan Wajah OpenCV

Proses Morfologi

Hasil dr proses segmentasi kulit adl topeng (mask) yg berupa gambar hitam putih (binary image)
yg menunjukkan bagian kulit dr gambar masukan. Akan tetapi topeng hasil segmentasi kulit
masih terdapat noise & potongan dr beberapa benda lainnya pd gambar, seperti latar belakang
gambar. Oleh krn itu, perlu dilakukan beberapa tahapan proses morfologi unt membersihkan
gambar dr noise & potongan tersebut

Teknik morfologi dapat dilakukan unt suatu gambar biner maupun gambar pd level grayscale
(abu-abu). Untuk gambar biner, piksel berwarna putih bernilai biner .1. (ON) & piksel berwarna
hitam bernilai biner .0. (OFF).

Proses morfologi unt gamber biner adl proses erosi & dilasi. Proses erosi membuang piksel dr
gambar atau ekivalen dengan membuat piksel ON menjadi OFF, yaitu piksel putih yg melekat pd
daerah background, sehingga akan menyebabkan piksel putih berkurang luasnya (shrinking)
dengan tujuan unt menghilangkan piksel yg adl noise pd topeng. Proses dilasi adl kebalikan dr
proses erosi, membuat piksel OFF menjadi ON, sehingga akan menyebabkan piksel putih
bertambah luasnya (growing). Tujuan dilakukan proses dilasi adl krn saat proses erosi dilakukan
pd topeng, daerah yg adl kulit juga ikut mengalami shrinking sehingga perlu dilakukan suatu
proses yg mengembalikan daerah tersebut agar bagian wajah nantinya akan terdeteksi dengan
benar.

Metode Fisherface Pengenalan Wajah OpenCV

Region Analysis

Gambar topeng hasil proses morfologi akan tetap terdapat bagian bukan wajah yg adl bagian
tubuh lainnya seperti tangan & bagian lainnya yg memiliki intensitas warna yg menyerupai
intensitas warna kulit. Pada proses region analysis akan dianalisa bagian-bagian tersebut unt
mendapatkan satu bagian yg adl bagian wajah, yaitu dengan menghitung nilai Euler dr tiap-tiap
bagian yg terdapat pd topeng. Nilai Euler pd gambar biner adl selisih antara region (daerah yg
memiliki nilai piksel 1) dengan hole (daerah yg memilki nilai piksel 0) yg ada pd region tersebut.
Pada umumnya unt wajah manusia setidaknya akan memiliki satu region & tiga buah hole pd
region tersebut yg menunjukkan sepasang mata & satu mulut

Metode Fisherface Pengenalan Wajah OpenCV


Ekstraksi Wajah

Setelah didapat satu bagian yg adl wajah, proses selanjutnya adl mengambil (cropping) wajah
tersebut dr gambar input dengan ukuran yg sesuai dengan posisi wajah pd gambar topeng &
mengubah ukurannya menjadi ukuran yg sama dengan ukuran gambar wajah pd training set yg
digunakan unt pengenalan wajah

Metode Fisherface Pengenalan Wajah OpenCV

Perhitungan PCA

Perhitungan PCA dilakukan dengan langkah-langkah sebagai berikut :

1. Mengambil satu set gambar training & kemudian mentransformasikan setiap gambar
tersebut menjadi vektor kolom, sehingga akan didapat satu matriks yg tiap kolomnya
mewakili gambar yg berbeda, face space.

2. Membentuk average face (), yaitu nilai rata-rata dr seluruh gambar wajah pd training
set, & mengurangi seluruh gambar pd training set terhadap average face unt mencari
deviasinya ().

3. Menghitung matriks kovarian (A), yaitu dengan melakukan operasi perkalian transpose
dr training set yg telah dinormalisasikan.

4. Menghitung nilai eigen ( ) & vektor eigen () dr matriks kovarian.

5. Mengurutkan vektor eigen berdasarkan dengan besarnya nilai eigen masing-masing


vektor.

6. Menghitung matriks proyeksi PCA (Wpca) yaitu dengan mengalikan nilai deviasi dengan
vektor eigen.

7. Mengambil N-C komponen Wpca yg diperlu-kan unt mengkonstruksi fisherface.

Perhitungan FLD
Perhitungan FLD dilakukan dengan langkah-langkah sebagai berikut :

1. Mentransformasikan training set ke dlm vektor kolom (face space).

2. Membentuk average face () dr face space, & nilai wajah rata-rata masing-masing kelas
(class average face)

3. Melakukan perhitungan matriks sebaran dlm kelas (within-calss scatter-matrix) & ma-
triks sebaran antar kelas (between-class scatter-matrix).

4. Memproyeksikan matriks sebaran (WS dan) ke dlm matriks proyeksi PCA (Wpca).

5. Menghitung nilai eigen & vektor eigen dr matriks sebaran.

6. Menghitung matriks proyeksi fisher dengan mengurutkan vektor eigen berdasarkan


besarnya nilai eigen masing-masing vektor eigen & mengambil komponen vektor eigen
yg memiliki nilai eigen tidak nol.Untuk C kelas, akan selalu didapat C-1 vektor eigen yg
memiliki nilai eigen tidak nol

7. Menghitung matriks proyeksi optimal.

8. Melakukan normalisasi pd matriks proyeksi optimal.

9. Menghitung bobot tiap fisherface terhadap masing-masing gambar wajah pd training set
(face key) dengan memproyeksikan nilai deviasi face space terhadap average face ke dlm
matriks proyeksi optimal.

Klasifikasi Identitas

Klasifikasi identitas yg digunakan adl dengan membandingkan bobot dr masing-masing


fisherface pd gambar wajah pd training set & gambar wajah masukan dengan menghitung jarak
Euclidian-nya. Langkah-langkah klasifikasi identitas adl sebagai berikut :

1. Mengubah gambar wajah masukan menjadi vektor kolom

2. Menormalisasikan gambar wajah masukan terhadap nilai rata-rata training set (average
face,).

3. Menghitung bobot fisherface pd gambar wajah masukan, yaitu dengan memproyeksikan


gambar masukan ke dlm matriks proyeksi optimal (Wopt).

4. Menghitung jarak euclidian (Emin) antara bobot input & bobot training set (Udatabase).

5. Mencari & membandingkan jarak minimum (Emin) dengan satu nilai batas (). Sebuah
wajah dikatakan cocok jika jarak minimumnya lebih kecil dr nilai batas yg diterapkan.
Semakin kecil jarak minimum yg diperoleh, semakin besar kesamaan (similarity) gambar
masukan dengan pasangan gambar pd training set. Nilai batas diperoleh dr hasil
percobaan-percobaan hingga ditemukan satu nilai yg memuaskan

Metode Fisherface Pengenalan Wajah Dengan OpenCV

Kesulitan dlm pembuatan proses face recognition terutama adl krn kekompleksan dr kondisi
wajah, yaitu alam hal kualitas gambar yg ditangkap, dr segi warna, pencahayaan, hingga posisi
gambar yg tertangkap, maupun dlm hal peru-bahan geometrinya. Oleh krn itu, dlm tulisan ini
akan diujikan metode fisherface unt melakukan pengenalan wajah.

Face recognition / pengenalan wajah adl salah satu teknik identifikasi teknologi biometrik
dengan memakai wajah individu yg bersangkutan sbg parameter utamanya. Secara garis besar
proses pengenalan wajah terdiri dr tiga proses utama [1], yaitu:

1. Deteksi wajah (face detection).


2. Ektraksi ciri/wajah (face/feature extraction).
3. Pengenalan wajah (face recognition).

wajah dapat dikelompokan ke dlm tiga pendekatan berdasarkan data yg dibutuhkannya [1], yaitu:

1. Pendekatan holistik.

Pada pendekatan holistik, seluruh bagian / ciri-ciri global wajah digunakan sbg data masukan unt
pengenalan wajah.
Contoh: eigenface, fisherface, nearest feature line (NFL), & support vector machine (SVM).

2. Pendekatan feature-based.

Pada pendekatan feature-based, wajah terbagi berdasarkan ciri-ciri lokal wajah seperti hidung,
mulut, mata, & lainnya yg kemudian digunakan sbg data masukan. Contoh : Hidden Markov
Model & Dynamic Link Architecture.

3. Pendekatan hybrid.

Pendekatan hybrid memakai seluruh bagian wajah & ciri-ciri lokal wajah sbg data masukan.
Contoh : modular eigenface & hybrid local feature.

METODE FISHERFACE

Pengenalan wajah yg akan direalisasikan terbagi ke dlm empat modul utama. Diagram blok yg
akan direalisasikan terlihat pd Gambar 1.

Gambar 1. Diagram Blok yg akan Direalisasikan


Deteksi Wajah (Face Detection)
Salah satu kunci sukses dlm pengenalan wajah adl deteksi wajah yg akurat krn gambar wajah yg
terdeteksi akan sangat mempengaruhi dlm proses pengenalannya [4]. Langkah pertama pd
pengenalan wajah scr otomatis adl mendeteksi keberadaan wajah dr gambar masukan. Setelah
wajah terdeteksi, tugas feature extraction adl unt memperoleh ciri-ciri dr wajah yang

diperlukan pd klasifikasi wajah. Bergantung pd tipe pengenalan wajahnya, ciri-ciri yg diperlukan


dapat berupa ciri-ciri lokal wajah seperti hidung, mata, mulut, & lainnya, maupun ciri-ciri global
wajah (seluruh bagian wajah). Metode fisherface memakai seluruh bagian wajah sbg data dlm
pengenalannya.

Segmentasi Warna Kulit

Proses yg dilakukan pertama kali pd algoritma deteksi wajah yg digunakan adl membuang
sebanyak mungkin bagian bukan wajah dr gambar input. Hal ini dapat dilakukan dengan
memberikan batasan pd nilai intensitas warna (color thres-holding) pd gambar input krn pd
dasarnya seluruh manusia memiliki range / cakupan nilai warna (chrominance value) yg hampir
sama unt warna kulitnya. Yang membedakannya adl variasi pd nilai intensitas cahayanya
(luminance value) [3]. Akibatnya, jika nilai chrominance & luminance dapat dipisahkan dr
gambar & kemudian dilakukan pembatasan nilai intensitas pd komponen chrominance, akan
didapat bagian yg adl bagian berwarna seperti kulit (skin like-hood) dr gambar input.

Pengenalan wajah adl adl suatu pengenalan pola (pattern recognition) yg khusus unt kasus wajah.
Ini dapat dideskripsikan sbg pengklasifikasian suatu wajah apakah dikenali (known) / tidak
dikenali (unknown), dimana setelah dibandingkan kemudian disimpan scr tersendiri. Beberapa
pendekatan unt pengenalan obyek & grafika komputer didasarkan scr langsung pd citra-citra
tanpa penggunaan model 3D. Banyak dr teknik ini tergantung pd suatu representasi citra yg
membentuk suatu struktur ruang vektor, & dlm prinsip ini memerlukan korespondensi yg padat.

Pendekatan appearance-based kebanyakan digunakan unt pengenalan wajah. Pada metode ini,
model wajah dipelajari melalui proses training dengan memakai satu set data pelatihan yg berisi
contoh-contoh wajah. Kemudian hasil training ini digunakan unt pengenalan wajah. Secara
umum metode ini memakai teknik-teknik analisis statistik & mesin pembelajaran (machine
learning) unt menemukan karakteristik-karakteristik yg sesuai dr wajah maupun non-wajah. Yang
termasuk dlm kelompok ini adl : Eigenfaces, distribution-based & clustering, jaringan syaraf
tiruan, SVM (Support VectorMmachine), dll.

Tiga pengklasifikasi linear appearance-based adl PCA, ICA and LDA. Tiap pengklasifikasi
mempunyai representasi (vector basis) tersendiri dr suatu ruang space vector wajah dengan
dimensi tinggi didasarkan pd titik pandang scr statistik yg berbeda. Melalui proyeksi vector
wajah ke vector basis, koefisien proyeksi digunakan sbg representasi fitur tiap citra wajah. Nilai
matching diantara citra wajah tes & pelatihan dihitung (sebagai contoh sudut nilai cosine)
diantara vector-vector koefisien. Ketiga representasi dapat dianggap sbg suatu transformasi linier
dr vector citra asli ke suatu vector fitur proyeksi.
Proyeksi citra ke dlm ruang eigen (eigenspace) adl suatu prosedur standar unt beberapa algoritma
pengenalan obyek yg didasarkan pd tampilan (appearance-based). Penelitian dasar tentang
proyeksi eigenspace pertama kali dilakukan oleh Michael Kirby yg memperkenalkan tentang ide
karakteristikasi dimensi rendah suatu wajah. Turk and Pentland memakai proyeksi eigenspace
unt pengenalan wajah. Eigenspace dihitung melalui identifikasi eigenvector dr matriks
kovariansi yg diturunkan dr suatu himpunan citra pelatihan (Turk and Pentland,1991)

Proyeksi ruang eigen (eigenspace) juga dikenal sbg Karhunen-Loeve (KL) / juga dinamakan
dengan Principal Component Analysis (PCA). Algoritma eigenface memanfaatkan Principal
Component Analysis (PCA) unt mereduksi dimensinya guna menemukan vector-vektor yg
mempunyai nilai terbaik unt distribusi citra wajah didlm ruang citra masukan.

Vektor ini mendefinsikan subruang dr citra-citra wajah & subruang tersebut dinamakan ruang
wajah. Semua wajah-wajah dlm himpunan pelatihan diproyeksikan ke dlm ruang wajah unt
menemukan suatu himpunan bobot-bobot yg mendeskripsikan kontribusi dr tiap vector dlm
ruang wajah. Untuk identifikasi suatu citra uji, membutuhkan proyeksi suatu citra ke dlm ruang
wajah unt menentukan korespondensi kumpulan bobot-bobot.

Dengan membandingkan kumpulan bobot-bobot wajah dlm training set, Pengujian citra dapat
diidentifikasi. Prosedur kunci dlm PCA didasarkan pd tranformasi Karhumen-Loeve. Jika
elemen-elemen citra dianggap sbg variable-variabel random, citra mungkin dilihat sbg sample
suatu proses stokastik.

Ide utama principal component analysis adl menemukan vektor dengan nilai terbaik unt
distribusi citra wajah dlm seluruh ruang citra. Vektor-vektor ini mendefinisikan subruang citra
wajah / biasa disebut dengan nama ruang wajah. Tiap vektor dengan panjang N2,
mendsikripsikan citra dengan ukuran N x N, yg adl suatu kombinasi linier dr citra wajah asli

Contoh Program Fisherface Pengenalan Wajah OpenCV

Fisherface unt Klasifikasi Jenis Kelamin

Metode fisherface mencapai tingkat pengenalan 98% dlm cross-validasi subjek-independen.


Sebuah subjek-independen meansimages lintas validasi dr orang yg diuji tidak pernah digunakan
unt belajar model. Dan bisa Anda percaya: Anda hanya dapat memakai facerec_fisherfaces
demo, yg inlcuded OpenCV.

Kode sumber unt aplikasi demo ini juga tersedia dlm folder src dokumentasi ini:

Source Code C++

#include "opencv2/core.hpp"
#include "opencv2/contrib.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include <fstream>
#include <sstream>

using namespace cv;


using namespace std;

static Mat norm_0_255(InputArray _src) {


Mat src = _src.getMat();

// Membuat & mengembalikan citra normalisasi:


Mat dst;
switch(src.channels()) {
case 1:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
break;
case 3:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
}

static void read_csv(const string& filename, vector<Mat>& images, vector<int>&


labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check
the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;

while (getline(file, line)) {


stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
}

int main(int argc, const char *argv[]) {

// Periksa argumen baris perintah yg sah, penggunaan cetak jika tidak ada
argumen yg diberikan.
if (argc < 2) {
cout << "usage: " << argv[0] << " <csv.ext> <output_folder> " << endl;
exit(1);
}
string output_folder;
if (argc == 3) {
output_folder = string(argv[2]);
}

// Dapatkan path ke CSV Anda.


string fn_csv = string(argv[1]);

// Vektor ini memegang gambar & label yg sesuai.


vector<Mat> images;
vector<int> labels;

// Baca di data. Hal ini dapat gagal jika tidak ada nama file input yg
valid diberikan.
try {
read_csv(fn_csv, images, labels);
} catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg
<< endl;
exit(1);
}

// Keluar jika tidak ada cukup gambar unt demo ini.


if(images.size() <= 1) {
string error_message = "This demo needs at least 2 images to work.
Please add more images to your data set!";
CV_Error(CV_StsError, error_message);
}

// Dapatkan ketinggian dr gambar pertama. Kita akan membutuhkan nanti ini


dlm kode unt membentuk kembali gambar ke ukuran aslinya:

int height = images[0].rows;

Mat testSample = images[images.size() - 1];


int testLabel = labels[labels.size() - 1];
images.pop_back();
labels.pop_back();

// Baris berikut membuat model fisherface unt


// Pengenalan wajah & melatihnya dengan gambar dan
// Label membaca dr file CSV yg diberikan.
// Jika Anda hanya ingin menyimpan 10 fisherface, kemudian memanggil
// Metode pabrik seperti ini:
//
// cv::createFisherFaceRecognizer(10);
//
// Namun tidak berguna unt membuang fisherface! mohon Untuk
// Selalu mencoba unt memakai _all_ tersedia fisherface unt
// Klasifikasi.
//
// Jika Anda ingin membuat FaceRecognizer dengan
// Batas kepercayaan (misalnya 123,0) & memakai _all_
// Fisherface, kemudian menyebutnya dengan:
//
// cv::createFisherFaceRecognizer(0, 123.0);
//

Ptr<FaceRecognizer> model = createFisherFaceRecognizer();


model->train(images, labels);

// Baris berikut memprediksi label yg diberikan


// test image:
int predictedLabel = model->predict(testSample);
//
// Untuk mendapatkan kepercayaan dr prediksi panggilan model dengan:
//
// int predictedLabel = -1;
// double confidence = 0.0;
// model->predict(testSample, predictedLabel, confidence);
//
string result_message = format("Predicted class = %d / Actual class =
%d.", predictedLabel, testLabel);
cout << result_message << endl;

// Berikut adl cara unt mendapatkan nilai eigen model Eigenfaces ini:
Mat eigenvalues = model->getMat("eigenvalues");

// Dan kita bisa melakukan hal yg sama unt menampilkan Vektor Eigen (baca
Eigenfaces):
Mat W = model->getMat("eigenvectors");

// Dapatkan mean sampel dr data pelatihan


Mat mean = model->getMat("mean");

// Menampilkan / menyimpan:
if(argc == 2) {
imshow("mean", norm_0_255(mean.reshape(1, images[0].rows)));
} else {
imwrite(format("%s/mean.png", output_folder.c_str()),
norm_0_255(mean.reshape(1, images[0].rows)));
}

// Menampilkan / menyimpan pertama, paling 16 fisherface:


for (int i = 0; i < min(16, W.cols); i++) {
string msg = format("Eigenvalue #%d = %.5f", i,
eigenvalues.at<double>(i));
cout << msg << endl;

// dapatkan eigenvector #i
Mat ev = W.col(i).clone();

// Membentuk ke ukuran aslinya & menormalkan ke [0 ... 255] unt


imshow.
Mat grayscale = norm_0_255(ev.reshape(1, height));

// Tampilkan gambar & menerapkan colormap tulang unt penginderaan yg


lebih baik.
Mat cgrayscale;
applyColorMap(grayscale, cgrayscale, COLORMAP_BONE);
// Menampilkan / menyimpan:
if(argc == 2) {
imshow(format("fisherface_%d", i), cgrayscale);
} else {
imwrite(format("%s/fisherface_%d.png", output_folder.c_str(), i),
norm_0_255(cgrayscale));
}
}

// Menampilkan / menyimpan rekonstruksi gambar di beberapa langkah yg


telah ditetapkan:
for(int num_component = 0; num_component < min(16, W.cols); num_component+
+) {

// Potong Fisherface dr model:


Mat ev = W.col(num_component);
Mat projection = subspaceProject(ev, mean, images[0].reshape(1,1));
Mat reconstruction = subspaceReconstruct(ev, mean, projection);

// Menormalkan hasilnya:
reconstruction = norm_0_255(reconstruction.reshape(1,
images[0].rows));

// Menampilkan / menyimpan:
if(argc == 2) {
imshow(format("fisherface_reconstruction_%d", num_component),
reconstruction);
} else {
imwrite(format("%s/fisherface_reconstruction_%d.png",
output_folder.c_str(), num_component), reconstruction);
}
}
// Tampilan jika kita tidak menulis ke folder output:
if(argc == 2) {
waitKey(0);
}
return 0;
}

Deteksi Wajah Viola Jones Java


Metode Viola-Jones merupakan metode pendeteksian obyek yang memiliki tingkat keakuratan
yang cukup tinggi yaitu sekitar 93,7 % dengan kecepatan 15 kali lebih cepat daripada detektor
Rowley Baluja-Kanade dan kurang lebih 600 kali lebih cepat daripada detektor Schneiderman-
Kanade. Metode ini, diusulkan oleh Paul Viola dan Michael Jones pada tahun 2001. Metode
Viola-Jones menggabungkan empat kunci utama yaitu Haar Like Feature, Integral Image,
Adaboost learning dan Cascade classifier.
Haar Like Feature yaitu selisih dari jumlah piksel dari daerah di dalam persegi panjang. Contoh
Haar Like Feature disajikan dalam Gambar berikut :

Contoh Haar Like Feature


Deteksi Wajah Viola Jones Java
Nilai Haar Like Feature diperoleh dari selisih jumlah nilai piksel daerah gelap dengan jumlah
nilai piksel daerah terang :

F ( Haar ) = F white - F black


Dimana :

F ( Haar ) = Nilai fitur total


F white = Nilai fitur pada daerah terang
F black = Nilai fitur pada daerah gelap

Integral Image yaitu suatu teknik untuk menghitung nilai fitur secara cepat dengan mengubah
nilai dari setiap piksel menjadi suatu representasi citra baru, sebagaimana disajikan dalam
Gambar berikut :

Integral image (x,y)


Deteksi Wajah Viola Jones Java

Berdasarkan Gambar diatas, citra integral pada titik (x,y) (ii(x,y)) dapat dicari menggunakan
persamaan

Keterangan :

ii(x,y) = Citra integral pada lokasi x,y


i(x',y') = nilai piksel pada citra asli
Perhitungan nilai dari suatu fitur dapat dilakukan secara cepat dengan menghitung nilai citra
integral pada empat buah titik sebagaimana disajikan dalam Gambar berikut :

Perhitungan Nilai Fitur


Deteksi Wajah Viola Jones Java
Jika nilai integral image titik 1 adalah A, titik 2 adalah A+B, titik 3 adalah A+C, dan di titiki 4
adalah A+B+C+D, maka jumlah piksel di daerah D dapat diketahui dengan cara 4 + 1 - ( 2 + 3 )

Algoritma Adaboost learning, digunakan untuk meningkatkan kinerja klasifikasi dengan


pembelajaran sederhana untuk menggabungkan banyak classifier lemah menjadi satu classifier
kuat. Classifier lemah adalah suatu jawaban benar dengan tingkat kebenaran yang kurang akurat.
Sebuah classifier lemah dinyatakan:

Keterangan :

hj(x) adalah klasifikasi lemah


Pj adalah parity ke j
j adalah threshold ke j
x adalah dimensi sub image misalnya 24x24.

Langkah-langkah untuk mendapatkan sebuah classifier kuat dinyatakan dalam suatu algoritma
sebagai berikut :

1. Diberikan contoh gambar (X1, Y1) , ... (Xn, Yn) dimana Yi = 0 untuk contoh positif dan Yi = 1
untuk contoh negatif

2. Inisialisasi bobot ;

m dan l adalah jumlah negatif dan positif.

3. Untuk t = 1 , ... , T
Menormalkan bobot sehingga wt adalah distribusi probabilitas

Untuk setiap fitur, j melatih classifier hj , untuk setiap fitur tunggal.

Kesalahan ( j) dievaluasi dengan bobot wt

Pilih classifier ht dengan eror terkecil dimana ei = 0 untuk xi adalah klaifikasi benar, dan ei = 1
untuk yang lain.

Perbaharui bobot :

Dimana :

Didapatkan sebuah Classifier kuat yaitu

dimana

Cascade classifier adalah sebuah metode untuk mengkombinasikan classifier yang kompleks
dalam sebuah struktur bertingkat yang dapat meningkatkan kecepatan pendeteksian obyek
dengan memfokuskan pada daerah citra yang berpeluang saja. Struktur cascade 43lassifier
disajikan Gambar berikut :
Cascade Clasifier
Deteksi Wajah Viola Jones Java
Di asumsikan suatu sub image di evaluasi oleh classifier pertama dan berhasil melewati classifier
tersebut, hal ini mengindikasikan sub image berpotensi terkandung obyek dan dilanjutkan pada
classifier ke dua sampai dengan ke-n, jika berhasil melewati keseluruhan classifier, maka
disimpulkan terdapat obyek yang dideteksi. Jika tidak, proses evaluasi tidak dilanjutkan ke
classifier berikutnya dan disimpulkan tidak terdapat obyek.

CONTOH PROGRAM
JAVA : Viola Jones

Berikut adalah contoh implementasi program metode Viola Jones dengan menggunakan bahasa
pemrograman Java.

Source Code Java

package jviolajones;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.Point;
import java.io.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.filter.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Detector {


List<Stage> stages;
Point size;
public Detector(String filename) throws java.io.FileNotFoundException{
this(new FileInputStream(filename));
}
public Detector(InputStream input) {
org.jdom.Document document=null;
Element racine;
stages=new LinkedList<Stage>();
SAXBuilder sxb = new SAXBuilder();
try
{
document = sxb.build(input);
}
catch(Exception e){e.printStackTrace();}
racine = (Element) document.getRootElement().getChildren().get(0);
Scanner scanner = new Scanner(racine.getChild("size").getText());
size = new Point(scanner.nextInt(),scanner.nextInt());
Iterator it=racine.getChild("stages").getChildren("_").iterator();
while(it.hasNext())
{
Element stage=(Element)it.next();
float
thres=Float.parseFloat(stage.getChild("stage_threshold").getText());
Iterator it2=stage.getChild("trees").getChildren("_").iterator();
Stage st=new Stage(thres);
while(it2.hasNext())
{
Element tree = ((Element)it2.next());
Tree t = new Tree();
Iterator it4 = tree.getChildren("_").iterator();
while(it4.hasNext())
{
Element feature=(Element) it4.next();
float
thres2=Float.parseFloat(feature.getChild("threshold").getText());
int left_node=-1;
float left_val = 0;
boolean has_left_val =false;
int right_node=-1;
float right_val = 0;
boolean has_right_val =false;
Element e;
if((e=feature.getChild("left_val"))!=null)
{
left_val = Float.parseFloat(e.getText());
has_left_val=true;
}
else
{
left_node =
Integer.parseInt(feature.getChild("left_node").getText());
has_left_val=false;
}

if((e=feature.getChild("right_val"))!=null)
{
right_val = Float.parseFloat(e.getText());
has_right_val=true;
}
else
{
right_node =
Integer.parseInt(feature.getChild("right_node").getText());
has_right_val=false;
}
Feature f = new
Feature(thres2,left_val,left_node,has_left_val,right_val,right_node,has_right_
val,size);
Iterator
it3=feature.getChild("feature").getChild("rects").getChildren("_").iterator();
while(it3.hasNext())
{
String s = ((Element) it3.next()).getText().trim();
Rect r = Rect.fromString(s);
f.add(r);
}
t.addFeature(f);
}
st.addTree(t);
}
stages.add(st);
}
}
public List<java.awt.Rectangle> getFaces(String filename, float baseScale,
float scale_inc,float increment, int min_neighbors,boolean doCannyPruning)
throws java.io.FileNotFoundException, java.io.IOException{
return getFaces(new FileInputStream(filename), baseScale, scale_inc,
increment, min_neighbors, doCannyPruning);
}
public List<java.awt.Rectangle> getFaces(InputStream input, float
baseScale, float scale_inc,float increment, int min_neighbors,boolean
doCannyPruning) throws java.io.FileNotFoundException, java.io.IOException{
return getFaces(ImageIO.read(input), baseScale, scale_inc, increment,
min_neighbors, doCannyPruning);
}
public List<java.awt.Rectangle> getFaces(BufferedImage image, float
baseScale, float scale_inc,float increment, int min_neighbors,boolean
doCannyPruning)
{
List<Rectangle> ret=new ArrayList<Rectangle>();
int width=image.getWidth();
int height=image.getHeight();
float maxScale = (Math.min((width+0.f)/size.x,(height+0.0f)/size.y));
int[][] grayImage=new int[width][height];
int[][] img = new int[width][height];
int[][] squares=new int[width][height];
for(int i=0;i<width;i++)
{
int col=0;
int col2=0;
for(int j=0;j<height;j++)
{
int c = image.getRGB(i,j);
int red = (c & 0x00ff0000) >> 16;
int green = (c & 0x0000ff00) >> 8;
int blue = c & 0x000000ff;
int value=(30*red +59*green +11*blue)/100;
img[i][j]=value;
grayImage[i][j]=(i>0?grayImage[i-1][j]:0)+col+value;
squares[i][j]=(i>0?squares[i-1][j]:0)+col2+value*value;
col+=value;
col2+=value*value;
}
}
int[][] canny = null;
if(doCannyPruning)
canny = getIntegralCanny(img);
for(float scale=baseScale;scale<maxScale;scale*=scale_inc)
{
int step=(int) (scale*24*increment);
int size=(int) (scale*24);
for(int i=0;i<width-size;i+=step)
{
for(int j=0;j<height-size;j+=step)
{
if(doCannyPruning)
{
int edges_density = canny[i+size][j+size]+canny[i][j]-canny[i]
[j+size]-canny[i+size][j];
int d = edges_density/size/size;
if(d<20||d>100)
continue;
}
boolean pass=true;
int k=0;
for(Stage s:stages)
{

if(!s.pass(grayImage,squares,i,j,scale))
{pass=false;
break;}
k++;
}
if(pass) ret.add(new Rectangle(i,j,size,size));
}
}
}
return merge(ret,min_neighbors);
}
public int[][] getIntegralCanny(int[][] grayImage)
{
int[][] canny = new int[grayImage.length][grayImage[0].length];
for(int i=2;i<canny.length-2;i++)
for(int j=2;j<canny[0].length-2;j++)
{
int sum =0;
sum+=2*grayImage[i-2][j-2];
sum+=4*grayImage[i-2][j-1];
sum+=5*grayImage[i-2][j+0];
sum+=4*grayImage[i-2][j+1];
sum+=2*grayImage[i-2][j+2];
sum+=4*grayImage[i-1][j-2];
sum+=9*grayImage[i-1][j-1];
sum+=12*grayImage[i-1][j+0];
sum+=9*grayImage[i-1][j+1];
sum+=4*grayImage[i-1][j+2];
sum+=5*grayImage[i+0][j-2];
sum+=12*grayImage[i+0][j-1];
sum+=15*grayImage[i+0][j+0];
sum+=12*grayImage[i+0][j+1];
sum+=5*grayImage[i+0][j+2];
sum+=4*grayImage[i+1][j-2];
sum+=9*grayImage[i+1][j-1];
sum+=12*grayImage[i+1][j+0];
sum+=9*grayImage[i+1][j+1];
sum+=4*grayImage[i+1][j+2];
sum+=2*grayImage[i+2][j-2];
sum+=4*grayImage[i+2][j-1];
sum+=5*grayImage[i+2][j+0];
sum+=4*grayImage[i+2][j+1];
sum+=2*grayImage[i+2][j+2];

canny[i][j]=sum/159;
}
int[][] grad = new int[grayImage.length][grayImage[0].length];
for(int i=1;i<canny.length-1;i++)
for(int j=1;j<canny[0].length-1;j++)
{
int grad_x =-canny[i-1][j-1]+canny[i+1][j-1]-2*canny[i-1][j]
+2*canny[i+1][j]-canny[i-1][j+1]+canny[i+1][j+1];
int grad_y = canny[i-1][j-1]+2*canny[i][j-1]+canny[i+1][j-1]-
canny[i-1][j+1]-2*canny[i][j+1]-canny[i+1][j+1];
grad[i][j]=Math.abs(grad_x)+Math.abs(grad_y);
}
for(int i=0;i<canny.length;i++)
{
int col=0;
for(int j=0;j<canny[0].length;j++)
{
int value= grad[i][j];
canny[i][j]=(i>0?canny[i-1][j]:0)+col+value;
col+=value;
}
}
return canny;
}
public List<java.awt.Rectangle> merge(List<java.awt.Rectangle> rects, int
min_neighbors)
{
List<java.awt.Rectangle> retour=new LinkedList<java.awt.Rectangle>();
int[] ret=new int[rects.size()];
int nb_classes=0;
for(int i=0;i<rects.size();i++)
{
boolean found=false;
for(int j=0;j<i;j++)
{
if(equals(rects.get(j),rects.get(i)))
{
found=true;
ret[i]=ret[j];
}
}
if(!found)
{
ret[i]=nb_classes;
nb_classes++;
}
}
//System.out.println(Arrays.toString(ret));
int[] neighbors=new int[nb_classes];
Rectangle[] rect=new Rectangle[nb_classes];
for(int i=0;i<nb_classes;i++)
{
neighbors[i]=0;
rect[i]=new Rectangle(0,0,0,0);
}
for(int i=0;i<rects.size();i++)
{
neighbors[ret[i]]++;
rect[ret[i]].x+=rects.get(i).x;
rect[ret[i]].y+=rects.get(i).y;
rect[ret[i]].height+=rects.get(i).height;
rect[ret[i]].width+=rects.get(i).width;
}
for(int i = 0; i < nb_classes; i++ )
{
int n = neighbors[i];
if( n >= min_neighbors)
{
Rectangle r=new Rectangle(0,0,0,0);
r.x = (rect[i].x*2 + n)/(2*n);
r.y = (rect[i].y*2 + n)/(2*n);
r.width = (rect[i].width*2 + n)/(2*n);
r.height = (rect[i].height*2 + n)/(2*n);
retour.add(r);
}
}
return retour;
}
public boolean equals(Rectangle r1, Rectangle r2)
{
int distance = (int)(r1.width*0.2);
if(r2.x <= r1.x + distance &&
r2.x >= r1.x - distance &&
r2.y <= r1.y + distance &&
r2.y >= r1.y - distance &&
r2.width <= (int)( r1.width * 1.2 ) &&
(int)( r2.width * 1.2 ) >= r1.width) return true;

if(r1.x>=r2.x&&r1.x+r1.width<=r2.x+r2.width&&r1.y>=r2.y&&r1.y+r1.height<=r2.y+
r2.height) return true;
return false;
}
}

Algoritma Haar Cascade Classifier


OpenCV memakai suatu tipe face detector yg disebut Haar-cascade classifier. Jika terbisa
suatu image (bisa dr file /live video), face detector akan melakukan proses pengujian tiap lokasi
image & mengklasifikasinya sbg wajah or bukan wajah. Klasifikasi wajah ini memakai
suatu pemisalan skala yg tetap, misalnya 5050 pixel. Jika wajah pd image lebih besar or lebih
kecil dr pixel tersebut, classifier terus menerus jalan beberapa kali, unt mencari wajah pd gambar
tersebut.

Classifier memakai data yg disimpan pd file XML unt memutuskan bagaimana mengklasifikasi
tiap lokasi image. OpenCV memakai 4 data XML unt deteksi wajah depan, & satu unt wajah
profile. Termasuk juga 3 file XML unt bukan wajah: satu unt mendeteksi badan secara penuh,
satu unt badan bagian atas, & satu unt badan bagian bawah. Kita harus memberitahukan
(mendeklarasikan) letak dr classifier yg dipakai. Salah satunya bernama
haarcascade_frontalface_default.xml.

Deteksi Wajah Algoritma Haar Cascade Classifier

Haar-Like Feature

Secara umum, Haar-Like Feature dipakai dlm mendeteksi objek pd image digital. Nama Haar
merujuk pd suatu fungsi matematika (Haar Wavelet) yg berbentuk kotak, prinsipnya sama seperti
pd fungsi Fourier. Awalnya pengolahan gambar hanya dng melihat dr nilai RGB setiap pixel,
namun metoda ini ternyata tidaklah efektif. Viola & Jones lalu mengembangkannya sehingga
terbentuk Haar-Like feature.

Haar-like feature memproses gambar dlm kotak-kotak, dimana dlm satu kotak terbisa beberapa
pixel. Per kotak itu pun lalu di-proses & dibisakan perbedaan nilai (threshold) yg menandakan
daerah gelap & terang. Nilai nilai inilah yg nantinya dijadikan dasar dlm image processing.

Lalu unt gambar bergerak(video), perhitungan & penjumlahan pixel terjadi secara terus
menerus & membutuhkan waktu yg lama. Oleh sebab itu, penjumlahan diganti dng integral
sehingga dibisakan hasil lebih cepat. Hasil deteksi dr Haar-Like kurang akurat jika hanya
memakai satu fungsi saja sehingga biasanya dipakai beberapa fungsi sekaligus (massal). makin
banyak fungsi yg dipakai maka hasilnya akan makin akurat. Pemrosesan Haar-Like feature yg
banyak tersebut diorganisir or diatur di dlm classifier cascade.

Hasil deteksi Haar-like Feature kurang akurat jika hanya memakai satu fungsi saja. makin tinggi
tingkatan filter pendeteksian maka makin tepat pula suatu obyek dideteksi akan tetapi akan
makin lama proses pendeteksiannya. Pemrosesan Haar-like feature yg banyak tersebut diatur dlm
classifier cascade.

Haar-Wavelet (Wave = Gelombang) adl gelombang persegi (interval gelap & interval terang)
yg lalu dibandingkan nilai rata-rata pixel keduanya. bila perbandingan nilai rata-rata intensitas
tersebut berada di atas threshold (ambang batas), maka disebut memenuhi syarat fitur Haar. unt
gambar bergerak seperti video, proses ini dikerjakan secara diskrit dng mencuplik video pd
frame rate tertentu. Macam-macam variasi Haar-like feature ditunjukkan pd gambar 3 sbg
berikut (Pavani, Delgadoa, & Frangia, 2010):
Berbagai variasi persegi Haar dng Bobot Standar Persegi Panjang
Deteksi Wajah Algoritma Haar Cascade Classifier
Keterangan gambar :

a, b : Fitur Haar yg diusulkan Papageogiou dkk.

c : Fitur Haar yg diusulkan Viola & James

d, e, f : Variasi fitur Haar yg diusulkan Leinhardt

g, h : Penguraian Lietal terhadap Fitur Haar-like

i : Fitur Haar-like Viola & James unt menangkap struktur diagonal dlm penampilan obyek

Perhitungan nilai fitur Gambar 3 di atas ditunjukkan pd Gambar & formula sbg berikut:
Fitur Persegi Haar-like
Deteksi Wajah Algoritma Haar Cascade Classifier

NilaiFitur(ABFE) = JumlahNilaiPixel(ABDC)-JumlahNilaiPixel(CDFE)

bila NilaiFitur (ABFE) punya nilai di atas threshold maka disebut memenuhi syarat. Seperti
dijelaskan pd gambar 2, bila suatu fitur disebut tidak memenuhi syarat, maka area ABFE tidak
terbisa obyek yg dideteksi & area perseginya berpindah lokasi akan tetapi jika persegi ABFE
memenuhi fitur, maka aturan fitur berikutnya dikerjakan. Jika semua syarat fitur dipenuhi disebut
pd persegi ABFE disebut terbisa obyek.

Deteksi Wajah Algoritma Haar Cascade Classifier

Integral image

suatu citra digital punya komponen nilai RGB (kombinasi dr warna merah, hijau & biru). dr nilai
RGB tersebut bisa diketahui nilai grayscale (derajat keabu-abuan) yg dihitung memakai formula
(2) sbg berikut:
Grayscale_pixel = 0.2989R + 0.5870G + 0.1140B
Sebagai contoh suatu pixel punya kombinasi warna R=100, B=100 & G=100 maka nilai
grayscale menurut formula 2 di atas sama dng 99.99. Proses pendeteksian obyek ditunjukkan pd
diagram alir di Gambar sbg berikut:
Deteksi Wajah Algoritma Haar Cascade Classifier
Pertama, ditentukan terlebih dahulu area yg akan dideteksi apakah terbisa obyek or tidak. Proses
berikutnya adalah melakukan pendeteksian obyek memakai Haar Cascade Clasifier dng
langkah-langkah yg akan dijelaskan nanti

Citra integral adalah suatu citra yg nilai tiap pixel-nya adl penjumlahan nilai pixel atas &
kirinya. sbg contoh pd gambar 5 (c) suatu daerah persegi yg akan di-scan memakai persegi gelap
terang punya nilai sbg berikut:
Deteksi Wajah Algoritma Haar Cascade Classifier
Proses integral image matriks citra ditentukan memakai formula sbg berikut:

s(x,y)=i(x,y)+s(x-1,y)+s(x,y-1)-s(x-1,y-1)
Dimana x-1 & y-1 adalah pixel tetangga dr pixel yg akan dihitung

Nilai fitur Haar dr area matriks dihitung memakai formula sbg berikut:

i(x',y')=s(A)+s(D)+s(B)-s(C)
Sehingga:

fitur nilai Haar = (32+2-16-5)-(49+5-32-6)+(77+6-49-9) = 22

Konsep Pendeteksian Wajah

OpenCV face detector memakai metode Paul-Viola & Michael Jones yg dipublikasikan pd tahun
2001. Pendekatan ini mendeteksi objek dng menggabungkan 4 konsep :

Fitur rectangular sederhana yg disebut fitur Haar

Integral image unt deteksi fitur yg cepat

Metode machine learning AdaBoost.

suatu pengklasifikasi cascade unt mengkombinasikan banyak fitur secara efisien.

Fitur yg dipakai Viola & Jones memakai bentuk gelombang Haar. Bentuk gelombang Haar ialah
suatu gelombang kotak. pd 2 dimensi, gelombang kotak ialah pasangan persegi yg bersebelahan,
1 terang & 1 gelap. Haar ditentukan oleh pengurangan pixel rata-rata daerah gelap dr pixel rata-
rata daerah terang. Jika perbedeaan diatas threshold (diset selama learning), fitur tersebut disebut
ada. unt menentukan terbisa or tidaknya Haar feature di setiap lokasi image / gambar, Viola &
Jones memakai teknik yg disebut Integral Image. Umumnya integral menambahkan unit kecil
secara bersamaan. dlm hal ini unit kecil ini disebut dng nilai dr pixel. Nilai dr integral / integral
value pd masing-masing pixel adl penjumlahan dr semua pixel di atasnya & di sebelah kirinya.
Dimulai dr kiri atas sampai kanan bawah, image / gambar bisa diintegrasikan sbg operasi
matematika per pixel.
Deteksi Wajah Algoritma Haar Cascade Classifier
unt memilih fitur Haar yg dipakai & unt mengubah nilai threshold, Viola & Jones memakai
metode machine-learning yg disebut AdaBoost. AdaBoost menggabungkan banyak classifier unt
membuat satu classifier. Masing-masing classifier menetapkan suatu bobot, & gabungan dr bobot
inilah yg akan membentuk satu classifier yg kuat.

Viola & Jones menggabungkan serangkaian AdaBoost classifier sbg rantai filter / filter chain.
Masing-masing filter adl AdaBoost classifier yg terpisah dng jumlah weak classifier yg sedikit &
sama.
Deteksi Wajah Algoritma Haar Cascade Classifier

Filter pd masing-masing level dilatih unt mengklasifikasikan gambar yg sebelumnya telah


difilter (Training set adl database dr wajah). Selama penggunaannya, jika satu dr filter-filter
tersebut gagal, image region / daerah pd gambar diklasifikasikan sbg Bukan Wajah. Saat filter
berhasil melewatkan image region, image region lalu masuk pd filter yg selanjutnya. Image
region yg telah melalui semua filter akan dianggap sbg Wajah.
Deteksi Wajah Algoritma Haar Cascade Classifier

CONTOH PROGRAM
Fungsi deteksi dan penampil

Fungsi deteksi dan penampil adalah sebagai berikut:

Source Code C++

void detectAndDisplay( Mat frame )


{
std::vector<Rect> cars;
cv::Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
cars_cascade.detectMultiScale( frame_gray, cars, 1.1, 2, 0|
CV_HAAR_SCALE_IMAGE, Size(30, 30));

for( size_t i = 0; i < cars.size(); i++ )


{
Point center( cars[i].x + cars[i].width*0.5, cars[i].y +
cars[i].height*0.5 );
ellipse( frame, center, Size( cars[i].width*0.5, cars[i].height*0.5), 0,
0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
}

cv::imshow( window_name, frame );


}

Membuka Koneksi Dengan IP Camera

Tahapan pertama dalam proses deteksi kendaraan adalah membuka koneksi ke IP camera.
Protokol yang digunakan adalah Real Time Streaming Protocol (RTSP). Petikan kode program
berikut adalah proses inisialisasi IP Camera menggunakan protokol RTSP:

Source Code C++

CvCapture* capture = cvCaptureFromFile("rtsp://192.168.1.1/MJPG?


Q=50&BR=3000000");
if (capture==NULL) {
printf("video is not ok\n");
system("PAUSE");
}
else
printf("video is ready\n");
}
Memanggil Cascade Classifier

Bagian ini digunakan untuk memanggil file cascade classifier yang telah dideklarasikan pada
global variable. Berikut petikan programnya:

Source Code C++

if( !cars_cascade.load( cars_cascade_name ) )


{
printf("--(!)Error loading\n"); system("PAUSE");
return -1;
};

Baca Video Stream IP Camera

Proses berikutnya adalah membaca stream dari video yang ditangkap oleh IP Camera. Berikut
adalah petikan programnya:

Source Code C++

if( capture )
{
while( true )
{
frame = cvQueryFrame( capture );
if( !frame.empty() ) {
detectAndDisplay( frame );
}
else {
printf(" --(!) Tidak ada frame yang terbaca -- Break!");
break; }
int c = waitKey(10);
if( (char)c == 'c' ) { break;
}
}
}

Proses Deteksi Wajah

Berikut adalah code unt deteksi wajah / face detection :

Source Code C++

void detect_faces(IplImage* img)


{
/* pertama-tama kita harus mengambil file XML
dng cvLoad(file name, memory storage, name, real name)
file name diisikan dng classifier file XML yg sudah
di-deklarasikan sebelumnya char*
file = C:/OpenCV2.0/data/haarcascades/haarcascade_frontalface_alt.xml;
memory storage, name, & real name diberikan nilai 0 saja.
lalu buat instance dr cvHaarClassifierCascade & panggil fungsi load.
*/

if (!cascade) {
char* file =
C:/OpenCV2.0/data/haarcascades/haarcascade_frontalface_alt.xml;
cascade = (CvHaarClassifierCascade*) cvLoad(file, 0, 0, 0);
/* Buat suatu memory storage kosong. Memory ini bersifat expandable
& berfungsi unt menyimpan hasil dr face detection
*/
storage = cvCreateMemStorage(0);
}

/* jabarkan semua element yg akan dipakai


dlm face detection dng cvSeq */

CvSeq* faces = cvHaarDetectObjects(


img, /* inputan gambar/video */
cascade, /* classifier yg sudah dideklarasikan sebelumnya */
storage, /* memory storage tempat menyimpan hasil detection */
1.1, /* nilai scale faktor. 1.1 menghasilkan detektor
bekerja dng cepat namun akurasi-nya rendah */
1, /* menunjukkan seberapa banyak kotak yg bisa
dihasilkan unt diproses lebih lanjut */
CV_HAAR_DO_CANNY_PRUNING, /*CV_HAAR_DO_CANNY_PRUNING akan men-skip
daerah yg dianggap bukan wajah */
cvSize(10, 10) /* dimensi ukuran terkecil dr wajah yg mungkin terbentuk
*/
);

int i;

/* Deklarasikan kotak sbg daerah hasil detector */

for( i = 0; i < (faces ? faces->total : 0); i++ ) {


CvRect* r = (CvRect*)cvGetSeqElem(faces, i);
cvRectangle(
img,
cvPoint(r->x, r->y),
cvPoint(r->x + r->width, r->y + r->height),
CV_RGB(255, 0, 0),
1, 8, 0
);
}
}

Proses Grayscale
Sebelum openCV melakukan pendeteksian wajah kita bisa melakukan beberapa image
processing terlebih dahulu. pd bagian ini, kami melakukan image processing yaitu, grayscale,
smoothing (filtering), & adaptive threshold. memakai fungsi cv_RGB2GRAY unt merubah
gambar RGB (3 channel) menjadi gambar grayscale. Setelah menjadi grayscale maka dikerjakan
face detection & hasilnya Haar-cascade masih data mendeteksi bagian wajah.

Berikut adalah code-nya :

Source Code C++

CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );


if ( !capture ) {
fprintf( stderr, ERROR: capture is NULL \n );
getchar();
}

// Create a window in which the captured images will be presented


// Show the image captured from the camera in the window and repeat

while ( 1 ) {
// Get one frame
IplImage* frame = cvQueryFrame( capture );
if ( !frame ) {
fprintf( stderr, ERROR: frame is null\n );
getchar();
break;
}

int percent = 50;

IplImage *frame2= cvCreateImage


( cvSize((int)((frame->width*percent)/100) , (int)((frame-
>height*percent)/100) ),frame->depth, frame->nChannels );
cvResize(frame, frame2);
IplImage* gray = cvCreateImage ( cvGetSize(frame2), frame2->depth, 1 );
cvCvtColor(frame2,gray,CV_RGB2GRAY);
detect_faces(gray);
cvShowImage( grayscale,gray);

// Do not release the frame!


//If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
//remove higher bits using AND operator

if ( (cvWaitKey(10) & 255) == 27 ) break;


}

// Release the capture device housekeeping


cvReleaseCapture( &capture );
cvDestroyWindow( grayscale );

Proses Smoothing
memakai fungsi cv_Smooth() dng tipe CV-BLUR unt memburamkan gambar. Smoothing filter
yg dipakai adalah Gaussian. Filter Gaussian mengkonvolusikan masing-masing titik pd input
array dng Gaussian kernel & lalu menjumlahkannya unt menghasilkan array output. unt
Gaussian blur kali ini, kernel yg dipakai adalah 15,15 ini menunjukkan lebar & tinggi dr filter
window.

Gambar menjadi lebih buram namun tetap dlm warna RGB. lalu dikerjakanlah face detection, &
hasilnya bagian wajah masih bisa terdeteksi.

Berikut adalah code-nya :

Source Code C++

CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );


if ( !capture ) {
fprintf( stderr, ERROR: capture is NULL \n );
getchar();
}

// Create a window in which the captured images will be presented


// Show the image captured from the camera in the window and repeat
while ( 1 ) {
// Get one frame
IplImage* frame = cvQueryFrame( capture );
IplImage* smooth = cvQueryFrame( capture );
if ( !frame ) {
fprintf( stderr, ERROR: frame is null\n );
getchar();
break;
}

cvSmooth( frame, smooth, CV_GAUSSIAN, 15, 15 );


detect_faces(smooth);
cvShowImage( smooth,smooth);

// Do not release the frame!


//If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
//remove higher bits using AND operator

if ( (cvWaitKey(10) & 255) == 27 ) break;


}

// Release the capture device housekeeping


cvReleaseCapture( &capture );
cvDestroyWindow( smooth );

Proses Adaptive Threshold


Gambar RGB mula-mula di-convert terlebih dahulu menjadi grayscale, lalu dng memakai fungsi
cvAdaptiveThreshold maka dikerjakan thresholding unt memisahkan antara bagian gelap &
terang. Adaptive threshold akan mengatur dirinya sendiri secara otomatis dlm memisahkan
daerah gelap & terang. Setelah itu dikerjakan face detection. Awalnya agak sulit bagi Haar-
cascade unt menemukan daerah wajah sebab perbedaan kontras antar gelap & terang telah
menjadi tipis, namun setelah beberapa saat akhinya dibisakan pula.

Berikut adalah code-nya :

Source Code C++

CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );


if ( !capture ) {
fprintf( stderr, ERROR: capture is NULL \n );
getchar();
}

// Create a window in which the captured images will be presented


// Show the image captured from the camera in the window and repeat

while ( 1 ) {
// Get one frame
IplImage* frame = cvQueryFrame( capture );
if ( !frame ) {
fprintf( stderr, ERROR: frame is null\n );
getchar();
break;
}

int percent = 50;


IplImage *frame2= cvCreateImage
( cvSize((int)((frame->width*percent)/100) , (int)((frame-
>height*percent)/100) ),frame->depth, frame->nChannels );

IplImage* gray = cvCreateImage ( cvGetSize(frame2), frame2->depth, 1 );


IplImage* adaptivethreshold = cvCreateImage ( cvGetSize(frame2), frame2-
>depth, 1 );
cvResize(frame,frame2);
cvCvtColor(frame2,gray,CV_RGB2GRAY);
cvAdaptiveThreshold(gray,adaptivethreshold,255,CV_ADAPTIVE_THRESH_MEAN_
C,CV_THRESH_BINARY,75,10);
detect_faces(adaptivethreshold);
cvShowImage(adaptive threshold,adaptivethreshold);

// Do not release the frame!


//If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
//remove higher bits using AND operator

if ( (cvWaitKey(10) & 255) == 27 ) break;


}

// Release the capture device housekeeping


cvReleaseCapture( &capture );
cvDestroyWindow( adaptive threshold );

Eigenface OpenCV Pengenalan Wajah


Pengenalan Citra Wajah

Pengenalan wajah adl salah satu teknologi biometrik yg telah banyak diaplikasikan dlm system
security selain pengenalan retina mata, pengenalan sidik jari & iris mata. dlm aplikasinya sendiri
pengenalan wajah memakai sebuah kamera unt menangkap wajah seseorang lalu dibandingkan
dng wajah yg sebelumnya telah disimpan di dlm database tertentu. Ada beberapa macam metoda
pengenalan wajah yaitu neural network, jaringan syaraf tiruan, neuro fuzzy adaptif dan eigenface.
Secara khusus dlm tulisan ini metoda yg akan dijelaskan adl metoda eigenface.

Pengenalan wajah manusia dlm gambaran visual bisa di implementasikan ke dlm banyak aplikasi
yg mencakup pengenalan wajah dengan memakai metode eigenface, yg mengisyaratkan
pemahaman, pengawasan oleh aplikasi tsb.
Konsep dari eigenface adl serangkaian eigenvektor yg dipakai unt mengenali wajah manusia dlm
suatu computer vision.
Eigenvektor berasal dari covariance matrix yg memiliki distribusi probabilitas yg tinggi &
dimensi ruang vector unt mengenali
kemungkinan sebuah wajah.

Eigenface

Untuk membaca karakteristik tubuh manusia semisal pola wajah diperlukan peralatan pembaca,
sebuah basisdata yg bisa menyimpan pola wajah & tentu saja algoritma pengenalan wajah yg
baik unt proses pengenalan pola wajah. Algoritma Eigenface bisa dipakai unt proses pengenalan
pola wajah tsb. Eigenface adl pendekatan eigenvalue & eigenvector. dng pendekatan tsb
dilakukan klasifikasi unt mengenali wajah yg di-training dng objek yg telah tersimpan di
database. Citra adl hasil keseluruhan dari suatu sistem perekaman data, yg secara teoritis
bisa dikelompokkan jadi 2 (dua) macam, yaitu citra kontinu & citra diskrit (citra digital).

Prinsip dasar dari pengenalan wajah adl dng mengutip informasi unik wajah tsb lalu di-encode &
dibandingkan dng hasil decode yg sebelumnya dilakukan. dlm metode eigenface, decoding
dilakukan dng Hitung eigenvector lalu direpresentasikan dlm sebuah matriks yg berukuran besar.

Algoritma eigenface secara keseluruhan cukup sederhana. Image Matriks (I) direpresentasikan
ke dlm sebuah himpunan matriks (1, 2, ..M). Cari nilai rata-rata () & pakai unt
mengekstraksi eigenvector (v) & eigenvalue () dari himpunan matriks. pakai nilai eigenvector
unt menbisakan nilai eigenface dari image. Apabila ada sebuah image baru atau test face (new),
proses yg sama juga dilakukan unt image (new), unt mengekstraksi eigenvector (v) &
eigenvalue (), lalu cari nilai eigenface dari image test face (new). Setelah itu barulah image baru
(new) memasuki tahap pengenalan dng memakai metode Euclidean distance.
Untuk lebih jelasnya, Alur prosesnya bisa dilihat pada gambar berikut :

Eigenface OpenCV Pengenalan Wajah

Algoritma selengkapnya adl :

1. Langkah Pertama Eigenface

Menyiapkan data dng membuat suatu himpunan S yg terdiri dari seluruh training image (1, 2,
..M).

S = {1, 2, ..M}

2. Langakah Kedua Eigenface

Ambil nilai tengah atau mean ()


3. Langkah Ketiga Eigenface

Cari selisih () antara Training image (i) dng nilai tengah (), apabila ditemukan nilainya
dibawah nol ganti nilainya dng nol

4. Langkah Keempat Eigenface

Hitung nilai matriks kovarian (C)

5. Langkah Kelima Eigenface

Hitung eigenvalue () & eigenvector (v)

CVi= iVi

6. Langkah Keenam Eigenface

Setelah eigenvector (v) diperoleh, maka eigenface () bisa dicari dng :

Tahapan Pengenalan :
1. Sebuah image wajah baru atau test face (new), akan dicoba unt dikenali, pertama terapkan
cara pada tahapan pertama perhitungan eigenface unt menbisakan nilai eigenface dari image tsb.

2. pakai metode Euclidean distance unt mencari jarak (distance) terpendek antara nilai eigenface
dari training image dlm database dng eigenface image test face.

OpenCV

OpenCV adl singkatan dari Open Source Computer Vision. OpenCV adl sebuah software library
bebas (open source) yg dipakai unt operasi computer vision & machine learning. OpenCV telah
dibangun unt menyediakan sebuah infrastruktur umum unt beberapa aplikasi computer vision &
unt mempercepat penggunaan dari mesin persepsi dlm produk komersial. OpenCV
mempermudah bisnis-bisnis unt memanfaatkan & memodifikasi kode. Library OpenCV
mempunyai lebih dari 2500 algoritma yg telah dioptimalkan dimana meliputi sebuah himpunan
menyeluruh dari keduanya yaitu klasik & seni beberapa algoritma computer vision & machine
learning. Algoritma-algoritma tsb bisa dipakai unt mendeteksi & mengenali wajah,
mengidentifikasi obyek, mengklasifikasi tindakan manusia dlm video, mengikuti jejak
perpindahan obyek, mengekstrak model-model 3D obyek, menghasilkan titik awan 3D dari
kamera stereo, & lain sebagainya.

OpenCV (Open Computer Vision) adl sebuah API (Application Programming Interface) Library
yg sudah sangat familiar pada Pengolahan Citra Computer Vision. Computer Vision itu sendiri
adl salah satu cabang dari Bidang Ilmu Pengolahan Citra (Image Processing) yg memungkinkan
komputer bisa melihat seperti manusia. dng vision tsb komputer bisa mengambil keputusan,
melakukan aksi, & mengenali terhadap suatu objek.

Beberapa pengimplementasian dari Computer Vision adl :

Face Recognition

Face Detection

Face/Object Tracking

Road Tracking
dll.

OpenCV adl library Open Source unt Computer Vision unt C/C++, OpenCV didesain unt
aplikasi real-time, memiliki fungsi-fungsi akuisisi yg baik unt image/video.

OpenCV sendiri terdiri dari 5 library, yaitu :

CV : untuk algoritma Image processing & Vision.

ML : unt machine learning library

Highgui : unt GUI, Image & Video I/O.

CXCORE : unt struktur data, support XML & fungsi-fungsi grafis.

CvAux

Contoh Program Eigenface di OpenCV

Berikut ini adl contoh penerapan Eigenface di OpenCV dng memakai bahasa pemrograman C++.

Source Code C++

#include "opencv2/core/core.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <fstream>
#include <sstream>

using namespace cv;


using namespace std;

static Mat norm_0_255(InputArray _src) {


Mat src = _src.getMat();
// Memmbuat & menormalkan kembali citra gambar
Mat dst;
switch(src.channels()) {
case 1:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
break;
case 3:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
}

static void read_csv(const string& filename, vector<Mat>& images, vector<int>&


labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "Input file tidak valid, silahkan cek nama file
yg dipakai.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
}

int main(int argc, const char *argv[]) {

if (argc < 2) {
cout << "usage: " << argv[0] << " <csv.ext> <output_folder> " << endl;
exit(1);
}

string output_folder = ".";

if (argc == 3) {
output_folder = string(argv[2]);
}

// Menbisakan lokasi CSV.


string fn_csv = string(argv[1]);

// Vektor unt mengambil gambar & label


vector<Mat> images;
vector<int> labels;

// Baca gambar dari input file yg diberikan


try {
read_csv(fn_csv, images, labels);
} catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg
<< endl;
exit(1);
}
// Keluar jika tidak gambar unt di proses
if(images.size() <= 1) {
string error_message = "This demo needs at least 2 images to work.
Please add more images to your data set!";
CV_Error(CV_StsError, error_message);
}

int height = images[0].rows;


Mat testSample = images[images.size() - 1];
int testLabel = labels[labels.size() - 1];
images.pop_back();
labels.pop_back();

Ptr<FaceRecognizer> model = createEigenFaceRecognizer();


model->train(images, labels);

// Memprediksi / test gambar


int predictedLabel = model->predict(testSample);

// unt menbisakan model prediksi :


int predictedLabel = -1;
double confidence = 0.0;
model->predict(testSample, predictedLabel, confidence);

string result_message = format("Predicted class = %d / Actual class =


%d.", predictedLabel, testLabel);
cout << result_message << endl;

// Berikut adl cara unt menbisakan nilai eigen dari model Eigenfaces :
Mat eigenvalues = model->getMat("eigenvalues");
Mat W = model->getMat("eigenvectors");

// Ambil rata2 sample dari data training


Mat mean = model->getMat("mean");

if(argc == 2) {
imshow("mean", norm_0_255(mean.reshape(1, images[0].rows)));
} else {
imwrite(format("%s/mean.png", output_folder.c_str()),
norm_0_255(mean.reshape(1, images[0].rows)));
}

// Menampilkan atau menyimpan Eigenfaces:


for (int i = 0; i < min(10, W.cols); i++) {
string msg = format("Eigenvalue #%d = %.5f", i,
eigenvalues.at<double>(i));
cout << msg << endl;

// Ambil eigenvector #i
Mat ev = W.col(i).clone();

// Membentuk kembali ke ukuran aslinya & menormalkan ke [0...255].


Mat grayscale = norm_0_255(ev.reshape(1, height));
// Tampilkan gambar & memproses Jet colormap unt pengindraan yg lebih
baik.
Mat cgrayscale;
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);

// Tampilkan atau simpan


if(argc == 2) {
imshow(format("eigenface_%d", i), cgrayscale);
} else {
imwrite(format("%s/eigenface_%d.png", output_folder.c_str(), i),
norm_0_255(cgrayscale));
}
}

// Menampilkan atau menyimpan rekonstruksi gambar di beberapa langkah yg


telah ditetapkan:
for(int num_components = min(W.cols, 10); num_components < min(W.cols,
300); num_components+=15) {

// iris vektor eigen dari model


Mat evs = Mat(W, Range::all(), Range(0, num_components));
Mat projection = subspaceProject(evs, mean, images[0].reshape(1,1));
Mat reconstruction = subspaceReconstruct(evs, mean, projection);

// menormalkan hasil
reconstruction = norm_0_255(reconstruction.reshape(1,
images[0].rows));

// Tampilkan & simpan


if(argc == 2) {
imshow(format("eigenface_reconstruction_%d", num_components),
reconstruction);
} else {
imwrite(format("%s/eigenface_reconstruction_%d.png",
output_folder.c_str(), num_components), reconstruction);
}
}

// Tampilkan jika tidak menunggu folder keluaran


if(argc == 2) {
waitKey(0);
}
return 0;
}

Penerapan Deteksi Wajah OpenCV


OpenCV

OpenCV ialah open source library computer vision, yg memudahkan pemrograman deteksi
wajah, face tracking, face recognition, kalman filtering & berbagai metode artificial intelligent.
OpenCV (Open Source Computer Vision Library) adalah sebuah pustaka perangkat lunak yg
ditujukan unt pengolahan citra dinamis scr real-time, yg dibuat oleh Intel, & sekarang didukung
oleh Willow Garage & Itseez. Program ini bebas & berada dlm naungan sumber terbuka dari
lisensi BSD. Pustaka ini merupakan pustaka lintas platform. Program ini didedikasikan
sebagaian besar unt pengolahan citra scr real-time. Jika pustaka ini menemukan pustaka
Integrated Performance Primitives dari intel dlm sistem komputer, maka program ini akan
menggunakan rutin ini unt mempercepat proses kerja program ini scr otomatis.

Penerapan Deteksi Wajah OpenCV

OpenCV pertama kali diluncurkan scr resmi pada tahun 1999 oleh Inter Research sbg lanjutan
dari bagian proyek bertajuk aplikasi intensif berbasis CPU, real-time ray tracing & tembok
penampil 3D. Para kontributor utama dlm proyek ini termasuk mereka yg berkecimpung dlm
bidang optimasi di Intel Russia, & juga Tim Pusataka Performansi Intel.

Pada awalnya, tujuan utama dari proyek OpenCV ini dideskripsikan sbg berikut,

1. Penelitian penginderaan citra lanjutan tdk hanya melalui kode program terbuka, tetapi
juga kode yg telah teroptimasi unt infrastruktur penginderaan citra.

2. Menyebarluarkan ilmu penginderaan citra dengan menyediakan infrastruktur bersama di


mana para pengembang dapat menggunakannya scr bersama-sama, sehingga kode akan
tampak lebih mudah dibaca & ditransfer.

3. Membuat aplikasi komersial berbasiskan penginderaan citra, di mana kode yg telah


teroptimasi tersedia scr bebas dengan lisensi yg tersedia scr bebas yg tdk mensyaratkan
program itu harus terbuka atau gratis.

Fitur Utama OpenCV

Mengoptimalkan image processing secara realtime

Antarmuka utama OpenCV adalah di C ++


Ada juga C, Python dan Java

Aplikasi OpenCV berjalan pada Windows, Android, Linux, Mac dan iOS

Dioptimalkan untuk prosesor Intel

Modul OpenCV

OpenCV memiliki struktur modular. Modul utama dari OpenCV tercantum di bawah ini. Saya
telah menyediakan beberapa link yang menunjuk ke beberapa pelajaran contoh di bawah setiap
modul

Core

Ini adalah modul dasar OpenCV. Ini mencakup struktur data dasar (misalnya-struktur data Mat)
dan fungsi pengolahan gambar dasar. Modul ini juga banyak digunakan oleh modul lain seperti
highgui, dll

HighGui

Modul ini menyediakan kemampuan pengguna yang sederhana antarmuka, beberapa gambar dan
video codec, gambar dan video yang menangkap kemampuan, memanipulasi jendela gambar,
penanganan track bar dan mouse acara dan lain-lain Jika Anda ingin kemampuan UI lebih maju,
Anda harus menggunakan kerangka UI seperti Qt, WinForms, dll

ImgProc

Modul ini mencakup algoritma pengolahan gambar dasar termasuk gambar filtering,
transformasi gambar, konversi ruang warna dan lain-lain

Video

Ini adalah modul analisis video yang mencakup algoritma pelacakan objek, algoritma
pengurangan latar belakang dan lain-lain

ObjDetect

Ini termasuk deteksi dan pengenalan obyek algoritma untuk objek standar.

OpenCV kin banyak digunakan untuk mengembangkan pengolahan citra dan visi komputer
canggih aplikasi. Ini telah menjadi alat bagi siswa, insinyur dan peneliti di setiap sudut dan sudut
dunia.

Konsep Pendeteksian Wajah


OpenCV face detector menggunakan metode Paul Viola & Michael Jones,

Metode mengkombinasikan :

Fitur rectangular sederhana yg disebut fitur Haar

Integral imag unt deteksi fitur yg cepat

Metode machine learning AdaBoost.

Sebuah pengklasifikasi cascade untkmengkombinasikan banyak fitur scr efisien.

Fitur yg digunakan Viola & Jones menggunakan bentuk gelombang Haar. Bentuk gelombang
Haar ialah sebuah gelombang kotak. Pada 2 dimensi, gelombang kotak ialah pasangan persegi
yg bersebelahan, 1 terang & 1 gelap. Haar ditentukan oleh pengurangan pixel rata-rata daerah
gelap dari pixel rata-rata daerah terang. Jika perbedeaan diatas threshold (diset selama learning),
fitur tersebut dikatakan ada.

Contoh Program OpenCV

OpenCV menggunakan sebuah tipe face detector yg dsebut Haar Cascade classifier. Gambar
menunjukkan face detector berhasil bekerja pada sebuah gambar. Jika ada sebuah image (bias
dari file /live video), face detector menguji tiap lokasi image & mengklasifikasinya sbg wajah
atau bukan wajah. Klasifikasi dimisalkan sebuah skala fix unt wajah, misal 50x50 pixel. Jika
wajah pada image lebih besar atau lebih kecil dari pixel tersebut, classifier terus menerus jalan
beberapa kali, unt mencari wajah pada gambar tersebut.
Penerapan Deteksi Wajah OpenCV

Classifier menggunakan data yg disimpan pada file XML unt memutuskan bagaimana
mengklasifikasi tiap lokasi image. OpenCV menggunakan 4 data XML unt deteksi wajah depan,
& 1 unt wajah profile. Termasuk juga 3 file XML bukan wajah: 1 unt deteksi full body, 1 unt
upper body, & 1 unt lower body. Anda harus memberitahukan classifier dimana menemukan file
data yg akan anda gunakan. Salah satunya bernama haarcascade_frontalface_default.xml.
Pada OpenCV, terletak pada :
Program_Files/OpenCV/data/haarcasades/haarcascade_frontalfa

Implementasi Deteksi Wajah:

1. Variable CvHaarClassifierCascade * pCascade menyimpan data dari file XML. Untuk


meload data XML ke pCascade, Anda dapat menggunakan fungsi cvLoad(). cvLoad ialah fungsi
umum unt meload data dari file yg membutuhkan hingga 3 parameter input. JIka anda membuat
kode pada C, set parameter sisanya menjadi 0, jika menggunakan C++ hilangkan parameter yg
tdk digunakan.

2. Sebelum mendeteksi wajah pada images, Anda membutuhkan objek CvMemStorage.


Detector akan mendaftar wajah yg terdeteki ke buffer. Yang harus anda kerjakan ialah
membuatnya

Source Code C++

pStorage=CvCreateMemStorage(0);
dan mereleasenya ketika telah selesai.

Source Code C++

cvReleaseMemStorage(&pStorage);

3. Anda akan sering meload data dari file, tentu ada kemungkinan salah path, sebaiknya
berikan pengecekan unt memastikan file diload dengan benar.

Source Code C++

if(!pInpImg || !pStorage || !pCascade)


{
printf (Inisialisasi gagal \n);
}
exit (-1);
}

4. Untuk menjalankan detector, panggil objek cvHaarDetect. Fungsi ini membutuhkan 7


parameter, 3 pertama ialah pointer image, XML data & memory buffer, sisanya diset pada
default C++.

Source Code C++

pFaceRectSeq =cvHaarDetectObjects
(pInpImg, pCascade, pStorage,
1.1, //tingkatkan skala pencarian dengan 10% tiap passing
3, //drop group yg kurang dari 3 deteksi
CV_HAAR_DO_CANNY_PRUNNING //skip region yg tdk berisi wajah
cvSize(0,)); //gunakan XML default unt skala pencarian terkecil.

5. Untuk membuat display Window gunakan cvNamedWindow seperti berikut:

Source Code C++

cvNamedWindow (Haar Window, CV_WINDOW_AUTOSIZE);

Untuk memasukkan image ke display, panggil fungsi cvShowImage() dengan nama yg telah
dibuat pada window & nama image yg ingin ditampilkan.

Source Code Open CV C++

Berikut ini kode lengkap untuk Penerapan Deteksi Wajah OpenCV :

Source Code C++


DetectFace.cpp:
// Capturing.cpp : Mendefinisikan entry point unt aplikasi konsol.

static CvMemStorage* storage = 0;


static CvHaarClassifierCascade* cascade = 0;

void detect_and_draw( IplImage* image );

const char* cascade_name =


"C:/Program
Files/OpenCV/data/haarcascades/haarcascade_frontalface_alt.xml";
/*"haarcascade_profileface.xml";*/

int main(int argc, char** argv)


{
CvCapture* capture = 0;
IplImage *frame, *frame_copy = 0;
argc = 1;
argv = 0;
int optlen = strlen("--cascade=");
const char* input_name;
input_name = 0;

if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )


{
cascade_name = argv[1] + optlen;
input_name = argc > 2 ? argv[2] : 0;
}
else
{
fprintf( stderr,
"Usage: facedetect --cascade=\"\" [filename|camera_index]\n" );
//return -1;
/*input_name = argc > 1 ? argv[1] : 0;*/
}

cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );


if( !cascade )
{
fprintf( stderr, "ERROR: Tidak dapat memuat classifier cascade\n" );
//return -1;
}

storage = cvCreateMemStorage(0);

if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') )


capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
else
capture = cvCaptureFromAVI( input_name );

cvNamedWindow( "Face Detection", 1 );

if( capture )
{
for(;;)
{
if( !cvGrabFrame( capture ))
break;
frame = cvRetrieveFrame( capture );
if( !frame )
break;
if( !frame_copy )
frame_copy = cvCreateImage( cvSize(frame->width,frame-
>height),
IPL_DEPTH_8U, 3 );
if( frame->origin == IPL_ORIGIN_TL )
cvCopy( frame, frame_copy, 0 );
else
cvFlip( frame, frame_copy, 0 );

detect_and_draw( frame_copy );

if( cvWaitKey( 10 ) >= 0 )


break;
}

cvReleaseImage( &frame_copy );
cvReleaseCapture( &capture );
}
else
{
const char* filename = "lena.jpg";
IplImage* image = cvLoadImage( filename, 1 );

if( image )
{
detect_and_draw( image );
cvWaitKey(0);
cvReleaseImage( &image );
}
else
{
/* menganggap itu adalah file teks yg berisi
daftar nama file gambar yg akan diproses - satu per baris */
FILE* f = fopen( filename, "rt" );
if( f )
{
char buf[1000+1];
while( fgets( buf, 1000, f ) )
{
int len = (int)strlen(buf);
while( len > 0 && isspace(buf[len-1]) )
len--;
buf[len] = '\0';
image = cvLoadImage( buf, 1 );
if( image )
{
detect_and_draw( image );
cvWaitKey(0);
cvReleaseImage( &image );
}
}
fclose(f);
}
}
}

cvDestroyWindow("Face Detection");

return 0;
}

void detect_and_draw( IplImage* img )


{
int scale = 1;
IplImage* temp = cvCreateImage( cvSize(img->width/scale,img-
>height/scale), 8, 3 );
CvPoint pt1, pt2;
int i;

//cvPyrDown( img, temp, CV_GAUSSIAN_5x5 );


cvClearMemStorage( storage );

if( cascade )
{

CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,


1.2, 2, CV_HAAR_DO_CANNY_PRUNING,
cvSize(40, 40) );
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
cvRectangle( img, pt1, pt2, CV_RGB(0,255,0), 3, 8, 0 );

IplImage * faceSave = cvCreateImage(cvGetSize(img),img->depth,img-


>nChannels);
IplImage * faceToSave = 0;
if( !faceToSave )
faceToSave = cvCreateImage( cvGetSize(pImg), 8, 3 );
cvCopy(pImg, faceToSave, 0);
faceToSave->origin = pImg->origin;
int pointX = 0;
int pointY = 0;
int lebar = 0;
if (r->width > r->height)
{
lebar = r->width;
pointX = r->x - ((r->width - r->height)/2);
pointY = r->y - ((r->width - r->height)/3);
} else if (r->width < r->height)
{
lebar = r->height;
pointX = r->x - ((r->height - r->width)/2);
pointY = r->y - ((r->height - r->width)/3);
}
cvSetImageROI(img, cvRect(pointX,pointY,lebar,lebar));
faceSave = img;
cvNamedWindow("Result", 1 );
cvShowImage("Result", img);
cvResetImageROI(img);*/

}
}

cvShowImage( "Face Detection", img );


cvReleaseImage( &temp );
}

#ifdef _EiC
main(1,"facedetect.c");
#endifx

Pengenalan Wajah Android Open CV

OpenCV (Open Source Computer Vision)


OpenCV (Open Source Computer Vision) adalah library untuk menangkap, memproses dan
menampilkan gambar, baik 2D maupun 3D. OpenCV digunakan untuk pengenalan wajah,
pengenalan gesture, deteksi gerakan dan lain-lain yang berkaitan dengan computer vision.

OpenCV telah dikembangkan cukup lama (dari 1999) dan tersedia untuk berbagai platform,
termasuk Android. Masalahnya, kebanyakan tulisan tentang instalasi openCV menggunakan
Eclipse+ADT dan belum menggunakan Android Studio. Tulisan ini menjadi pengantar memulai
openCV di Android dengan menggunakan Android Studio. Berikut langkah-langkahnya.'

1. Download library openCV dari http://opencv.org/downloads.html dan pilih platform Android


lalu ekstrak.

2. Impor library openCV. Jalankan Android Studio, pilih Import project (Eclipse ADT, gradle,
ADT), lalu pilih direktori \[opencv sdk]\sdk\java Pilih target direktori yang berbeda dengan
library openCV. Jika gradle scyn gagal, klik try agar AndroidStudio menginstall komponen
yang diperlukan. Pastikan anda terhubung dengan internet.

3. Sekarang kita akan buat project yang menggunakan openCV. Klik new project.

4. Pilih File > Import Module. Pilih direktori sesuai target direktori pada point no 2. Check
checbox impor dan ganti nama module menjadi :appOpenCV.

5. Pada project strucutre, klik kanan, pilih Open Module Setting. Klik tab dependency.
Pilih tanda plus hijau di kanan atas > module dependency. Pilih appOpenCV.

6. Pada build.gradle, set targetSdkVersion 19 (jika tidak akan menyebabkan error di Android 5
ke atas)

Sekarang kita akan mencoba openCV, contoh diambil dari \[opencv sdk]\samples\tutorial-1-
camerapreview

Buka layout (acvity_main.xml), ganti isinya sebagai berikut:

Source Code Java

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/tutorial1_activity_java_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" />
<org.opencv.android.NativeCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/tutorial1_activity_native_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" />

</FrameLayout>

Jangan lupa tambahkan camera pada AndroidManifest.xml

Source Code Java

<uses-permission android:name="android.permission.CAMERA"/>

<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.front"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus"
android:required="false"/>;

Terakhir source code untuk MainActivity

Source Code Java

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;

public class MainActivity extends ActionBarActivity implements


CameraBridgeViewBase.CvCameraViewListener2 {

private static final String TAG = "OCVSample::Activity";


private CameraBridgeViewBase mOpenCvCameraView;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this)


{
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};

public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}

/ ** Dipanggil ketika aktivitas tersebut pertama kali diciptakan. * /

@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

setContentView(R.layout.activity_main);

if (mIsJavaCamera)
mOpenCvCameraView = (CameraBridgeViewBase)
findViewById(R.id.tutorial1_activity_java_surface_view);
else
mOpenCvCameraView = (CameraBridgeViewBase)
findViewById(R.id.tutorial1_activity_native_surface_view);

mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);

mOpenCvCameraView.setCvCameraViewListener(this);
}

@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this,
mLoaderCallback);
}

public void onDestroy() {


super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is
present.
Log.i(TAG, "called onCreateOptionsMenu");
mItemSwitchCamera = menu.add("Toggle Native/Java camera");
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
String toastMesage = new String();
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);

if (item == mItemSwitchCamera) {
mOpenCvCameraView.setVisibility(SurfaceView.GONE);
mIsJavaCamera = !mIsJavaCamera;

if (mIsJavaCamera) {
mOpenCvCameraView = (CameraBridgeViewBase)
findViewById(R.id.tutorial1_activity_java_surface_view);
toastMesage = "Java Camera";
} else {
mOpenCvCameraView = (CameraBridgeViewBase)
findViewById(R.id.tutorial1_activity_native_surface_view);
toastMesage = "Native Camera";
}

mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mOpenCvCameraView.enableView();
Toast toast = Toast.makeText(this, toastMesage,
Toast.LENGTH_LONG);
toast.show();
}

return true;
}
@Override
public void onCameraViewStarted(int width, int height) {

@Override
public void onCameraViewStopped() {

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame
inputFrame) {
return inputFrame.rgba();
}
}

Jalankan dengan menggunakan device (jangan emulator). Jika sukses App ini akan menampilkan
isi kamera. Saat saya mencoba dengan Nexus 5, kamera berbasis java berhasil tapi nativenya
gagal. Posting ini akan diupdate kalau saya sudah menemukan masalahnya.

Anda mungkin juga menyukai