UnaNancyOwen
1/12/2017 - 6:37 PM

Face Recognition using Face Module

Face Recognition using Face Module

#include <iostream>
#include <vector>
#include <filesystem>
#include <string>
#include <regex>

#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>

int main( int argc, char* argv[] )
{
    /* Training */
    // Load Cascade Classifier for Face Detect
    cv::CascadeClassifier cascade( "../haarcascade_frontalface_default.xml" );
    if( cascade.empty() ){
        return -1;
    }

    // Create DataSet
    std::cout << "Create DataSet" << std::endl;
    std::vector<cv::Mat> faces;
    std::vector<int> labels;
    std::tr2::sys::path dataset( "../trainingdata" );
    std::for_each( std::tr2::sys::directory_iterator( dataset ), std::tr2::sys::directory_iterator(),
        [&]( const std::tr2::sys::path& path ){
            if( std::tr2::sys::is_regular_file( path ) ){
                // Read Image
                cv::Mat image = cv::imread( path.string(), cv::IMREAD_GRAYSCALE );
                if( image.empty() ){
                    return;
                }

                // Detect Face (First Face)
                std::vector<cv::Rect> rects;
                cascade.detectMultiScale( image, rects );
                cv::Mat face = image( rects[0] );

                // Resize Face
                cv::resize( face, face, cv::Size( 200, 200 ) );

                // Store Face
                faces.push_back( face.clone() );

                // Retrieve Label Number from File Name ( e.g. image01.png )
                const std::string filename = path.filename().string();
                std::smatch match;
                std::regex_search( filename, match, std::regex( "\\d+" ) );
                int label = std::stoi( match.str() );

                // Store Label Number
                labels.push_back( label );
            }
        }
    );

    // Create Recognizer
    //cv::Ptr<cv::face::FaceRecognizer> model = cv::face::createFisherFaceRecognizer();
    //cv::Ptr<cv::face::FaceRecognizer> model = cv::face::createEigenFaceRecognizer();
    cv::Ptr<cv::face::FaceRecognizer> model = cv::face::createLBPHFaceRecognizer();

    // Training Recognizer
    std::cout << "Training Recognizer" << std::endl;
    model->train( faces, labels );

    // Save Recognizer
    std::cout << "Save Recognizer" << std::endl;
    model->save( "../model.xml" );

    return 0;
}
#include <iostream>
#include <vector>

#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>

int main( int argc, char* argv[] )
{
    // Read Image
    cv::Mat image = cv::imread( "image.jpg", cv::IMREAD_GRAYSCALE );
    if( image.empty() ){
        return -1;
    }
    
    // Create Recognizer
    //cv::Ptr<cv::face::FaceRecognizer> model = cv::face::createFisherFaceRecognizer();
    //cv::Ptr<cv::face::FaceRecognizer> model = cv::face::createEigenFaceRecognizer();
    cv::Ptr<cv::face::FaceRecognizer> model = cv::face::createLBPHFaceRecognizer();
  
    // Load Recognizer
    model->load( "../model.xml" );
    if( model.empty() ){
        return -1;
    }
  
    // Load Cascade Classifier for Face Detect
    cv::CascadeClassifier cascade( "../haarcascade_frontalface_default.xml" );
    if( cascade.empty() ){
        return -1;
    }
  
    // Detect Face
    std::vector<cv::Rect> rects;
    cascade.detectMultiScale( image, rects );
    
    for( const cv::Rect rect : rects ){
        // Retrieve Face Image
        cv::Mat face = image( rect );
    
        // FisherFaceRecognizer and EigenFaceRecognizer require resize image to same size as training image.
        // LBPHFaceRecognizer doesn't requere resize image.
        //cv::resize( face, face, cv::Size( 200, 200 ) );
  
        // Face Recognition with Retrieve Most Match Result
        int label = -1;
        double confidence = 0.0;
        model->predict( face, label, confidence );
        std::cout << label << " (" << confidence << ")" << std::endl;
        
        /*
        // Face Recognition with Retrieve All Match Results
        cv::Ptr<cv::face::StandardCollector> collector = cv::face::StandardCollector::create( model->getThreshold() );
        model->predict( face, collector );
        std::vector<std::pair<int, double>> results = collector->getResults( true );
        for( const std::pair<int, double> result : results ){
            int label = result.first;
            double confidence = result.second;
            std::cout << label << " (" << confidence << ")" << std::endl;
        }
        */
    }
    
    return 0;
}