7 #include "../InferenceTestImage.hpp" 12 #include <mapbox/variant.hpp> 13 #include <cxxopts/cxxopts.hpp> 27 class CommandLineProcessor
33 if (result.count(
"infile"))
35 if (!ValidateInputFile(result[
"infile"].as<std::string>()))
42 std::cerr <<
"-i/--infile parameter is mandatory." << std::endl;
47 if (!result.count(
"model-format"))
49 std::cerr <<
"-f/--model-format parameter is mandatory." << std::endl;
54 if (result.count(
"outfile"))
56 if (!ValidateOutputFile(result[
"outfile"].as<std::string>()))
63 std::cerr <<
"-o/--outfile parameter is mandatory." << std::endl;
67 if (result.count(
"layout"))
69 if(!ValidateLayout(result[
"layout"].as<std::string>()))
78 bool ValidateInputFile(
const std::string& inputFileName)
80 if (inputFileName.empty())
82 std::cerr <<
"No input file name specified" << std::endl;
86 if (!fs::exists(inputFileName))
88 std::cerr <<
"Input file [" << inputFileName <<
"] does not exist" << std::endl;
92 if (fs::is_directory(inputFileName))
94 std::cerr <<
"Input file [" << inputFileName <<
"] is a directory" << std::endl;
101 bool ValidateLayout(
const std::string& layout)
105 std::cerr <<
"No layout specified" << std::endl;
109 std::vector<std::string> supportedLayouts = {
"NHWC",
"NCHW" };
111 auto iterator = std::find(supportedLayouts.begin(), supportedLayouts.end(), layout);
112 if (iterator == supportedLayouts.end())
114 std::cerr <<
"Layout [" << layout <<
"] is not supported" << std::endl;
121 bool ValidateOutputFile(
const std::string& outputFileName)
123 if (outputFileName.empty())
125 std::cerr <<
"No output file name specified" << std::endl;
129 if (fs::exists(outputFileName))
131 std::cerr <<
"Output file [" << outputFileName <<
"] already exists" << std::endl;
135 if (fs::is_directory(outputFileName))
137 std::cerr <<
"Output file [" << outputFileName <<
"] is a directory" << std::endl;
141 fs::path outputPath(outputFileName);
142 if (!fs::exists(outputPath.parent_path()))
144 std::cerr <<
"Output directory [" << outputPath.parent_path().c_str() <<
"] does not exist" << std::endl;
151 bool ProcessCommandLine(
int argc,
char* argv[])
153 cxxopts::Options options(
"ImageTensorGenerator",
154 "Program for pre-processing a .jpg image " 155 "before generating a .raw tensor file from it.");
159 options.add_options()
160 (
"h,help",
"Display help messages")
162 "Input image file to generate tensor from",
163 cxxopts::value<std::string>(m_InputFileName))
165 "Format of the intended model file that uses the images." 166 "Different formats have different image normalization styles." 167 "Accepted values (caffe, tensorflow, tflite)",
168 cxxopts::value<std::string>(m_ModelFormat))
170 "Output raw tensor file path",
171 cxxopts::value<std::string>(m_OutputFileName))
173 "The data type of the output tensors." 174 "If unset, defaults to \"float\" for all defined inputs. " 175 "Accepted values (float, int or qasymm8)",
176 cxxopts::value<std::string>(m_OutputType)->default_value(
"float"))
178 "Resize image to new width. Keep original width if unspecified",
179 cxxopts::value<std::string>(m_NewWidth)->default_value(
"0"))
181 "Resize image to new height. Keep original height if unspecified",
182 cxxopts::value<std::string>(m_NewHeight)->default_value(
"0"))
184 "Output data layout, \"NHWC\" or \"NCHW\", default value NHWC",
185 cxxopts::value<std::string>(m_Layout)->default_value(
"NHWC"));
187 catch (
const std::exception& e)
189 std::cerr << options.help() << std::endl;
195 auto result = options.parse(argc, argv);
197 if (result.count(
"help"))
199 std::cout << options.help() << std::endl;
208 catch (
const cxxopts::OptionException& e)
210 std::cerr << e.what() << std::endl << std::endl;
217 std::string GetInputFileName() {
return m_InputFileName;}
220 if (m_Layout ==
"NHWC")
224 else if (m_Layout ==
"NCHW")
233 std::string GetOutputFileName() {
return m_OutputFileName;}
234 unsigned int GetNewWidth() {
return static_cast<unsigned int>(std::stoi(m_NewWidth));}
235 unsigned int GetNewHeight() {
return static_cast<unsigned int>(std::stoi(m_NewHeight));}
238 if (m_ModelFormat ==
"caffe")
242 else if (m_ModelFormat ==
"tensorflow")
246 else if (m_ModelFormat ==
"tflite")
257 if (m_OutputType ==
"float")
261 else if (m_OutputType ==
"int")
265 else if (m_OutputType ==
"qasymm8")
276 std::string m_InputFileName;
277 std::string m_Layout;
278 std::string m_OutputFileName;
279 std::string m_NewWidth;
280 std::string m_NewHeight;
281 std::string m_ModelFormat;
282 std::string m_OutputType;
287 int main(
int argc,
char* argv[])
289 CommandLineProcessor cmdline;
290 if (!cmdline.ProcessCommandLine(argc, argv))
294 const std::string imagePath(cmdline.GetInputFileName());
295 const std::string outputPath(cmdline.GetOutputFileName());
298 const unsigned int newWidth = cmdline.GetNewWidth();
299 const unsigned int newHeight = cmdline.GetNewHeight();
300 const unsigned int batchSize = 1;
303 using TContainer = mapbox::util::variant<std::vector<float>, std::vector<int>, std::vector<uint8_t>>;
304 std::vector<TContainer> imageDataContainers;
312 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
316 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
321 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
327 ARMNN_LOG(fatal) <<
"Failed to load image file " << imagePath <<
" with error: " << e.
what();
331 std::ofstream imageTensorFile;
332 imageTensorFile.open(outputPath, std::ofstream::out);
333 if (imageTensorFile.is_open())
335 mapbox::util::apply_visitor(
337 imageDataContainers[0]
340 if (!imageTensorFile)
342 ARMNN_LOG(fatal) <<
"Failed to write to output file" << outputPath;
343 imageTensorFile.close();
346 imageTensorFile.close();
350 ARMNN_LOG(fatal) <<
"Failed to open output file" << outputPath;
void ParseOptions(const std::vector< BackendOptions > &options, BackendId backend, F f)
NormalizationParameters GetNormalizationParameters(const SupportedFrontend &modelFormat, const armnn::DataType &outputType)
Get normalization parameters.
mapbox::util::variant< std::vector< float >, std::vector< int >, std::vector< unsigned char > > TContainer
virtual const char * what() const noexcept override
#define ARMNN_LOG(severity)
void WriteImageTensorImpl(const std::vector< ElemType > &imageData, std::ofstream &imageTensorFile)
Write image tensor to ofstream.
std::vector< uint8_t > PrepareImageTensor< uint8_t >(const std::string &imagePath, unsigned int newWidth, unsigned int newHeight, const NormalizationParameters &normParams, unsigned int batchSize, const armnn::DataLayout &outputLayout)
std::vector< int > PrepareImageTensor< int >(const std::string &imagePath, unsigned int newWidth, unsigned int newHeight, const NormalizationParameters &normParams, unsigned int batchSize, const armnn::DataLayout &outputLayout)
Base class for all ArmNN exceptions so that users can filter to just those.
int main(int argc, char *argv[])
std::vector< float > PrepareImageTensor< float >(const std::string &imagePath, unsigned int newWidth, unsigned int newHeight, const NormalizationParameters &normParams, unsigned int batchSize, const armnn::DataLayout &outputLayout)