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 "If unset, defaults to tflite." 168 "Accepted value (tflite)",
169 cxxopts::value<std::string>(m_ModelFormat)->default_value(
"tflite"))
171 "Output raw tensor file path",
172 cxxopts::value<std::string>(m_OutputFileName))
174 "The data type of the output tensors." 175 "If unset, defaults to \"float\" for all defined inputs. " 176 "Accepted values (float, int, qasymms8 or qasymmu8)",
177 cxxopts::value<std::string>(m_OutputType)->default_value(
"float"))
179 "Resize image to new width. Keep original width if unspecified",
180 cxxopts::value<std::string>(m_NewWidth)->default_value(
"0"))
182 "Resize image to new height. Keep original height if unspecified",
183 cxxopts::value<std::string>(m_NewHeight)->default_value(
"0"))
185 "Output data layout, \"NHWC\" or \"NCHW\", default value NHWC",
186 cxxopts::value<std::string>(m_Layout)->default_value(
"NHWC"));
188 catch (
const std::exception& e)
190 std::cerr << options.help() << std::endl;
196 auto result = options.parse(argc, argv);
198 if (result.count(
"help"))
200 std::cout << options.help() << std::endl;
209 catch (
const cxxopts::OptionException& e)
211 std::cerr << e.what() << std::endl << std::endl;
218 std::string GetInputFileName() {
return m_InputFileName;}
221 if (m_Layout ==
"NHWC")
225 else if (m_Layout ==
"NCHW")
234 std::string GetOutputFileName() {
return m_OutputFileName;}
235 unsigned int GetNewWidth() {
return static_cast<unsigned int>(std::stoi(m_NewWidth));}
236 unsigned int GetNewHeight() {
return static_cast<unsigned int>(std::stoi(m_NewHeight));}
239 if (m_ModelFormat ==
"tflite")
250 if (m_OutputType ==
"float")
254 else if (m_OutputType ==
"int")
258 else if (m_OutputType ==
"qasymm8" || m_OutputType ==
"qasymmu8")
262 else if (m_OutputType ==
"qasymms8")
273 std::string m_InputFileName;
274 std::string m_Layout;
275 std::string m_OutputFileName;
276 std::string m_NewWidth;
277 std::string m_NewHeight;
278 std::string m_ModelFormat;
279 std::string m_OutputType;
284 int main(
int argc,
char* argv[])
286 CommandLineProcessor cmdline;
287 if (!cmdline.ProcessCommandLine(argc, argv))
291 const std::string imagePath(cmdline.GetInputFileName());
292 const std::string outputPath(cmdline.GetOutputFileName());
295 const unsigned int newWidth = cmdline.GetNewWidth();
296 const unsigned int newHeight = cmdline.GetNewHeight();
297 const unsigned int batchSize = 1;
300 using TContainer = mapbox::util::variant<std::vector<float>, std::vector<int>, std::vector<uint8_t>,
301 std::vector<int8_t>>;
302 std::vector<TContainer> imageDataContainers;
310 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
314 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
318 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
323 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
329 ARMNN_LOG(fatal) <<
"Failed to load image file " << imagePath <<
" with error: " << e.
what();
333 std::ofstream imageTensorFile;
334 imageTensorFile.open(outputPath, std::ofstream::out);
335 if (imageTensorFile.is_open())
337 mapbox::util::apply_visitor(
339 imageDataContainers[0]
342 if (!imageTensorFile)
344 ARMNN_LOG(fatal) <<
"Failed to write to output file" << outputPath;
345 imageTensorFile.close();
348 imageTensorFile.close();
352 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.
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< int8_t > PrepareImageTensor< int8_t >(const std::string &imagePath, unsigned int newWidth, unsigned int newHeight, const NormalizationParameters &normParams, unsigned int batchSize, const armnn::DataLayout &outputLayout)
mapbox::util::variant< std::vector< float >, std::vector< int >, std::vector< unsigned char >, std::vector< int8_t > > TContainer
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)