7 #include "../InferenceTestImage.hpp" 11 #include <boost/filesystem.hpp> 12 #include <boost/filesystem/operations.hpp> 13 #include <boost/filesystem/path.hpp> 14 #include <boost/program_options.hpp> 15 #include <boost/variant.hpp> 29 class CommandLineProcessor
32 bool ValidateInputFile(
const std::string& inputFileName)
34 if (inputFileName.empty())
36 std::cerr <<
"No input file name specified" << std::endl;
40 if (!boost::filesystem::exists(inputFileName))
42 std::cerr <<
"Input file [" << inputFileName <<
"] does not exist" << std::endl;
46 if (boost::filesystem::is_directory(inputFileName))
48 std::cerr <<
"Input file [" << inputFileName <<
"] is a directory" << std::endl;
55 bool ValidateLayout(
const std::string& layout)
59 std::cerr <<
"No layout specified" << std::endl;
63 std::vector<std::string> supportedLayouts = {
"NHWC",
"NCHW" };
65 auto iterator = std::find(supportedLayouts.begin(), supportedLayouts.end(), layout);
66 if (iterator == supportedLayouts.end())
68 std::cerr <<
"Layout [" << layout <<
"] is not supported" << std::endl;
75 bool ValidateOutputFile(std::string& outputFileName)
77 if (outputFileName.empty())
79 std::cerr <<
"No output file name specified" << std::endl;
83 if (boost::filesystem::exists(outputFileName))
85 std::cerr <<
"Output file [" << outputFileName <<
"] already exists" << std::endl;
89 if (boost::filesystem::is_directory(outputFileName))
91 std::cerr <<
"Output file [" << outputFileName <<
"] is a directory" << std::endl;
95 boost::filesystem::path outputPath(outputFileName);
96 if (!boost::filesystem::exists(outputPath.parent_path()))
98 std::cerr <<
"Output directory [" << outputPath.parent_path().c_str() <<
"] does not exist" << std::endl;
105 bool ProcessCommandLine(
int argc,
char* argv[])
107 namespace po = boost::program_options;
109 po::options_description desc(
"Options");
113 (
"help,h",
"Display help messages")
114 (
"infile,i", po::value<std::string>(&m_InputFileName)->required(),
115 "Input image file to generate tensor from")
116 (
"model-format,f", po::value<std::string>(&m_ModelFormat)->required(),
117 "Format of the intended model file that uses the images." 118 "Different formats have different image normalization styles." 119 "Accepted values (caffe, tensorflow, tflite)")
120 (
"outfile,o", po::value<std::string>(&m_OutputFileName)->required(),
121 "Output raw tensor file path")
122 (
"output-type,z", po::value<std::string>(&m_OutputType)->default_value(
"float"),
123 "The data type of the output tensors." 124 "If unset, defaults to \"float\" for all defined inputs. " 125 "Accepted values (float, int or qasymm8)")
126 (
"new-width", po::value<std::string>(&m_NewWidth)->default_value(
"0"),
127 "Resize image to new width. Keep original width if unspecified")
128 (
"new-height", po::value<std::string>(&m_NewHeight)->default_value(
"0"),
129 "Resize image to new height. Keep original height if unspecified")
130 (
"layout,l", po::value<std::string>(&m_Layout)->default_value(
"NHWC"),
131 "Output data layout, \"NHWC\" or \"NCHW\", default value NHWC");
133 catch (
const std::exception& e)
135 std::cerr <<
"Fatal internal error: [" << e.what() <<
"]" << std::endl;
139 po::variables_map vm;
143 po::store(po::parse_command_line(argc, argv, desc), vm);
145 if (vm.count(
"help"))
147 std::cout << desc << std::endl;
153 catch (
const po::error& e)
155 std::cerr << e.what() << std::endl << std::endl;
156 std::cerr << desc << std::endl;
160 if (!ValidateInputFile(m_InputFileName))
165 if (!ValidateLayout(m_Layout))
170 if (!ValidateOutputFile(m_OutputFileName))
178 std::string GetInputFileName() {
return m_InputFileName;}
181 if (m_Layout ==
"NHWC")
185 else if (m_Layout ==
"NCHW")
194 std::string GetOutputFileName() {
return m_OutputFileName;}
195 unsigned int GetNewWidth() {
return static_cast<unsigned int>(std::stoi(m_NewWidth));}
196 unsigned int GetNewHeight() {
return static_cast<unsigned int>(std::stoi(m_NewHeight));}
199 if (m_ModelFormat ==
"caffe")
203 else if (m_ModelFormat ==
"tensorflow")
207 else if (m_ModelFormat ==
"tflite")
218 if (m_OutputType ==
"float")
222 else if (m_OutputType ==
"int")
226 else if (m_OutputType ==
"qasymm8")
237 std::string m_InputFileName;
238 std::string m_Layout;
239 std::string m_OutputFileName;
240 std::string m_NewWidth;
241 std::string m_NewHeight;
242 std::string m_ModelFormat;
243 std::string m_OutputType;
248 int main(
int argc,
char* argv[])
250 CommandLineProcessor cmdline;
251 if (!cmdline.ProcessCommandLine(argc, argv))
255 const std::string imagePath(cmdline.GetInputFileName());
256 const std::string outputPath(cmdline.GetOutputFileName());
259 const unsigned int newWidth = cmdline.GetNewWidth();
260 const unsigned int newHeight = cmdline.GetNewHeight();
261 const unsigned int batchSize = 1;
264 using TContainer = boost::variant<std::vector<float>, std::vector<int>, std::vector<uint8_t>>;
265 std::vector<TContainer> imageDataContainers;
273 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
277 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
282 imagePath, newWidth, newHeight, normParams, batchSize, outputLayout));
288 ARMNN_LOG(fatal) <<
"Failed to load image file " << imagePath <<
" with error: " << e.
what();
292 std::ofstream imageTensorFile;
293 imageTensorFile.open(outputPath, std::ofstream::out);
294 if (imageTensorFile.is_open())
296 boost::apply_visitor([&imageTensorFile](
auto&& imageData) {
WriteImageTensorImpl(imageData, imageTensorFile); },
297 imageDataContainers[0]);
298 if (!imageTensorFile)
300 ARMNN_LOG(fatal) <<
"Failed to write to output file" << outputPath;
301 imageTensorFile.close();
304 imageTensorFile.close();
308 ARMNN_LOG(fatal) <<
"Failed to open output file" << outputPath;
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)
#define ARMNN_LOG(severity)
virtual const char * what() const noexcept override
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)
Base class for all ArmNN exceptions so that users can filter to just those.
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)
boost::variant< std::vector< float >, std::vector< int >, std::vector< unsigned char > > TContainer
void WriteImageTensorImpl(const std::vector< ElemType > &imageData, std::ofstream &imageTensorFile)
NormalizationParameters GetNormalizationParameters(const SupportedFrontend &modelFormat, const armnn::DataType &outputType)