Bab 13
Computer Vision
Tujuan Instruksional Umum :
1. Mahasiswa mampu menjelaskan peranan dan konsep pemrograman Computer Vision
Tujuan Instruksional Khusus :
1. Mahasiswa mampu menjelaskan fungsi dari Computer Vision
2. Mahasiswa dapat menyebutkan beberapa penerapan dari Computer Vision 3. Menjelaskan fungsi dari program OpenCV
4. Mahasiswa dapat menjelaskan penelitian di bidang Computer Vision
5. Mahasiswa dapat menginstal program OpenCV dan membuat program loading image.
13.1 Pendahuluan
Pada masa ini, perhatian difokuskan pada kemampuan komputer dalam mengerjakan sesuatu yang dapat dilakukan oleh manusia. Dalam hal ini, komputer tersebut dapat meniru kemampuan kecerdasan dan perilaku manusia. Salah satu cabang dari Kecerdasan buatan ialah Computer Vision. Menurut Forsyth dan Ponece, Computer Vision adalah:
Extracting descriptions of the world from pictures or sequences of pictures
Computer vision merupakan teknologi paling penting di masa yang akan datang dalam pengembangan robot yang interaktif. Computer Vision merupakan bidang pengetahuan yang berfokus pada bidang sistem kecerdasan buatan dan berhubungan dengan akuisisi dan pemrosesan images. Contoh penerapan computer vision pada dunia riset dan industri ialah :
Pengontrolan proses industri Pendeteksi nomor plat kendaraan 3D model building (photogrammetry)
Robot Vision, Humanoid Robot dan Robot Soccer.
Surveillance (monitor penyusup, analisa trafik jalan tol dan lainnya) Modeling obyek atau lingkungan
Interaksi manusia dan robot (Human Robot Interaction)
Gambar 13.1 Hubungan Computer vision dengan bidang lainnya
Pada penerapannya, computer vision dan machine visionmenerapkan digital image processing untuk menerapkan algoritma komputer untuk pemrosesan image pada image digital. Menurut Forsyth dan Ponce, Computer Vision adalah mengekstrak deskripsi dunia dari gambar atau urutan gambar. Computer vision secara umum merupakan area yang menyertakan metode metode untuk mengambil, pemroses menganalisa dan memahami image untuk menghasilkan informasi numeric atau simbolik. Image processing merupakan proses mengubah image 2D menggunakan metode Edge detection, fourier transform atau enhancement untuk memperoleh output image 2D yang diinginkan (misalnya smoothing gambar).
Gambar 13.2 Proses Image processing
Gambar 13.3 Proses inspeksi Machine Vision pada Industri
13.2
Program OpenCV
OpenCV ialah program open source berbasiskan C++ yang saat ini banyak digunakan sebagai program computer vision, salah satu penerapannya ialah pada robotika. Dengan OpenCV, Anda dapat membuat interaksi antara manusia dan robot (Human Robot Interaction. Misalnya, wajah dari manusia dideteksioleh camera/webcam, lalu diproses oleh komputer, untuk kemudian diproses oleh robot untuk melakukan aksi tertentu, misalnya mengikuti/mengenal wajah orang tersebut. Kesemuanya itu membutuhkan OpenCV sebagai program utama antara webcam dan pengolahnya yaitu komputer. Silahkan kunjungi situs opencv.org untuk download atau mengetahui berita terbaru tentang software ini. Program OpenCV 2.4.11 merupakan edisi terbaru yang harus Anda gunakan pada buku ini.
Pemrograman Dasar OpenCV
Anda membutuhkan editor dan kompiler Visual C++ 2013/ Visual Studio 2013 Express Edition untuk mengedit dan kompilasi program OpenCV. Anda terlebih dahulu harus mengkonfigurasi Visual C++ .Net tersebut dimana file library dan sourcenya harus disertakan. Beberapa file library juga harus ditambahkan pada input linker di Visual C++.
1. Jalankan program dan install pada suatu direktori, misalnya f:/OpenCV246 atau f:/OpenCV246 jika menggunakan versi OpenCV 2.4.6.
Gambar 13.4 Proses instalasi pada satu direktori
2.
Tambahkan path ke Path Variable:f:\OpenCV246\opencv\build\x86\vc10\bin
f:\OpenCV246\opencv\build\common\tbb\ia32\vc10
3. Lalu, buat proyek baru untuk OpenCV menggunakan Visual C++ 2013, dengan memilih create a new Win32 console Application. Klik kanan Project dan pilh properties
Gambar 13.5 Memilih properties
Pada bagian kiri, pilih C/C++ lalu edit Additional Include Directories dengan menambahkan : f:\OpenCV246\opencv\build\include\opencv
f:\OpenCV246\opencv\build\include
Gambar 13.6 Menambahkan Additional library Directories
5. Buka Linker dan pilih input, tambahkan Additional Dependencies berikut: opencv_core246d.lib
opencv_imgproc246d.lib opencv_highgui246d.lib opencv_ml246d.lib opencv_video246d.lib opencv_features2d246d.lib opencv_calib3d246d.lib opencv_objdetect246d.lib opencv_contrib246d.lib opencv_legacy246d.lib opencv_flann246d.lib
Jika sudah selesai, sebagai contoh buatlah program Win32 console application untuk menampilkan sebuah gambar di Windows, berikut contohnya:
Displayimage.cpp:
// Menampilkan Image menggunakan cvLoadImage //Dibuat oleh Widodo Budiharto
#include "stdafx.h" #include <cv.h> #include <cxcore.h> #include <highgui.h>
int _tmain(int argc, _TCHAR* argv[]) { // meload image
IplImage *img = cvLoadImage("f:\handsome.jpg"); cvNamedWindow("OpenCV",1);
cvShowImage("OpenCV",img);
//tunggu sembarang input dari user untuk exit cvWaitKey(0);
cvDestroyWindow("OpenCV "); cvReleaseImage(&img);
return 0; }
Pada program di atas, dibutuhkan library seperti cv.h, sxcore.h dan highgui.h agar fungsi dikenal oleh compiler. Hasil dari program di atas ialah :
Gambar 13.8 Hasil program menampilkan image
header matrik (berisi informasi ukuran matrik, metode yang digunakan untuk menyimpan) dan sebuah pointer ke matrik berisi nilai pixel, berikut contohnya:
cv::Mat A, C; // membuat bagian header
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // alokasi matrik cv::Mat B(A); // menggunakan kopi constructor
C = A; // operator assignment
Pada program di atas, kita meload image menggunakan fungsi
imread()
. Berikut contoh
program untuk loading image berbasis C++:
DisplayImage2.cpp:
#include "stdafx.h" // Program demo C++ untuk display image. #include <stdlib.h>
#include <cv.hpp> #include <cxcore.hpp> #include <highgui.h>
int _tmain(int argc, _TCHAR* argv[]) {
cv::Mat img = cv::imread("f:\handsome.jpg"); cv::imshow("OpenCV",img);
//tunggu sembarang input dari user untuk exit cv::waitKey();
return EXIT_SUCCESS; }
13.3 Digital Image Processing
Sebuah image ialah sebuah array, atau matrik dari piksel persegi yang disusun dalam format kolom dan baris. Pada image greyscale (8bit), tiap elemen gambar memiliki intesitas antara 0-255, sedangkan image true color terdiri dari 24 bit( 8x8x8 =16 juta warna) seperti gambar di bawah :
(a) (b)
Image standar dikenal sebagai image RGB (terdiri dari komponen Merah, Hijau dan biru) dan memiliki sistem warna 24 bit yang masing masing terdiri dari 8 bit. Representasi warna bertipe integer bervariasi dari 0-255, sedangkan untuk tipe float berkisar antara 0-1. Nilai warna tersebut disimpan pada matrik 3 dimensi yang dilambangkan dalam Intensitas I (X,Y, channel). Nilai warna RGB dapat dinormalisasi menggunakan persamaan :
� � = �
Sedangkan proses grascale menggunakan persamaan
���� = �+�+�
�
(13.2)
Kadang citra yang kita miliki perlu kita olah untuk tujuan tertentu yang dikenal dengan istilah Pengolahan Citra, misalnya proses penjumlahan nilai RGB pada images. Awal mula pemrosesan image digital dimulai pada sekitar tahun 1960an pada Jet Propulsion Laboratory, Massachusetts Institute of Technology, Bell Laboratories, University of Maryland, untuk aplikasi satelit, medical imaging dan character recognition. Pemrosesan image digital memungkinkan penggunaan algoritma komplek untuk pemrosesan image sehingga menghasilkan performa sistem yang robust dan berbiaya murah. Klasifikasi merupakan metode yang sangat penting dalam image processing. Pemrosesan image digital umumnya digunakan pada proses :
Classification Feature extraction Pattern recognition Multi-scale signal analysis
Beberapa teknik yang digunakan pada pemrosesan image digital antara lain :
Pixelization Linear filtering Erosi dan dilasi
Principal components analysis Independent component analysis Hidden Markov models
Robotika saat ini membutuhkan metode computer vision untuk membuat service robot [6]. Sebagai percobaan, untuk mengenal RGB, buatlah sebuah proyek baru dan beri nama RGB, lalu buat program di bawah ini :
RGB.cpp:
void sum_rgb( IplImage* src, IplImage* dst ) { // Allocate individual image planes.
IplImage* r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1 ); IplImage* g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1 ); IplImage* b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1 );
// Temporary storage.
IplImage* s = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1 );
// Split image
cvSplit( src, r, g, b, NULL );
// Add equally weighted rgb values. cvAddWeighted( r, 1./3., g, 1./3., 0.0, s ); cvAddWeighted( s, 2./3., b, 1./3., 0.0, s );
// Truncate nilai diatas 100.
cvThreshold( s, dst, 150, 100, CV_THRESH_TRUNC );
cvReleaseImage( &r ); cvReleaseImage( &g ); cvReleaseImage( &b ); cvReleaseImage( &s ); }
int main(int argc, char** argv) { // Buat jendela
cvNamedWindow( argv[1], 1 );
// Load the image from the given file name. IplImage* src = cvLoadImage( argv[1] );
IplImage* dst = cvCreateImage( cvGetSize(src), src->depth, 1); sum_rgb( src, dst);
// Tampilkan jendela cvShowImage( argv[1], dst );
// Idle until the user hits the "Esc" key.
while( 1 ) { if( (cvWaitKey( 10 )&0x7f) == 27 ) break; } // Bersihkan jendela dan memori
}
Hasil program di atas berupa gambar yang nilai RGB-nya telah berubah seperti gambar di bawah :
Gambar 13.10 Hasil penjumlahan RGB
Pada pengolahan citra dasar, biasanya edge detection, threshold dan countour sangat dibutuhkan, berikut contohnya :
Countour.cpp:
//Program membuat countour dan variasi threshold #include <cv.h>
#include <highgui.h>
IplImage* image = 0; int thresh = 100; void on_trackbar(int) {
IplImage* gray = cvCreateImage( cvGetSize(image), 8, 1 ); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0;
cvCvtColor( image, gray, CV_BGR2GRAY );
cvThreshold( gray, gray, thresh, 255, CV_THRESH_BINARY ); cvFindContours( gray, storage, &contours );
cvZero( gray ); if( contours )
cvDrawContours( gray, contours, cvScalarAll(255), cvScalarAll(255), 100 );
cvShowImage( "Contours", gray );cvReleaseImage( &gray ); cvReleaseMemStorage( &storage );
}
int main( int argc, char** argv ) { IplImage* image;
return -1;
cvNamedWindow( "Contours", 1 );
cvCreateTrackbar( "Threshold", "Contours", &thresh, 255, on_trackbar );
on_trackbar(0); cvWaitKey(); return 0; }
Gambar 13.11 Program countour pada Lena.jpg
3.1 Penggunaan Kamera
Kamera sangat penting pada dunia machine vision[1]. Secara umum, struktur umum dari penggunaan machine vision pada dunia industri atau riset dapat digambarkan pada gambar 13.12 berikut :
Fungsi untuk menampilkan image menggunakan kamera pada OpenCV ialah [3]:
pCapture =cvCaptureFromCAM (CV_CAP_ANY);
atau
cvCapture* cvCreateCameraCapture(int index);// index merupakan urutan
// kamera yang ada.
Jika ingin mengatur lebar dan tinggi frame, gunakan kode berikut :
capture = cvCaptureFromCAM(CV_CAP_ANY); // Capture dari webcam cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640); cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
Sebagai contoh, jika Anda ingin mendeteksi webcam dan mengambil streaming video dari
webcam tersebut, gunakan demo kode berikut ini:
Kamera.cpp:
//Menampilkan image menggunakan Webcam
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
int main( int argc, char** argv ) {
cvNamedWindow( "Camera", CV_WINDOW_AUTOSIZE );
CvCapture* capture;
if (argc==1) {
capture = cvCreateCameraCapture( 0 ); //kamera pertama
} else {
capture = cvCreateFileCapture( argv[1] );
}
IplImage* frame;
while(1) {
frame = cvQueryFrame( capture );
if( !frame ) break;
cvShowImage( "Camera", frame );
char c = cvWaitKey(10);
if( c == 27 ) break;
}
cvReleaseCapture( &capture );
cvDestroyWindow( "Camera" );
}
Gambar 13.13 Hasil penggunaan webcam dengan deteksi wajah
Jika menggunakan versi terbaru, berikut kodenya:
using namespace cv;
int main(int, char)
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("edges",1);
for(;;)
Mat frame;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
if(waitKey(30) >= 0) break;
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
13.2 Konsep Image Filtering
Sebuah mask ialah sebuah matrik kecil dimana nilainya disebut weights. Linear filtering adalah filtering dimana nilai dari tiap piksel output merupakan sebuah kombinasi linear dari nilai piksel pada input. Linear filtering dilakukan melalui operasi convolution. Sebuah filter ialah sebuah fungsi yang mengambil nilai input signal dan menghasilkan output yang sesuai dengan persamaan yang ada pada fungsi tersebut.
A. Blurring Image
Blurring sebuah image ialah langkah untuk mengurangi ukuran image tanpa mengubah tampilan gambar terlalu banyak, menggunakan matrik kernel. Blurring dapat dilakukan dengan mengganti tiap pixel image dengan beberapa nilai rata-rata di sekitarnya. Kernel Gaussian umum digunakan pada proses ini demgam nilai:
Mat image, image_blurred; int slider=5;
float sigma=0.3 *((slider -1) *0.5-1)+0.8; void on_trackbar(int, void*) {
int k_size=max(1,slider);
k_size=k_size%2==0?k_size+1:k_size;
setTrackbarPos("Kernel size", "Bluerred image",k_size); sigma=0.3*((k_size -1) *0.5-1) +0.8;
GaussianBlur(image,image_blurred, Size(k_size,k_size),sigma); imshow ("Blurred image", image_blurred);
}
int main() {
image=imread ("lena.jpg"); namedWindow ("Original image"); namedWindow ("Blurred image"); imshow ("Original image", image); sigma=0.3*((slider-1) *0.5-1)+0.8;
GaussianBlur (image,image_blurred,Size(slider,slider),sigma); imshow ("Blurred image", image_blurred);
createTrackbar("Kernel size", "Blurred image", &slider, 21, on_trackbar); while (char(waitKey(1) !='q')) {}
return 0; }
Gambar 13.14 Hasil blurring sebuah image
b. Dilasi dan Erosi
Erosi dan dilasi merupakan 2 operasi morfologis pada image.
#include "opencv2/highgui/highgui.hpp"
int choice_slider=0, size_slider=5;//0=erosi, 1=dilasi void proses(){
Mat st_elem=getStructuringElement(MORPH_RECT, Size(size_slider, size_slider)); if (choice_slider==0) {
void on_choice_slider(int, void*) { proses();
}
void on_size_slider(int, void*) { int size=max(1,size_slider) ; size=size%2==0 ? size+1:size;
setTrackbarPos("Kernel size", "Processed image", size); proses();
Mat st_elem=getStructuringElement(MORPH_RECT, Size(size_slider, size_slider)); erode(image, image_processed, st_elem);
imshow("Processed image", image_processed);
createTrackbar("Erode/Dilate", "Processed image", &choice_slider, 1, on_choice_slider); createTrackbar("Kernel Size", "Processed image", &size_slider, 21, on_size_slider); while (char(waitKey(1) !='q')) {}
return 0; }
Gambar 13.15 Hasil erosi dilasi
3.3 Canny Edge Detector
Edge atau tepi ialah titik-titik di image dimana gradient dari image tersebut cukup tinggi. Gradient image dihitung menggunakan gradient pada arah X dan Y dan dikombinasikan dengan teorema phythagoras. Arah X dan Y dihitung dengan konvolusi image dengan kernel berikut
-3 0 3
-10 0 10
-3 0 3 ( untuk arah X)
dan
-3 -10 -3
0 0 0
Dengan nilai gradient G=sqrt(Gx2 + Gy2) dan sudut gradient Θ=arctan(Gy/Gx)
Berikut contoh kode canny edge detector:
Canny.cpp:
//Canny Edge Detector
#include "opencv2/imgproc/imgproc.hpp"
int const max_lowThreshold = 100; int ratio = 3;
int kernel_size = 3;
char* window_name = "Canny Edge Detector"; void CannyThreshold(int, void*){
/// Reduce noise with a kernel 3x3 blur( src_gray, detected_edges, Size(3,3) );
/// Canny detector
Canny( detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size ); /// Using Canny's output as a mask, we display our result
dst = Scalar::all(0);
src.copyTo( dst, detected_edges); imshow( window_name, dst ); dst.create( src.size(), src.type() );
/// Convert the image to grayscale cvtColor( src, src_gray, CV_BGR2GRAY ); /// Create a window
/// Create a Trackbar for user to enter threshold
createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold ); /// Show the image
CannyThreshold(0, 0);
/// Wait until user exit program by pressing a key waitKey(0);
return 0; }
Gambar 13.16 Hasil Canny Edge Detector
13.4 Implementasi: Color-Based Object Detector
Untuk membuat color-based object detector, dapat menggunakan fungsi inRange di
openCv sebagai berikut :
inRange(frame, Scalar (low_b, low_g,low_r), Sclar (high_b, high_g,high_r), frame thresholded);
colorbased.cpp:
//Color-Based Object Detector
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream>
using namespace cv; using namespace std;
Mat frame, frame_thresholded;
int rgb_slider=0,low_slider=30, high_slider=100;
int low_r=30,low_g=30,low_b=30, high_r=100, high_g=100, high_b=100;
void on_rgb_trackbar(int, void*) { switch (rgb_slider) { case 0:
setTrackbarPos("Low threshold", "Segmentation", low_r); setTrackbarPos("High threshold", "Segmentation", high_r); break;
case 1:
setTrackbarPos("Low threshold", "Segmentation", low_g); setTrackbarPos("High threshold", "Segmentation", high_g); break;
case 2:
setTrackbarPos ("Low threshold", "Segmentation", low_b); setTrackbarPos("High threshold", "Segmentation", high_b); break;
low_r=min (high_slider -1, low_slider);
setTrackbarPos("Low threshold", "Segmentation", low_r); break;
case 1:
low_g=min(high_slider-1, low_slider);
setTrackbarPos("Low threshold", "Segmentation", low_g); break;
case 2:
setTrackbarPos("Low threshold", "Segmentation", low_b);
setTrackbarPos("High threshold", "Segmentation", high_r); break;
case 1:
high_g=max(low_slider+1, high_slider);
setTrackbarPos("High threshold", "Segmentation", high_g); break;
case 2:
high_b=max(low_slider+1, high_slider);
setTrackbarPos("High threshold", "Segmentation", high_b); break; //cek apakah dapat diakses
createTrackbar("0. R\n1. G\n2. B","Segmentation", &rgb_slider, 2, on_rgb_trackbar); createTrackbar ("Low threshold","Segmentation", &low_slider, 255, on_low_thresh_trackbar); createTrackbar("High threshold","Segmentation", &high_slider, 255,on_high_thresh_trackbar);
while(char(waitKey(1)) !='q' && cap.isOpened()) {
cap>>frame; if (frame.empty()) {
cout<<"Video over"<<endl; break;
}
inRange(frame,Scalar(low_b,low_g,low_r),Scalar(high_b,high_g,high_r),frame_thresholded); imshow("Video", frame);
imshow("Segmentation",frame_thresholded); }
return 0; }
Gambar 13.17 Hasil streaming object detecter yang masih terlihat adanya noise
13.5 Morphological Opening dan Closing
Operasi Opening diperoleh dengan proses erosi pada image diikuti dengan dilasi dengan
hasil penghapusan daerah putih yang kecil pada image. Penerapannya misalnya pada smoothing
Closing diperoleh dengan dilasi image diikuti dengan proses erosi yang berakibat pada efek
sebaliknya. Kedua operasi ini berfungsi utuk menghapus oise dari image. Fungsi
morphologyEX() dapat digunakan utuk melakukan operasi morphological seperti opening dan
closing pada image. Berikut contohnya :
inRange(frame,Scalar(low_b,low_g,low_r),Scalar(high_b,high_g,high_r),frame_thresholded);
//Operasi Opening dan Closing
Mat str_el=getStructuringElement(MORPH_RECT, Size(3,3));
morphologyEx(frame_thresholded, frame_thresholded,MORPH_OPEN, str_el);
morphologyEx(frame_thresholded, frame_thresholded,MORPH_CLOSE, str_el);
imshow("Video", frame);
imshow("Segmentation",frame_thresholded);
Gambar 13.18 Hasil streaming object detector yang sudah bersih dari noise karena operasi opening dan closing
Untuk menyimpan file, gunakan fungsi imwrite() berikut :
cv::Mat red_image;
cv::inRange(image, cv::Scalar(40, 0, 180), cv::Scalar(135, 110, 255), red_image);
//cv::imwrite("out1.png", red_image);
Haar Cascade Classifier
OpenCV menggunakan sebuah tipe face detector yang disebut 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 dan mengklasifikasinya
sebagai “wajah” atau “bukan wajah”. Klasifikasi dimisalkan sebuah skala fix untuk wajah, misal
50x50 pixel. Jika wajah pada image lebih besar atau lebih kecil dari pixel tersebut, classifier
terus menerus jalan beberapa kali, untuk mencari wajah pada gambar tersebut.
Classifier menggunakan data yang disimpan pada file XML untuk memutuskan
bagaimana mengklasifikasi tiap lokasi image. OpenCV menggunakan 4 data XML untuk deteksi
wajah depan, dan 1 untuk wajah profile. Termasuk juga 3 file XML bukan wajah: 1 untuk
deteksi full body, 1 untuk upper body, dan 1 untuk lower body.
Anda harus memberitahukan classifier dimana menemukan file data yang akan anda gunakan.
Salah satunya bernama haarcascade_frontalface_default.xml. Pada OpenCV, terletak pada :
Program_Files/OpenCV/data/haarcasades/haarcascade_frontalface_default.xml.
Fitur yang digunakan Viola dan Jones menggunakan bentuk gelombang Haar. Bentuk
gelombang Haar ialah sebuah gelombang kotak. Pada 2 dimensi, gelombang kotak ialah
pasangan persegi yang bersebelahan, 1 terang dan 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.Kata cascade pada classfier berarti total
Gambar 13.19 Feature yang diusulkan Viola dan Jones
Implementasi Deteksi Wajah pada Haar Classifier sebagai berikut:
1.
Variable CvHaarClassifierCascade * pCascade menyimpan data dari file XML. Untuk meload
data XML ke pCascade, Anda dapat menggunakan fungsi cvLoad(). cvLoad ialah fungsi umum
untuk meload data dari file yang membutuhkan hingga 3 parameter input. JIka anda
membuat kode pada C, set parameter sisanya menjadi 0, jika menggunakan C++ hilangkan
parameter yang tidak digunakan.
2.
Sebelum mendeteksi wajah pada images, Anda membutuhkan objek CvMemStorage.
Detector akan mendaftar wajah yang terdeteki ke buffer. Yang harus anda kerjakan ialah
membuatnya
pStorage=CvCreateMemStorage(0);
dan mereleasenya ketika telah selesai. cvReleaseMemStorage(&pStorage);
3.
Anda akan sering meload data dari file, tentu ada kemungkinan salah path, sebaiknya
berikan pengecekan untuk memastikan file diload dengan benar.
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 dan memory buffer, sisanya diset pada default C++.
pFaceRectSeq =cvHaarDetectObjects (pInpImg, pCascade, pStorage,1.1,
//tingkatkan skala pencarian dengan 10% tiap passing 3, //drop group yang kurang dari 3 deteksi
CV_HAAR_DO_CANNY_PRUNNING //skip region yang tidak berisi //wajah
cvSize(0,)); //gunakan XML default untuk skala pencarian //terkecil.
5.
Untuk membuat display Window gunakan cvNamedWindow seperti berikut:
cvNamedWindow (“Haar Window”, CV_WINDOW_AUTOSIZE);
6.
Untuk memasukkan image ke display, panggil fungsi cvShowImage() dengan nama yang telah dibuat
pada window dan nama image yang ingin ditampilkan.
Jika ingin mendeteksi wajah termasuk mata menggunakan webcam, gunakan contoh program di bawah ini :
FaceandEyeDetection.cpp:
//Face and eyes detection using Haar Cascade Classifier // Copyright Dr. Widodo Budiharto 2015
#include <iostream> using namespace std; using namespace cv;
void detectAndDisplay( Mat frame ); /** Variabel global */
String face_cascade_name = "lbpcascade_frontalface.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml"; CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Face detection";
int main( int argc, const char** argv ) {
CvCapture* capture; Mat frame;
//-- 1. Load the cascade
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face\n"); return -1; }; if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading eye\n"); return -1; };
//-- 2. Read the video stream capture = cvCaptureFromCAM(0); if( capture )
{
while( true ) {
frame = cvQueryFrame( capture );
//-- 3. Apply the classifier to the frame if( !frame.empty() )
{ detectAndDisplay( frame ); } else
{ printf(" --(!) No captured frame -- Break!"); break; }
if( (char)c == 'c' ) { break; }
} } return 0; }
void detectAndDisplay( Mat frame ) {
std::vector<Rect> faces; Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY ); equalizeHist( frame_gray, frame_gray );
//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0, Size(80, 80) );
for( int i = 0; i < faces.size(); i++ ) {
Mat faceROI = frame_gray( faces[i] ); std::vector<Rect> eyes;
//-- deteksi mata
eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) ); if( eyes.size() == 2)
{
//gambar wajah
Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 0 ), 2, 8, 0 );
for( int j = 0; j < eyes.size(); j++ ) { //-- Draw the eyes
circle( frame, center, radius, Scalar( 255, 0, 255 ), 3, 8, 0 ); }
}
}
//-- Show the result
imshow( window_name, frame ); }
Hasilnya akan tampil seperti gambar di bawah ini:
Gambar 13.21 Wajah dan mata gadis yang terdeteksi
Menampilkan hasil wajah yang terdeteksi pada kamera webcam dengan garis circle dan kotak sering dibutuhkan, karena dapat digunakan untuk mengukur jarak antara kamera dan obyek sebagai pengganti sensor jarak ultrasonik, kode berikut dapat digunakan :
cvCircle( img, center, radius, color, 3, 8, 0 );
cvRectangle( img,cvPoint( r->x, r->y ),cvPoint( r->x + r->width, r->y + r->height ),CV_RGB( 0, 255, 0 ), 1, 8, 0 );
// Face Detection using Rectangle // By Dr. Widodo Budiharto 2014 // HP: 08569887384
void detectAndDraw( Mat& img, CascadeClassifier& cascade, CascadeClassifier& nestedCascade, double scale);
String cascadeName ="haarcascade_frontalface_alt.xml";
int main( int argc, const char** argv ){ CvCapture* capture = 0;
Mat frame, frameCopy, image; const String scaleOpt = "--scale="; size_t scaleOptLen = scaleOpt.length(); const String cascadeOpt = "--cascade="; size_t cascadeOptLen = cascadeOpt.length(); String inputName;
CascadeClassifier cascade, nestedCascade; double scale = 1;
if( !cascade.load( cascadeName ) ) {
cerr << "ERROR: Could not load classifier cascade" << endl; cerr << "Usage: facedetect [--cascade=\"<cascade_path>\"]\n" " [--nested-cascade[=\"nested_cascade_path\"]]\n"
capture = cvCaptureFromCAM(0);
cvNamedWindow( "Face Detection with Rectangle", 1 ); if( capture )
{
cvDestroyWindow("result"); return 0;
}
void detectAndDraw( Mat& img,
CascadeClassifier& cascade, CascadeClassifier& nestedCascade,double scale){
Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
cvtColor( img, gray, CV_BGR2GRAY );
resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR ); equalizeHist( smallImg, smallImg );
t = (double)cvGetTickCount();
cascade.detectMultiScale( smallImg, faces, 1.1, 2, 0
for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ ) {
Mat smallImgROI;
vector<Rect> nestedObjects; Point center;
Scalar color = colors[i%8]; int radius;
center.x = cvRound((r->x + r->width*0.5)*scale); center.y = cvRound((r->y + r->height*0.5)*scale); radius = cvRound((r->width + r->height)*0.25*scale); circle( img, center, radius, color, 3, 8, 0 );
cv::rectangle( img,cvPoint( r->x, r->y ),cvPoint( r->x + r->width, r->y + r->height ), CV_RGB( 255, 0, 0 ), 1, 8, 0 );
}
cv::imshow( "Face Detection with Rectangle", img ); }
Gambar 13.22 Wajah yang terdeteksi menggunakan rectangle
Deteksi fitur wajah seperti mata, hidung dan mulut sangat penting untuk robot vision. Robot harus mampu
mengenal ekspresi(marha, sedih, senang dll) dan fitur lainnya yang ada pada wajah di depan robot. Contoh berikut
menampilkan deteksi wajah, mata dan hidung menggunakan library :
haarcascade_frontalface_alt2.xml
haarcascade_mcs_eyepair_big.xml
haarcascad_mcs_nose.xml
haarcascade_smile.xml
Aplikasi dari sistem ini sangat luas, mulai dari deteksi kantuk pada pengemudi, facial emotion recognition serta kendali robot vision.
Untuk 3D Head pose estimation, riset terkini pada pengenalan wajah berfokus pada Active Appearance Model (AAM) dan Active Shape Model (ASM) yang sangat berguna untuk memelajari variasi shape[5]. Active appearance model merupakan model parameterisasi dari kombinasi tekstur dan bentuk untuk digunakan pada algoritma pencarian yang efisien.
Gambar 13.23 Active Appearance Model (AAM)
Kode AAM yang dapat dikembangkan sebagai berikut : int main()
{
VideoCapture cap(0); if (!cap.isOpened()) return -1;
AAM aam= loadPreviouslyTrainedAAM(); HeadModel headModel=load3DHeadModel();
Mapping mapping=mapAAMLandmarsToHeadModel(); Pose2D pose=detectFacePosition();
while(1) {
Pose2D new2DPose =performAAMSearch(pose, aam);
Pose3D new3DPose=applyPOSIT(new2DPose, headModel, mapping); if (waitKey(30) >=0) break;
} return 0;
}
Latihan :
1. Buatlah program untuk menyimpan hasil streaming kamera yang sudah dismoothing ke dalam file .avi.
2. Buatlah program online training faces menggunakan PCA dan LDA serta LBP yang mampu menyimpan informasi wajah pelanggan dan orderan minuman pelanggan tersebut yang tersimpan pada file .xml sebagai berikut 3. Jelaskan cara kerja Haar Cascade Classifier.
4. Buat program yang dapat mengukur jarak obyek menggunakan kamera stereo
Referensi:
1. Forsyth, D., Ponce, J. (2012). Computer Vision: A Modern Approach. 2nd ed. Prentice Hall. ISBN: 978-0-27-376414-4
2. Stuart Russel and Peter Norvig, (2011), Artificial Intelligence, A Modern Approach, Pearson Publisher. 3. Opencv.org
4. Widodo Budiharto, Bayu Kanigoro, Viska Noviantri, Ball Distance Estimation and Tracking System of Humanoid Soccer Robot, Lecturer Notes on Information Technology, Springer Publisher, 2014. 5. Widodo Budiharto, Modern Robotics with OpenCV(2014), SPG Publisher.