diff --git a/modules/datasets/include/opencv2/datasets/or_pascal.hpp b/modules/datasets/include/opencv2/datasets/or_pascal.hpp new file mode 100644 index 000000000..bca8e62f4 --- /dev/null +++ b/modules/datasets/include/opencv2/datasets/or_pascal.hpp @@ -0,0 +1,102 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2015, Itseez Inc, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Itseez Inc or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DATASETS_VOC_PASCAL_HPP +#define OPENCV_DATASETS_VOC_PASCAL_HPP + +#include +#include + +#include "opencv2/datasets/dataset.hpp" + +#include + +namespace cv +{ +namespace datasets +{ + +//! @addtogroup datasets_or +//! @{ +struct PascalPart: public Object +{ + std::string name; + int xmin; + int ymin; + int xmax; + int ymax; +}; + +struct PascalObj: public PascalPart +{ + std::string pose; + bool truncated; + bool difficult; + bool occluded; + + std::vector parts; +}; + +struct OR_pascalObj : public Object +{ + std::string filename; + + int width; + int height; + int depth; + + std::vector objects; +}; + +class CV_EXPORTS OR_pascal : public Dataset +{ +public: + virtual void load(const std::string &path) = 0; + + static Ptr create(); +}; + +//! @} + +}// namespace dataset +}// namespace cv + +#endif diff --git a/modules/datasets/samples/or_pascal.cpp b/modules/datasets/samples/or_pascal.cpp new file mode 100644 index 000000000..59f48a0f2 --- /dev/null +++ b/modules/datasets/samples/or_pascal.cpp @@ -0,0 +1,112 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2015, Itseez Inc, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Itseez Inc or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "opencv2/datasets/or_pascal.hpp" + +#include + +#include +#include // atoi + +#include +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::datasets; + +int main(int argc, char *argv[]) +{ + const char *keys = + "{ help h usage ? | | show this message }" + "{ path p |true| path to folder with dataset }"; + CommandLineParser parser(argc, argv, keys); + string path(parser.get("path")); + if (parser.has("help") || path=="true") + { + parser.printMessage(); + return -1; + } + + Ptr dataset = OR_pascal::create(); + dataset->load(path); + + // Print train/test/validation size and first example + OR_pascalObj *example; + vector< Ptr > &train = dataset->getTrain(); + printf("\ntrain:\nsize: %u", (unsigned int)train.size()); + example = static_cast(train[0].get()); + printf("\nfirst image: \n%s", example->filename.c_str()); + + printf("\nsize:"); + printf("\n - width: %d", example->width); + printf("\n - height: %d", example->height); + printf("\n - depth: %d", example->depth); + + for (unsigned int i = 0; i < example->objects.size(); i++) + { + printf("\nobject %d", i); + printf("\nname: %s", example->objects[i].name.c_str()); + printf("\npose: %s", example->objects[i].pose.c_str()); + printf("\ntruncated: %d", example->objects[i].truncated); + printf("\ndifficult: %d", example->objects[i].difficult); + printf("\noccluded: %d", example->objects[i].occluded); + + printf("\nbounding box:"); + printf("\n - xmin: %d", example->objects[i].xmin); + printf("\n - ymin: %d", example->objects[i].ymin); + printf("\n - xmax: %d", example->objects[i].xmax); + printf("\n - ymax: %d", example->objects[i].ymax); + } + + vector< Ptr > &test = dataset->getTest(); + printf("\ntest:\nsize: %u", (unsigned int)test.size()); + example = static_cast(test[0].get()); + printf("\nfirst image: \n%s", example->filename.c_str()); + + vector< Ptr > &validation = dataset->getValidation(); + printf("\nvalidation:\nsize: %u", (unsigned int)validation.size()); + example = static_cast(validation[0].get()); + printf("\nfirst image: \n%s\n", example->filename.c_str()); + + return 0; +} diff --git a/modules/datasets/src/or_pascal.cpp b/modules/datasets/src/or_pascal.cpp new file mode 100644 index 000000000..112a8e589 --- /dev/null +++ b/modules/datasets/src/or_pascal.cpp @@ -0,0 +1,214 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2015, Itseez Inc, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Itseez Inc or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "opencv2/datasets/or_pascal.hpp" +#include "opencv2/datasets/util.hpp" +#include +#include + +namespace cv +{ +namespace datasets +{ + +using namespace std; +using namespace tinyxml2; + +class OR_pascalImp : public OR_pascal +{ +public: + OR_pascalImp() {} + + virtual void load(const string &path); + +private: + void loadDataset(const string &path, const string &nameImageSet, vector< Ptr > &imageSet); + Ptr parseAnnotation(const string path, const string id); + const char* parseNodeText(XMLElement* node, const string nodeName, const string defaultValue); +}; + + +void OR_pascalImp::load(const string &path) +{ + train.push_back(vector< Ptr >()); + test.push_back(vector< Ptr >()); + validation.push_back(vector< Ptr >()); + + loadDataset(path, "train", train.back()); + loadDataset(path, "test", test.back()); + loadDataset(path, "val", validation.back()); +} + +void OR_pascalImp::loadDataset(const string &path, const string &nameImageSet, vector< Ptr > &imageSet) +{ + string pathImageSets(path + "ImageSets/Main/"); + string imageList = pathImageSets + nameImageSet + ".txt"; + + ifstream in(imageList.c_str()); + string error_message = format("Image list not exists!\n%s", imageList.c_str()); + + if (!in.is_open()) + CV_Error(Error::StsBadArg, error_message); + + string id = ""; + + while( getline(in, id) ) + { + if( strcmp(nameImageSet.c_str(), "test") == 0 ) // test set ground truth is not available + { + Ptr annotation(new OR_pascalObj); + annotation->filename = path + "JPEGImages/" + id + ".jpg"; + imageSet.push_back(annotation); + } + else + { + imageSet.push_back(parseAnnotation(path, id)); + } + } +} + +const char* OR_pascalImp::parseNodeText(XMLElement* node, const string nodeName, const string defaultValue) +{ + const char* e = node->FirstChildElement(nodeName.c_str())->GetText(); + + if( e != 0 ) + return e ; + else + return defaultValue.c_str(); +} + +Ptr OR_pascalImp::parseAnnotation(const string path, const string id) +{ + string pathAnnotations(path + "Annotations/"); + string pathImages(path + "JPEGImages/"); + Ptr annotation(new OR_pascalObj); + + XMLDocument doc; + string xml_file = pathAnnotations + id + ".xml"; + + XMLError error_code = doc.LoadFile(xml_file.c_str()); + string error_message = format("Parsing XML failed. Error code = %d. \nFile = %s", error_code, xml_file.c_str()); + switch (error_code) + { + case XML_SUCCESS: + break; + case XML_ERROR_FILE_NOT_FOUND: + error_message = "XML file not found! " + error_message; + CV_Error(Error::StsParseError, error_message); + return annotation; + default: + CV_Error(Error::StsParseError, error_message); + break; + } + + // + XMLElement *xml_ann = doc.RootElement(); + + // + string img_name = xml_ann->FirstChildElement("filename")->GetText(); + annotation->filename = pathImages + img_name; + + // + XMLElement *sz = xml_ann->FirstChildElement("size"); + int width = atoi(sz->FirstChildElement("width")->GetText()); + int height = atoi(sz->FirstChildElement("height")->GetText()); + int depth = atoi(sz->FirstChildElement("depth")->GetText()); + annotation->width = width; + annotation->height = height; + annotation->depth = depth; + + // + vector objects; + XMLElement *xml_obj = xml_ann->FirstChildElement("object"); + + while (xml_obj) + { + PascalObj pascal_obj; + pascal_obj.name = xml_obj->FirstChildElement("name")->GetText(); + pascal_obj.pose = parseNodeText(xml_obj, "pose", "Unspecified"); + pascal_obj.truncated = atoi(parseNodeText(xml_obj, "truncated", "0")) > 0; + pascal_obj.difficult = atoi(parseNodeText(xml_obj, "difficult", "0")) > 0; + pascal_obj.occluded = atoi(parseNodeText(xml_obj, "occluded", "0")) > 0; + + // + XMLElement *xml_bndbox = xml_obj->FirstChildElement("bndbox"); + pascal_obj.xmin = atoi(xml_bndbox->FirstChildElement("xmin")->GetText()); + pascal_obj.ymin = atoi(xml_bndbox->FirstChildElement("ymin")->GetText()); + pascal_obj.xmax = atoi(xml_bndbox->FirstChildElement("xmax")->GetText()); + pascal_obj.ymax = atoi(xml_bndbox->FirstChildElement("ymax")->GetText()); + + // + vector parts; + XMLElement *xml_part = xml_obj->FirstChildElement("part"); + + while (xml_part) + { + PascalPart pascal_part; + pascal_part.name = xml_part->FirstChildElement("name")->GetText(); + + xml_bndbox = xml_part->FirstChildElement("bndbox"); + pascal_part.xmin = atoi(xml_bndbox->FirstChildElement("xmin")->GetText()); + pascal_part.ymin = atoi(xml_bndbox->FirstChildElement("ymin")->GetText()); + pascal_part.xmax = atoi(xml_bndbox->FirstChildElement("xmax")->GetText()); + pascal_part.ymax = atoi(xml_bndbox->FirstChildElement("ymax")->GetText()); + parts.push_back(pascal_part); + + xml_part = xml_part->NextSiblingElement("part"); + } + + pascal_obj.parts = parts; + objects.push_back(pascal_obj); + + xml_obj = xml_obj->NextSiblingElement("object"); + } + + annotation->objects = objects; + + return annotation; +} + +Ptr OR_pascal::create() +{ + return Ptr(new OR_pascalImp); +} + +} +}