基于Dlib进行人脸特征点批量标注

程序功能:遍历传入文件夹下的所有Png格式图片并对图片的人脸进行标注。

标注结果:每个图片会生成一个xml文件,里面包含68个关键点的信息,如下所示,

基于Dlib进行人脸特征点批量标注_第1张图片

开发环境: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& 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 cimg(imgTemp);
        std::vector faces = detector(cimg);
        std::vector 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& 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

你可能感兴趣的:(小工具)