Aging_MouthReplace / dlibs /tools /imglab /src /convert_pascal_xml.cpp
AshanGimhana's picture
Upload folder using huggingface_hub
9375c9a verified
raw
history blame
7 kB
#include "convert_pascal_xml.h"
#include "dlib/data_io.h"
#include <iostream>
#include <dlib/xml_parser.h>
#include <string>
#include <dlib/dir_nav.h>
#include <dlib/cmd_line_parser.h>
using namespace std;
using namespace dlib;
namespace
{
using namespace dlib::image_dataset_metadata;
// ----------------------------------------------------------------------------------------
class doc_handler : public document_handler
{
image& temp_image;
std::string& dataset_name;
std::vector<std::string> ts;
box temp_box;
public:
doc_handler(
image& temp_image_,
std::string& dataset_name_
):
temp_image(temp_image_),
dataset_name(dataset_name_)
{}
virtual void start_document (
)
{
ts.clear();
temp_image = image();
temp_box = box();
dataset_name.clear();
}
virtual void end_document (
)
{
}
virtual void start_element (
const unsigned long ,
const std::string& name,
const dlib::attribute_list&
)
{
if (ts.size() == 0 && name != "annotation")
{
std::ostringstream sout;
sout << "Invalid XML document. Root tag must be <annotation>. Found <" << name << "> instead.";
throw dlib::error(sout.str());
}
ts.push_back(name);
}
virtual void end_element (
const unsigned long ,
const std::string& name
)
{
ts.pop_back();
if (ts.size() == 0)
return;
if (name == "object" && ts.back() == "annotation")
{
temp_image.boxes.push_back(temp_box);
temp_box = box();
}
}
virtual void characters (
const std::string& data
)
{
if (ts.size() == 2 && ts[1] == "filename")
{
temp_image.filename = trim(data);
}
else if (ts.size() == 3 && ts[2] == "database" && ts[1] == "source")
{
dataset_name = trim(data);
}
else if (ts.size() >= 3)
{
if (ts[ts.size()-2] == "bndbox" && ts[ts.size()-3] == "object")
{
if (ts.back() == "xmin") temp_box.rect.left() = string_cast<double>(data);
else if (ts.back() == "ymin") temp_box.rect.top() = string_cast<double>(data);
else if (ts.back() == "xmax") temp_box.rect.right() = string_cast<double>(data);
else if (ts.back() == "ymax") temp_box.rect.bottom() = string_cast<double>(data);
}
else if (ts.back() == "name" && ts[ts.size()-2] == "object")
{
temp_box.label = trim(data);
}
else if (ts.back() == "difficult" && ts[ts.size()-2] == "object")
{
if (trim(data) == "0" || trim(data) == "false")
{
temp_box.difficult = false;
}
else
{
temp_box.difficult = true;
}
}
else if (ts.back() == "truncated" && ts[ts.size()-2] == "object")
{
if (trim(data) == "0" || trim(data) == "false")
{
temp_box.truncated = false;
}
else
{
temp_box.truncated = true;
}
}
else if (ts.back() == "occluded" && ts[ts.size()-2] == "object")
{
if (trim(data) == "0" || trim(data) == "false")
{
temp_box.occluded = false;
}
else
{
temp_box.occluded = true;
}
}
}
}
virtual void processing_instruction (
const unsigned long ,
const std::string& ,
const std::string&
)
{
}
};
// ----------------------------------------------------------------------------------------
class xml_error_handler : public error_handler
{
public:
virtual void error (
const unsigned long
) { }
virtual void fatal_error (
const unsigned long line_number
)
{
std::ostringstream sout;
sout << "There is a fatal error on line " << line_number << " so parsing will now halt.";
throw dlib::error(sout.str());
}
};
// ----------------------------------------------------------------------------------------
void parse_annotation_file(
const std::string& file,
dlib::image_dataset_metadata::image& img,
std::string& dataset_name
)
{
doc_handler dh(img, dataset_name);
xml_error_handler eh;
xml_parser::kernel_1a parser;
parser.add_document_handler(dh);
parser.add_error_handler(eh);
ifstream fin(file.c_str());
if (!fin)
throw dlib::error("Unable to open file " + file);
parser.parse(fin);
}
// ----------------------------------------------------------------------------------------
}
void convert_pascal_xml(
const command_line_parser& parser
)
{
cout << "Convert from PASCAL XML annotation format..." << endl;
dlib::image_dataset_metadata::dataset dataset;
std::string name;
dlib::image_dataset_metadata::image img;
const std::string filename = parser.option("c").argument();
// make sure the file exists so we can use the get_parent_directory() command to
// figure out it's parent directory.
make_empty_file(filename);
const std::string parent_dir = get_parent_directory(file(filename)).full_name();
for (unsigned long i = 0; i < parser.number_of_arguments(); ++i)
{
try
{
parse_annotation_file(parser[i], img, name);
const string root = get_parent_directory(get_parent_directory(file(parser[i]))).full_name();
const string img_path = root + directory::get_separator() + "JPEGImages" + directory::get_separator();
dataset.name = name;
img.filename = strip_path(img_path + img.filename, parent_dir);
dataset.images.push_back(img);
}
catch (exception& )
{
cout << "Error while processing file " << parser[i] << endl << endl;
throw;
}
}
save_image_dataset_metadata(dataset, filename);
}