"Orang berilmu binasa kecuali orang yang mengamalkan ilmunya. Orang yang mengamalkan ilmunya binasa kecuali orang yang ikhlas". (Ibnu Qudamah)

Selasa, 28 Juli 2015

Face Detection (Deteksi Wajah)

https://www.sony.co.in/product/resources/en_IN/images/Technology/DI/Camera/face_detection.jpg

Face detection adalah salah satu teknik image processing yang fungsinya adalah mendeteksi wajah manusia. Haar classifier adalah suatu metode yang mampu mengenali wajah. Metode ini sudah built-in pada OpenCV. Teknik face detection pertama kali dibuat oleh  by Paul Viola dan Michael Jones yang secara umum disebut dengan Viola-Jones detector . Selanjutnya dikembangkan oleh Rainer Lienhart dan Jochen Maydt untuk penggunaan fitur-fitur diagonal. OpenCV yang mengarah pada detektor ini sebagai “Haar classifier” karena dia menggunakan fitur-fitur Haar, atau lebih tepatnya, Haar-like wavelets  yang terdiri dari penambahan dan pengurangan daerah kotak image sebelum pen-tresholan dihasilkan. OpenCV dilengkapi dengan sebuah kumpulan dari file-file pengenalan objek sebelum dilatihkan, tetapi hanya mengizinkanmu untuk melatih dan menyimpan model-model objek baru untuk pendeteksi. Kita perjelas sekali lagi bahwa pengenalan (createsamples(), haartraining()) dan detecting (cvHaarDetectObjects()) kode bekerja dengan baik pada beberapa objek (tidak hanya wajah) namun yang secara konsisten dan kebanyakan bertekstur dan kaku (keras). Detector (pendeteksi wajah) ini berada pada .../opencv/data/ haarcascades, dimana model yang bekerja dengan baik adalah haarcascade_ frontalface_alt2.xml. Namun untuk mendeteksi wajah tampak samping lebih susah untuk mendeteksi secara akurat dengan menggunakan teknik ini. Diperlukan algoritma tambahan agar dapat mendeteksi wajah tampak samping dengan akurat. Face detection adalah langkah awal untuk bisa menerapkan aplikasi image prosesing untuk mengenali wajah seseorang. Berikut ini adalah contoh program facedetection dan video hasil pengujian programnya. 

PROGRAM


#include "cv.h"
#include "highgui.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>


static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;

void detect_and_draw( IplImage* image );
const char* cascade_name ="haarcascade_frontalface_alt";

int main( int argc, char** argv )
{
    CvCapture* capture = 0;
    IplImage *frame= 0;
    IplImage *frame_copy= 0;

    //1. Load file database haarcascade
    cascade_name = "haarcascade_frontalface_alt.xml";
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

    //2. Jika tidak bisa nge-load, maka program dibatalkan
    if( !cascade )
    {
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
        fprintf( stderr, "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
        return -1;
    }
    //membuat memory penyimpanan
    storage = cvCreateMemStorage(0);
    //mengambil gambar dari kamera video0
    capture = cvCaptureFromCAM(0);
    //membuat nama window
    cvNamedWindow( "result", 1 );

    //jika tidak bisa mengambil gambar dari kamera, program dibatalkan
    if ( !capture ) {
             fprintf( stderr, "ERROR: capture is NULL \n" );
         getchar();
         return -1;
    }
    //jika bisa mengambil gambar
    if( capture )
    {
        while(1)
        {
            /* cvGrabFrame (ambil frame dg kasar)
            grab a frame, return 1 on success, 0 on fail.
            this function is thought to be fast*/
            /* get the frame grabbed with cvGrabFrame(..)
            This function may apply some frame processing like
            frame decompression, flipping etc.
            /* Just a combination of cvGrabFrame and cvRetrieveFrame*/

            //jika frame tidak dipegang, break
            if( !cvGrabFrame( capture ))
                break;
            //jika dipegang ambil frame tadi dengan cvRetrieveFrame
            frame = cvRetrieveFrame( capture );
            if( !frame )
                break;
            if( !frame_copy )
                frame_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );
            if( frame->origin == IPL_ORIGIN_TL )
                cvCopy( frame, frame_copy, 0 );
            else
                cvFlip( frame, frame_copy, 0 );
         
            IplImage* frame = cvQueryFrame( capture );

            detect_and_draw( frame_copy);
            if( cvWaitKey( 10 ) >= 0 )
                break;
        }

        cvReleaseImage( &frame_copy);
        cvReleaseCapture( &capture );
    }
    cvDestroyWindow("result");
    return 0;
}

void detect_and_draw( IplImage* img )
{
    static CvScalar colors[] =
    {
        {{0,0,255}},          //biru
        {{0,128,255}},        //biru muda
        {{0,255,255}},        //sian
        {{0,255,0}},          //hijau
        {{255,128,0}},        //orange
        {{255,255,0}},        //kuning
        {{255,0,0}},        //merah
        {{255,0,255}}         //magenta
    };

    double scale = 1.3;
    IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
    IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8, 1 );
    int i;

    cvCvtColor( img, gray, CV_BGR2GRAY );
    cvResize( gray, small_img, CV_INTER_LINEAR );
    cvEqualizeHist( small_img, small_img );
    cvClearMemStorage( storage );

    if( cascade )
    {
        //menghitung waktu pengambilan & untuk mempercepat
        double t = (double)cvGetTickCount();
        //CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.1, 3, 0/*CV_HAAR_DO_CANNY_PRUNING dan */,cvSize(30, 30) );  // default ada error
        //nilai 1.1 adalah nilai minimal
        //CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.3, 2, 0|1/*CV_HAAR_DO_CANNY_PRUNING dan */,cvSize(33, 33) ); //masih sedikit   error
        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.1, 3, 0|1/*CV_HAAR_DO_CANNY_PRUNING dan */,cvSize(50, 50) );  //Oke
        //CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 1.1, 3, 0|1/*CV_HAAR_DO_CANNY_PRUNING dan */,cvSize(33, 33) );  //Oke Akhir
        //CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage, 2, 3, 0|1/*CV_HAAR_DO_CANNY_PRUNING dan */,cvSize(50, 50) );  //tidak terdeteksi
        t = (double)cvGetTickCount() - t;
        //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

        unsigned char a=0;

        for( i = 0; i < (faces ? faces->total : 0); i++ )
        {
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
            CvPoint center;
            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);
            cvCircle( img, center, radius, cvScalar( 0,128,255), 3, 8, 0 );
            a=1;

        }
        if (a==1)
        {
            //Menampilkan text pada layar
            CvFont font;
            cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 1, 8);
            cvPutText(img,"Ada orang",cvPoint(100,50),&font,CV_RGB(0,255,0));
            printf( "detected\n");
        }
        else
        {
            //Menampilkan text pada layar
            CvFont font;
            cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 1, 8);
            cvPutText(img,"?",cvPoint(100,50),&font,CV_RGB(0,255,0));
            printf( "not detected\n");
        }
    }

    cvShowImage( "result", img );
    cvReleaseImage( &gray );
    cvReleaseImage( &small_img );
}

VIDEO



Untuk lebih bisa memahami tentang facedetection bisa anda baca pada manual OpenCV. Dapat anda download di link berikut ini.

Tidak ada komentar: