OpenCV for face detection

OpenCV for face detection (Reprinted)

Original link: https://www.cnblogs.com/mengdd/archive/2012/08/01/2619043.html

This paper introduces the most basic method of face detection with OpenCV.

I Principle of face detection algorithm

Viola Jones face detection method

References: Paul Viola, Michael J. Jones Robust Real-Time Face Detection[J]. International Journal of Computer Vision,2004,57(2):137-154.

The main contributions of the algorithm are three:

1. An integral image is proposed, which can quickly calculate Haar like features.

2. Adaboost learning algorithm is used for feature selection and classifier training, and weak classifiers are combined into strong classifiers.

3. Cascade classifiers to improve efficiency.

II OpenCV detection principle

OpenCV has a function to detect faces (this function can also detect some other objects), and even contains some pre trained object recognition files.

So using these ready-made things can quickly make a human face detection program.

The main steps are:

1. Load the classifier.

Use the cvLoad function to read in the file in xml format. The file is in the "data/haarcascades /" path under the OpenCV installation directory.

http://blog.csdn.net/yang_xian521/article/details/6973667 Haarcascade is recommended_ frontalface_ atl. XML and haarcascade_frontalface_atl2.xml

2. Read in the image to be detected. Read in pictures or videos.

3. Face detection.

Main functions used:

CvSeq* cvHaarDetectObjects( 
const CvArr* image, 
CvHaarClassifierCascade* cascade, 
CvMemStorage* storage, 
double scale_factor CV_DEFAULT(1.1), 
int min_neighbors CV_DEFAULT(3), 
int flags CV_DEFAULT(0), 
CvSize min_size CV_DEFAULT(cvSize(0,0)), 
CvSize max_size CV_DEFAULT(cvSize(0,0)) 
);

 

The function description is extracted from learning OpenCV: CvArr* image is a grayscale image. If ROI is set, only this area will be processed. CvHaarClassifierCascade* cascade is the cascade of classifier features read in earlier. CvMemStorage* storage is the working cache of this algorithm. scale_factor: the algorithm scans with windows of different sizes_ Factor is the size relationship between every two windows of different sizes. min_neighbors control false detection, because the face will be repeatedly detected by windows of different positions and sizes. At least so many times, we think the face is really detected. flags has four available values, which can be used in combination with bits or operations. The default is CV_HAAR_DO_CANNY_PRUNING tells the classifier to skip the smooth region. min_size indicates the smallest area to find the face. max_size should obviously be the largest area to find the face...

4. Indication of test results.

You can draw a circle or a box.

III code

#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 ) 
{ 
    cascade_name = "haarcascade_frontalface_alt2.xml"; 
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); 
  
    if( !cascade ) 
    { 
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); 
        return -1; 
    } 
    storage = cvCreateMemStorage(0); 
    cvNamedWindow( "result", 1 ); 
     
    const char* filename = "Lena.jpg"; 
    IplImage* image = cvLoadImage( filename, 1 );

    if( image ) 
    { 
        detect_and_draw( image ); 
        cvWaitKey(0); 
        cvReleaseImage( &image );   
    }

    cvDestroyWindow("result"); 
  
    return 0; 
}


void detect_and_draw(IplImage* img ) 
{ 
    double scale=1.2; 
    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}} 
    };//Just some pretty colors to draw with

    //Image Preparation 
    // 
    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); 
    cvCvtColor(img,gray, CV_BGR2GRAY); 
    cvResize(gray, small_img, CV_INTER_LINEAR);

    cvEqualizeHist(small_img,small_img); //histogram equalization 

    //Detect objects if any 
    // 
    cvClearMemStorage(storage); 
    double t = (double)cvGetTickCount(); 
    CvSeq* objects = cvHaarDetectObjects(small_img, 
                                                                        cascade, 
                                                                        storage, 
                                                                        1.1, 
                                                                        2, 
                                                                        0/*CV_HAAR_DO_CANNY_PRUNING*/, 
                                                                        cvSize(30,30));

    t = (double)cvGetTickCount() - t; 
    printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

    //Loop through found objects and draw boxes around them 
    for(int i=0;i<(objects? objects->total:0);++i) 
    { 
        CvRect* r=(CvRect*)cvGetSeqElem(objects,i); 
        cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]); 
    } 
    for( int i = 0; i < (objects? objects->total : 0); i++ ) 
    { 
        CvRect* r = (CvRect*)cvGetSeqElem( objects, 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); 
}

 

IV Results and some explanations

The operation results are as follows:

Points to be explained:

1. Images and The xml file should be placed in the bin directory of the program (. The directory where sln is located).

2. Learning OpenCV is represented by a rectangle, but the code in the book is not quite right because the scaling factor, namely void detect, is ignored_ and_ double scale=1.2 in draw (iplimage * IMG);

The function of this scaling factor is to get an image, first scale it (scale=1.2, that is, it becomes a small image), and then detect the face on the scaled small image, which will be faster.

Posted by php_gromnie on Thu, 19 May 2022 19:50:53 +0300