opencvcameraface-detectionraspberry-pi2haar-classifier

What is the best algorithm for face detection using opencv and raspberry camera module


i'm working on face and eye detection (no recognition needed) using opencv , and i've found some algorithms that i can use :

Viola–Jones object detection framework : This algorithm is implemented in OpenCV as cvHaarDetectObjects(). https://en.wikipedia.org/wiki/Viola%E2%80%93Jones_object_detection_framework Local binary patterns (LBP) is a type of feature used for classification in computer vision https://en.wikipedia.org/wiki/Local_binary_patterns 3.....

i'm just a newbie and i want to know what is the best algorithm (in term of speed and performance and precision ) for face and especially eye detection using opencv :) thanks a lot

update : for my situation i need to capture faces of people walking on a street from a distance of ~ 2-5 meters , i'm using raspberry pi 2 with opencv 3 gold and raspicam-0.1.3 libarrry for the pi camera module


Solution

  • In my experience the best one is a Haarcascade. The file I use is haarcascade_frontalface_alt2.xml. I did many tests with all haar files and found that this one was the best.

    std::vector<Rect> faces;
    Mat img_gray;
    Mat img; //here you have to load the image
    
    CascadeClassifier face_cascade;
    face_cascade.load("haarcascade_frontalface_alt2.xml");
    
    cvtColor( img, img_gray, CV_BGR2GRAY );
    cv::equalizeHist( img_gray, img_gray );
    
    int rect_size = 20;
    float scale_factor = 1.05;
    int min_neighbours = 1;
    face_cascade.detectMultiScale( img_gray, faces, scale_factor, min_neighbours, 0|CV_HAAR_SCALE_IMAGE, Size(rect_size, rect_size) );
    

    The haar cascade returns several bounding box (they are the candidates). Some of these candidates will contain a face and other not. If most of the pixels of the bounding box are green, then probably there is no a face. You need to filter skin color pixels. You can do this with HSV. First you need to set a range, in our case this range only allow skin color pixels.

    cv::Scalar  hsv_min = cv::Scalar(0, 30, 60);
    cv::Scalar  hsv_max = cv::Scalar(20, 150, 255);
    cvtColor(image, hsv_image, CV_BGR2HSV);
    inRange (hsv_image, hsv_min, hsv_max, result_mask);
    

    result_mask is a skin mask. All pixels in white are skin and all in black are not skin. Then you only need to count the number of white pixels in the mask:

    int number_skin_pixels = cv::countNonZero(result_mask);
    

    If there are many skin pixels, then youo can assume that there is a face. If not, then there is a false positive