程序功能:遍歷傳入文件夾下的所有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;
}