基於Dlib進行人臉特徵點批量標註

程序功能:遍歷傳入文件夾下的所有Png格式圖片並對圖片的人臉進行標註。

標註結果:每個圖片會生成一個xml文件,裏面包含68個關鍵點的信息,如下所示,

開發環境:Win10&VS2015

使用開源庫:

C++ XML parser :https://github.com/leethomason/tinyxml2
Dlib : https://github.com/davisking/dlib/releases/tag/v19.16

檢測部分代碼:

void DetectLandmark(cv::Mat& imgTemp, std::map<int, Coordination_2D>& markerCoordis, std::string mvxPath)
{
    try
    {
        dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();
        dlib::shape_predictor pose_model;
        dlib::deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;

        dlib::cv_image<dlib::bgr_pixel> cimg(imgTemp);
        std::vector<dlib::rectangle> faces = detector(cimg);
        std::vector<dlib::full_object_detection> shapes; // Find the pose of each face.
        for (unsigned long i = 0; i < faces.size(); ++i)
            shapes.push_back(pose_model(cimg, faces[i]));

        if (!shapes.empty()) {
            for (int i = 0; i < 68; i++) {
                circle(imgTemp, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 1, cv::Scalar(0, 0, 255), -1);
                Coordination_2D Coordi(shapes[0].part(i).x(), shapes[0].part(i).y());
                markerCoordis[i] = Coordi;
            }
        }
        std::string saveIRName = mvxPath.substr(0, mvxPath.rfind(".")) + "Feature" + ".png";
    }
    catch (dlib::serialization_error& e)
    {
        std::cout << "You need dlib's default face landmarking model file to run this example." << std::endl
            << "You can get it from the following URL: " << std::endl
            << "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << std::endl
            << std::endl << e.what() << std::endl;
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
};

 保存爲xml部分代碼:

void ExportFeatureCoordToXml(const std::map<int, Coordination_2D>& featuresMap, std::string mvxPath)
{
    std::cout << GetSampleID(mvxPath) << std::endl;
    tinyxml2::XMLDocument doc;
    tinyxml2::XMLElement* root = doc.NewElement("sampleID");
    root->SetAttribute("value", GetSampleID(mvxPath).c_str());
    doc.InsertFirstChild(root);
    tinyxml2::XMLElement* features = doc.NewElement("features");

    for (int i = 0; i < 68; i++)
    {
        tinyxml2::XMLElement* feature = doc.NewElement("feature");
        tinyxml2::XMLElement* x = doc.NewElement("x");
        tinyxml2::XMLElement* y = doc.NewElement("y");

        feature->SetAttribute("featureID", i);
        x->SetAttribute("value", featuresMap.at(i).x_2D);
        y->SetAttribute("value", featuresMap.at(i).y_2D);

        feature->InsertFirstChild(x);
        feature->InsertAfterChild(x, y);

        features->InsertEndChild(feature);
    }

    root->InsertFirstChild(features);

    std::string saveXmlName = mvxPath.substr(0, mvxPath.rfind(".")) + "Feature" + ".xml";
    doc.SaveFile(saveXmlName.c_str());

    std::cout << saveXmlName << " saved." << std::endl;
}

完整工程地址:https://github.com/yazhouzheng/FaceAnnotation

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章