1 // Copyright (C) 2018 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
6 #include "classification_set_generator.hpp"
17 #include "user_exception.hpp"
18 #include "details/ie_exception.hpp"
21 # include "w_dirent.h"
23 # include <sys/stat.h>
27 #include "../common/samples/common.hpp"
30 * @brief Gets path part of a filename including separator
31 * @param filepath - filename to extract path part from
32 * @return string with path part of the filename
34 inline std::string folderOf(const std::string &filepath) {
35 auto pos = filepath.rfind("/");
36 if (pos == std::string::npos) pos = filepath.rfind("\\");
37 if (pos == std::string::npos) return "";
38 return filepath.substr(0, pos + 1);
41 void readFile(std::string filename, std::function<void(std::string&, int lineNumber)> perLine) {
42 std::ifstream inputFile;
43 inputFile.open(filename, std::ios::in);
44 std::string strLine = "";
46 if (!inputFile.is_open())
47 THROW_IE_EXCEPTION << "Cannot open file: " << filename;
49 size_t lineNumber = 0;
50 while (std::getline(inputFile, strLine)) {
52 perLine(strLine, lineNumber);
56 std::map<std::string, int> ClassificationSetGenerator::readLabels(const std::string& labels) {
60 readFile(labels, [&](std::string& line, size_t lineNumber) {
68 std::string getFullName(const std::string& name, const std::string& dir) {
69 return dir + "/" + name;
72 std::list<std::string> ClassificationSetGenerator::getDirContents(const std::string& dir, bool includePath) {
74 if (stat(dir.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) {
75 return std::list<std::string>();
76 // THROW_USER_EXCEPTION(1) << "Can't read contents of directory " << dir << ". It isn't a directory or not accessible";
79 std::list<std::string> list;
81 dp = opendir(dir.c_str());
83 THROW_USER_EXCEPTION(1) << "Can't open directory " << dir;
87 while (nullptr != (ep = readdir(dp))) {
88 std::string fileName = ep->d_name;
89 if (fileName == "." || fileName == "..") continue;
90 list.push_back(includePath ? getFullName(ep->d_name, dir) : ep->d_name);
96 std::vector<std::pair<int, std::string>> ClassificationSetGenerator::validationMapFromTxt(const std::string& file) {
97 std::string ext = fileExt(file);
99 THROW_USER_EXCEPTION(1) << "Unknown dataset data file format: " << ext << "";
102 std::string dir = folderOf(file);
103 std::vector<std::pair<int, std::string>> validationMap;
104 std::string imgPath = "";
107 readFile(file, [&](std::string& line, size_t lineNumber) {
109 size_t pos = line.rfind(" ");
110 if (pos == std::string::npos) {
111 THROW_USER_EXCEPTION(1) << "Bad file format! Cannot parse line " << lineNumber << ":\n> " << line;
114 classId = std::stoi(line.substr(pos + 1));
115 } catch (const std::invalid_argument& e) {
116 THROW_USER_EXCEPTION(1) << "Invalid class id specified at line " << lineNumber << ":\n> " << line;
118 imgPath = line.substr(0, pos);
119 validationMap.push_back({ classId, dir + imgPath });
122 return validationMap;
125 std::vector<std::pair<int, std::string>> ClassificationSetGenerator::validationMapFromFolder(const std::string& dir) {
126 std::vector<std::pair<int, std::string>> validationMap;
127 std::list<std::string> validation_labels = getDirContents(dir, false);
129 for (auto& label : validation_labels) {
130 auto val = _classes.find(label);
131 if (val == _classes.end()) continue;
133 int id = val->second;
134 for (auto& image : getDirContents(getFullName(label, dir))) {
135 validationMap.push_back({ id + 1, image }); // [CVS-8200] line in .labels file is counted from 0, but classes are counted from 1
138 return validationMap;
141 std::vector<std::pair<int, std::string>> ClassificationSetGenerator::getValidationMap(const std::string& path) {
143 if (stat(path.c_str(), &sb) == 0) {
144 if (S_ISDIR(sb.st_mode)) {
145 return validationMapFromFolder(path);
147 return validationMapFromTxt(path);
150 if (errno == ENOENT || errno == EINVAL || errno == EACCES) {
151 THROW_USER_EXCEPTION(3) << "The specified path \"" << path << "\" can not be found or accessed";