用opencv自带的Haar分类器进行人脸检测(二)

#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>  
  
#ifdef _EiC  
#define WIN32  
#endif  
  
static CvMemStorage* storage = 0;  
static CvHaarClassifierCascade* cascade = 0;  
  
void detect_and_draw( IplImage* image );  
  
const char* cascade_name =  
"haarcascade_frontalface_alt.xml";  
/* "haarcascade_profileface.xml";*/  
  
int main( int argc, char** argv )  
{  
    CvCapture* capture = 0;  
    IplImage *frame, *frame_copy = 0;  
    int optlen = strlen("--cascade=");  
    const char* input_name;  
  
    if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )  
    {  
        cascade_name = argv[1] + optlen;  
        input_name = argc > 2 ? argv[2] : 0;  
    }  
    else  
    {  
        cascade_name = "D:\\Program Files\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt_tree.xml";  
        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" );  
        fprintf( stderr,  
        "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\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( "result", 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, frame->nChannels );  
            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 = input_name ? input_name : (char*)"10.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("result");  
  
    return 0;  
}  
  
void detect_and_draw( IplImage* img )  
{  
    static CvScalar colors[] =   
    {  
        {{0,0,255}},  
        {{0,128,255}},  
        {{0,255,255}},  
        {{0,255,0}},  
        {{255,128,0}},  
        {{255,255,0}},  
        {{255,0,0}},  
        {{255,0,255}}  
    };  
  
    double scale = 1.0;  //越大越快,过大或过小都会误检
    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 )  
    {  
        double t = (double)cvGetTickCount();  
        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,  
        1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,  
        cvSize(20, 30) );  //越大圆圈越大越快,过大引起漏检
        t = (double)cvGetTickCount() - t;  
        printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );  
        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, colors[i%8], 3, 8, 0 );  
        }  
    }  
  
    cvShowImage( "result", img );  
    cvReleaseImage( &gray );  
    cvReleaseImage( &small_img );  
} 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值