SeetaFace2-master在Windows10+VS环境中实现人脸检测、关键点定位、特征提取与比对的Simple Demos

  • 首先,需要实现SeetaFace2-master在Windows10 VS20XX搭建项目。
    可以参考这篇博客:https://blog.csdn.net/sinat_33896833/article/details/100183581
  • 环境搭建好之后,会发现里面有example.cpp,运行能够基本实现FaceDetection功能。但还是不够,因此我又模拟了几个demo,仅供参考。

在search中添加.cpp文件

引用头文件

#pragma warning(disable: 4819)

#include 
#include 
#include 

#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using std::string;
using std::vector;
using namespace std;

图片对象FaceDetection、FaceLandmarker

int test_image(seeta::FaceDetector &FD, seeta::FaceLandmarker &FL)
{
    std::string image_path = "C:\\xxx\\xxx\\xxx.jpg";
    std::cout << "Loading image: " << image_path << std::endl;
    auto frame = cv::imread(image_path);
    seeta::cv::ImageData simage = frame;

    if (simage.empty()) {
        std::cerr << "Can not open image: " << image_path << std::endl;
        return EXIT_FAILURE;
    }


    auto faces = FD.detect(simage);

    for (int i = 0; i < faces.size; ++i)
    {
        auto &face = faces.data[i];
        auto points = FL.mark(simage, face.pos);

        cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3);
        for (auto &point : points)
        {
            cv::circle(frame, cv::Point(point.x, point.y), 3, CV_RGB(128, 255, 128), -1);
        }
    }

    auto output_path = image_path + ".pts81.png";
    cv::imwrite(output_path, frame);
    std::cerr << "Saving result into: " << output_path << std::endl;

    cv::namedWindow("Image_Result", 0);
    //cv::resizeWindow("Image_Result",500,500);
    cv::imshow("Image_Result", frame);
    cv::waitKey(0);

    return 0;
    //return EXIT_SUCCESS;
}

视频对象FaceDetection、FaceLandmarker

int test_video(seeta::FaceDetector &FD, seeta::FaceLandmarker &FL)
{
    cv::VideoCapture capture;
    cv::Mat video;
    video = capture.open("C:\\xxx\\xxx\\xxx.mp4");
    cv::Mat frame;
    if (!capture.isOpened())
    {
        printf("Can not open the video.\n");
        return -1;
    }
    while (capture.isOpened())
    {
        capture.grab();
        capture.retrieve(frame);

        if (frame.empty()) break;

        seeta::cv::ImageData simage = frame;

        auto faces = FD.detect(simage);

        for (int i = 0; i < faces.size; ++i)
        {
            auto &face = faces.data[i];
            auto points = FL.mark(simage, face.pos);

            cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3);
            for (auto &point : points)
            {
                cv::circle(frame, cv::Point(point.x, point.y), 2, CV_RGB(128, 255, 128), -1);
            }
        }
        cv::namedWindow("Video_Result", 0);
        cv::imshow("Video_Result", frame);
        auto key = cv::waitKey(20);
        if (key == 27)
        {
            break;
        }
    }
    return EXIT_SUCCESS;
}

图片对象FaceRecognizer

int identify_pic(){
    seeta::ModelSetting::Device device = seeta::ModelSetting::CPU;
    int id = 0;
    seeta::ModelSetting FD_model("./model/fd_2_00.dat", device, id);
    seeta::ModelSetting PD_model("./model/pd_2_00_pts5.dat", device, id);
    seeta::ModelSetting FR_model("./model/fr_2_10.dat", device, id);
    seeta::ModelSetting FL_model("./model/pd_2_00_pts81.dat", device, id);
    seeta::FaceEngine engine(FD_model, PD_model, FR_model, 2, 16);

    seeta::FaceDetector FD(FD_model);
    seeta::FaceLandmarker FL(FL_model);

    // recognization threshold
    float threshold = 0.5f;

    //set face detector's min face size
    engine.FD.set(seeta::FaceDetector::PROPERTY_MIN_FACE_SIZE, 50);

    //this is the picture identity database directory
    std::ifstream fin("C:\\xxx\\xxx\\xxx\\list.txt");
        
    if (!fin.is_open())
    {
        cout << "can not open listfile." << endl;
    }

    std::vector GalleryImageFilename;
    string str;
    while (std::getline(fin, str))
    {
        GalleryImageFilename.push_back(str);
    }
    fin.close();

    std::vector GalleryIndex(GalleryImageFilename.size());
    for (size_t i = 0; i < GalleryImageFilename.size(); ++i)
    {
        //register face into facedatabase
        std::string &filename = GalleryImageFilename[i];
        
        int64_t &index = GalleryIndex[i];
        std::cerr << "Registering... " << filename << std::endl;
        seeta::cv::ImageData image = cv::imread(filename);
        auto id = engine.Register(image);
        /*
        //删除文件夹中无效图片
        if (id == -1)
        {
            const char* p = filename.data();
            remove(p);
        }*/
        index = id;
        std::cerr << "Registered id = " << id << std::endl;
    }
    std::map GalleryIndexMap;
    for (size_t i = 0; i < GalleryIndex.size(); ++i)
    {
        // save index and name pair
        if (GalleryIndex[i] < 0) continue;
        GalleryIndexMap.insert(std::make_pair(GalleryIndex[i], GalleryImageFilename[i]));
    }
    std::string image_path = "C:\\xxx\\xxx\\xxx.jpg";
    std::cout << "Loading image: " << image_path << std::endl;
    auto frame = cv::imread(image_path);
    int width1 = frame.cols;
    int height1 = frame.rows;
    cv::resize(frame, frame, cv::Size(width1 / 2, height1 / 2));
    
        seeta::cv::ImageData image = frame;

        // Detect all faces
        std::vector faces = engine.DetectFaces(image);

        for (SeetaFaceInfo &face : faces)
        {
            // Query top 1
            int64_t index = -1;
            float similarity = 0;

            auto points = engine.DetectPoints(image, face);
            
            auto faces = FD.detect(image);

            for (int i = 0; i < faces.size; ++i)
            {
                auto &face = faces.data[i];
                auto points = FL.mark(image, face.pos);

                cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3);
                for (auto &point : points)
                {
                    cv::circle(frame, cv::Point(point.x, point.y), 3, CV_RGB(128, 255, 128), -1);
                }
            }

            auto queried = engine.QueryTop(image, points.data(), 1, &index, &similarity);

            /*cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3);
            for (int i = 0; i < 5; ++i)
            {
                auto &point = points[i];
                cv::circle(frame, cv::Point(int(point.x), int(point.y)), 2, CV_RGB(128, 255, 128), -1);
            }*/

            // no face queried from database
            if (queried < 1) continue;

            std::cerr << similarity << std::endl;
            std::cout << "top_person:" << GalleryIndexMap[index] << std::endl;
            // similarity greater than threshold, means recognized
            if (similarity > threshold)
            {
                std::cout << "right_person:" << GalleryIndexMap[index] << std::endl;
                cv::putText(frame, GalleryIndexMap[index], cv::Point(face.pos.x, face.pos.y - 5), 3, 1, CV_RGB(255, 128, 128));
            }
            else {
                std::cerr << "Nothing similar." << std::endl;
            }
        }
            cv::namedWindow("Compare_Result", 0);
            cv::imshow("Compare_Result", frame);
            cv::waitKey(0);
    return 0;
}

camera对象FaceRecognizer

int identify_camera() {
    seeta::ModelSetting::Device device = seeta::ModelSetting::CPU;
    int id = 0;
    seeta::ModelSetting FD_model("./model/fd_2_00.dat", device, id);
    seeta::ModelSetting PD_model("./model/pd_2_00_pts5.dat", device, id);
    seeta::ModelSetting FR_model("./model/fr_2_10.dat", device, id);
    seeta::ModelSetting FL_model("./model/pd_2_00_pts81.dat", device, id);
    seeta::FaceEngine engine(FD_model, PD_model, FR_model, 2, 16);

    seeta::FaceDetector FD(FD_model);
    seeta::FaceLandmarker FL(FL_model);

    // recognization threshold
    float threshold = 0.5f;

    //set face detector's min face size
    engine.FD.set(seeta::FaceDetector::PROPERTY_MIN_FACE_SIZE, 50);

    //this is the picture identity database directory
    std::ifstream fin("C:\\xxx\\xxx\\list.txt");
    if (!fin.is_open())
    {
        cout << "can not open listfile." << endl;
    }

    std::vector GalleryImageFilename;
    string str;
    while (std::getline(fin, str))
    {
        GalleryImageFilename.push_back(str);
    }
    fin.close();

    std::vector GalleryIndex(GalleryImageFilename.size());
    for (size_t i = 0; i < GalleryImageFilename.size(); ++i)
    {
        //register face into facedatabase
        std::string &filename = GalleryImageFilename[i];

        int64_t &index = GalleryIndex[i];
        std::cerr << "Registering... " << filename << std::endl;
        seeta::cv::ImageData image = cv::imread(filename);
        auto id = engine.Register(image);
        /*
        //删除文件夹中无效图片,防止数据库中无效图片过多。
        if (id == -1)
        {
            const char* p = filename.data();
            remove(p);
        }*/
        index = id;
        std::cerr << "Registered id = " << id << std::endl;
    }
    std::map GalleryIndexMap;
    for (size_t i = 0; i < GalleryIndex.size(); ++i)
    {
        // save index and name pair
        if (GalleryIndex[i] < 0) continue;
        GalleryIndexMap.insert(std::make_pair(GalleryIndex[i], GalleryImageFilename[i]));
    }
    std::cout << "----open camera----" << std::endl;
    // Open default USB camera
    cv::VideoCapture capture;
    capture.open(0);

    cv::Mat frame;

    while (capture.isOpened())
    {
        capture >> frame;
        if (frame.empty()) continue;

        seeta::cv::ImageData image = frame;

        // Detect all faces
        std::vector faces = engine.DetectFaces(image);

        for (SeetaFaceInfo &face : faces)
        {
            // Query top 1
            int64_t index = -1;
            float similarity = 0;

            auto points = engine.DetectPoints(image, face);

            auto queried = engine.QueryTop(image, points.data(), 1, &index, &similarity);

            cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3);
            for (int i = 0; i < 5; ++i)
            {
                auto &point = points[i];
                cv::circle(frame, cv::Point(int(point.x), int(point.y)), 2, CV_RGB(128, 255, 128), -1);
            }

            // no face queried from database
            if (queried < 1) continue;
            std::cerr << similarity << std::endl;
            // similarity greater than threshold, means recognized
            if (similarity > threshold)
            {
                std::cout << "person:" << GalleryIndexMap[index] << std::endl;
                cv::putText(frame, GalleryIndexMap[index], cv::Point(face.pos.x, face.pos.y - 5), 3, 1, CV_RGB(255, 128, 128));
                capture.release();    //close camera
            }
            else {
                std::cerr << "Nothing similar." << std::endl;
                capture.release();    //close camera
            }
        }

        cv::imshow("Idenify_result", frame);

        auto key = cv::waitKey(20);
        if (key == 27)
        {
            break;
        }
    }
    return 0;
}

主函数调用

int main()
{
    
    seeta::ModelSetting::Device device = seeta::ModelSetting::CPU;
    int id = 0;
    seeta::ModelSetting FD_model( "./model/fd_2_00.dat", device, id );
    seeta::ModelSetting PD_model( "./model/pd_2_00_pts5.dat", device, id );
    seeta::ModelSetting FR_model( "./model/fr_2_10.dat", device, id );
    seeta::ModelSetting FL_model("./model/pd_2_00_pts81.dat", device, id);
    seeta::FaceEngine engine( FD_model, PD_model, FR_model, 2, 16 );

    seeta::FaceDetector FD(FD_model);
    seeta::FaceLandmarker FL(FL_model);
    
    // recognization threshold
    float threshold = 0.5f;

    //set face detector's min face size
    engine.FD.set( seeta::FaceDetector::PROPERTY_MIN_FACE_SIZE, 50 );
    
    //test_video(FD, FL);
    //test_image(FD, FL);
    identify_pic();
    //identify_camera();

    //测试本地摄像头
    /*
    std::vector GalleryImageFilename = { "C:\\xxx\\xxx\\xxx.jpg" };
    std::vector GalleryIndex( GalleryImageFilename.size() );
    for( size_t i = 0; i < GalleryImageFilename.size(); ++i )
    {
        //register face into facedatabase
        std::string &filename = GalleryImageFilename[i];
        int64_t &index = GalleryIndex[i];
        std::cerr << "Registering... " << filename << std::endl;
        seeta::cv::ImageData image = cv::imread( filename );
        auto id = engine.Register( image );
        index = id;
        std::cerr << "Registered id = " << id << std::endl;
    }
    std::map GalleryIndexMap;
    for( size_t i = 0; i < GalleryIndex.size(); ++i )
    {
        // save index and name pair
        if( GalleryIndex[i] < 0 ) continue;
        GalleryIndexMap.insert( std::make_pair( GalleryIndex[i], GalleryImageFilename[i] ) );
    }

    std::cout << "----open camera----" << std::endl;
    // Open default USB camera
    cv::VideoCapture capture;
    capture.open( 0 );

    cv::Mat frame;

    while( capture.isOpened() )
    {
        capture >> frame;
        if( frame.empty() ) continue;

        seeta::cv::ImageData image = frame;

        // Detect all faces
        std::vector faces = engine.DetectFaces( image );

        for( SeetaFaceInfo &face : faces )
        {
            // Query top 1
            int64_t index = -1;
            float similarity = 0;

            auto points = engine.DetectPoints(image, face);
             
            auto queried = engine.QueryTop( image, points.data(), 1, &index, &similarity );

            cv::rectangle( frame, cv::Rect( face.pos.x, face.pos.y, face.pos.width, face.pos.height ), CV_RGB( 128, 128, 255 ), 3 );
            for (int i = 0; i < 5; ++i)
            {
                auto &point = points[i];
                cv::circle(frame, cv::Point(int(point.x), int(point.y)), 2, CV_RGB(128, 255, 128), -1);
            }

            // no face queried from database
            if (queried < 1) continue;

            // similarity greater than threshold, means recognized
            if( similarity > threshold )
            {
                cv::putText( frame, GalleryIndexMap[index], cv::Point( face.pos.x, face.pos.y - 5 ), 3, 1, CV_RGB( 255, 128, 128 ) );
            }
        }

        cv::imshow( "Frame", frame );

        auto key = cv::waitKey( 20 );
        if( key == 27 )
        {
            break;
        }
    }
    */
    return 0;
}
  • 欢迎提出问题建议,查缺补漏。
    如有帮助,请多多支持,感谢~~~

你可能感兴趣的:(SeetaFace2-master在Windows10+VS环境中实现人脸检测、关键点定位、特征提取与比对的Simple Demos)