Minggu, 29 November 2015


Haar Cascade Classifier

OpenCV ialah open source library computer vision, yang memudahkan pemrograman  deteksi wajah, face tracking, face recognition, kalman filtering dn berbagai metode artificial intelligent.
OpenCV menggunakan sebuah tipe face detector yang 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 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.

Konsep Pendeteksian Wajah
OpenCV face detector menggunakan metode Paul Viola dan Michael Jones, silahkan baca detail paper mereka di CD Program. Metode mengkombinasikan :
·           Fitur  rectangular sederhana yang disebut fitur Haar
·           Integral imag untuk deteksi fitur yang cepat
·           Metode machine learning AdaBoost.
·           Sebuah pengklasifikasi cascade untkmengkombinasikan banyak fitur secara efisien.
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.

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 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);
Untuk memasukkan image ke display, panggil fungsi cvShowImage() dengan nama yang telah dibuat pada window dan nama image yang ingin ditampilkan.

Berikut ini kode lengkapnya :

DetectFace.cpp:
// Capturing.cpp : Defines the entry point for the console application.

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: Could not load 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
        {
            /* assume it is a text file containing the
               list of the image filenames to be processed - one per line */
            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");
#endif


 

 Gambar wajah hasil deteksi


Sumber  :  http://bajay-x.blogspot.co.id/2010/04/pengenalan-wajah.html




Tidak ada komentar:

Posting Komentar