SeetaFace2-master在Windows10+VS環(huán)境中實(shí)現(xiàn)人臉檢測、關(guān)鍵點(diǎn)定位、特征提取與比對的Simple Demos

  • 首先,需要實(shí)現(xiàn)SeetaFace2-master在Windows10 VS20XX搭建項(xiàng)目。
    可以參考這篇博客:https://blog.csdn.net/sinat_33896833/article/details/100183581
  • 環(huán)境搭建好之后,會發(fā)現(xiàn)里面有example.cpp,運(yùn)行能夠基本實(shí)現(xiàn)FaceDetection功能。但還是不夠,因此我又模擬了幾個demo,僅供參考。

在search中添加.cpp文件

引用頭文件

#pragma warning(disable: 4819)

#include <seeta/FaceEngine.h>
#include <seeta/FaceDetector.h>
#include <seeta/FaceLandmarker.h>

#include <seeta/Struct_cv.h>
#include <seeta/Struct.h>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <array>
#include <map>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <vector>
#include <cstdio>
#include <fstream>
#include <iostream>
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<std::string> GalleryImageFilename;
    string str;
    while (std::getline(fin, str))
    {
        GalleryImageFilename.push_back(str);
    }
    fin.close();

    std::vector<int64_t> 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<int64_t, std::string> 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<SeetaFaceInfo> 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<std::string> GalleryImageFilename;
    string str;
    while (std::getline(fin, str))
    {
        GalleryImageFilename.push_back(str);
    }
    fin.close();

    std::vector<int64_t> 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);
        /*
        //刪除文件夾中無效圖片,防止數(shù)據(jù)庫中無效圖片過多。
        if (id == -1)
        {
            const char* p = filename.data();
            remove(p);
        }*/
        index = id;
        std::cerr << "Registered id = " << id << std::endl;
    }
    std::map<int64_t, std::string> 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<SeetaFaceInfo> 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;
}

主函數(shù)調(diào)用

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();

    //測試本地?cái)z像頭
    /*
    std::vector<std::string> GalleryImageFilename = { "C:\\xxx\\xxx\\xxx.jpg" };
    std::vector<int64_t> 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<int64_t, std::string> 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<SeetaFaceInfo> 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;
}
  • 歡迎提出問題建議,查缺補(bǔ)漏。
    如有幫助,請多多支持,感謝~~~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1,Search Bar 怎樣去掉背景的顏色(storyboard里只能設(shè)置background顏色,可是發(fā)現(xiàn)cl...
    以德扶人閱讀 2,895評論 2 50
  • 幾千年來,我們一直在尋找一種能夠延長壽命的方法,但結(jié)果卻是運(yùn)氣不佳。在過去的200年里,發(fā)達(dá)國家的人均壽命從37歲...
    梓色揚(yáng)光閱讀 555評論 0 2
  • 清明節(jié)的陵園里, 我靜靜肅立。 讓目光觸摸每一個墓碑, 眼前呈現(xiàn)飄揚(yáng)的戰(zhàn)旗。 松柏的長青, 攪動我心的潮汐。 ...
    左寨小學(xué)王晶霞閱讀 296評論 0 1
  • 那么一瞬間,想要談戀愛,想要結(jié)婚,想要做好多好多的事情。這種沖動提醒著我,自己的人生空白一片。
    千浮生閱讀 137評論 0 0
  • 今天我回到家看見有一個大包裹,我拆開一看,哇喔,原來是媽媽給我買的輪滑鞋,我好興奮喲。 我的新輪滑鞋是黃黑色的...
    M張皓軒M閱讀 217評論 0 1

友情鏈接更多精彩內(nèi)容