10 #include <boost/format.hpp> 11 #include <boost/numeric/conversion/cast.hpp> 15 #define STB_IMAGE_IMPLEMENTATION 16 #include <stb/stb_image.h> 18 #define STB_IMAGE_RESIZE_IMPLEMENTATION 19 #include <stb/stb_image_resize.h> 21 #define STB_IMAGE_WRITE_IMPLEMENTATION 22 #include <stb/stb_image_write.h> 29 switch (channelLayout)
32 return static_cast<unsigned int>(channel);
34 return 2u -
static_cast<unsigned int>(channel);
37 % static_cast<int>(channelLayout)));
41 inline float Lerp(
float a,
float b,
float w)
43 return w * b + (1.f - w) * a;
46 inline void PutData(std::vector<float> & data,
47 const unsigned int width,
53 data[(3*((y*width)+x)) + c] = value;
57 const unsigned int outputWidth,
58 const unsigned int outputHeight,
60 const std::array<float, 3>& mean,
61 const std::array<float, 3>& stddev)
63 std::vector<float> out;
64 out.resize(outputWidth * outputHeight * 3);
70 const unsigned int inputWidth = image.
GetWidth();
71 const unsigned int inputHeight = image.
GetHeight();
75 const float scaleY =
boost::numeric_cast<
float>(inputHeight) / boost::numeric_cast<float>(outputHeight);
76 const float scaleX =
boost::numeric_cast<
float>(inputWidth) / boost::numeric_cast<float>(outputWidth);
83 for (
unsigned int y = 0; y < outputHeight; ++y)
89 const float fiy = floorf(iy);
93 const float yw = iy - fiy;
95 for (
unsigned int x = 0; x < outputWidth; ++x)
99 const float fix = floorf(ix);
103 const float xw = ix - fix;
106 const unsigned int x1 = std::min(x0 + 1, inputWidth - 1u);
107 const unsigned int y1 = std::min(y0 + 1, inputHeight - 1u);
114 for (
unsigned c=0; c<3; ++c)
116 const float ly0 = Lerp(
float(rgb_x0y0[c]),
float(rgb_x1y0[c]), xw);
117 const float ly1 = Lerp(
float(rgb_x0y1[c]),
float(rgb_x1y1[c]), xw);
118 const float l = Lerp(ly0, ly1, yw);
119 PutData(out, outputWidth, x, y, c, ((l / scale) - mean[c]) / stddev[c]);
137 using StbImageDataPtr = std::unique_ptr<unsigned char, decltype(&stbi_image_free)>;
138 StbImageDataPtr stbData(stbi_load(filePath, &width, &height, &channels, 0), &stbi_image_free);
140 if (stbData ==
nullptr)
145 if (width == 0 || height == 0)
155 m_Data.resize(sizeInBytes);
156 memcpy(m_Data.data(), stbData.get(), sizeInBytes);
161 if (x >= m_Width || y >= m_Height)
164 "Requested (%1%, %2%). Maximum valid coordinates (%3%, %4%).") % x % y % (m_Width - 1) % (m_Height - 1)));
168 const uint8_t*
const pixelData = m_Data.data() + pixelOffset;
171 std::array<uint8_t, 3> outPixelData;
172 outPixelData.fill(0);
174 const unsigned int maxChannelsInPixel = std::min(
GetNumChannels(), static_cast<unsigned int>(outPixelData.size()));
175 for (
unsigned int c = 0; c < maxChannelsInPixel; ++c)
177 outPixelData[c] = pixelData[c];
180 return std::make_tuple(outPixelData[0], outPixelData[1], outPixelData[2]);
186 std::vector<uint8_t> newData;
187 newData.resize(newWidth * newHeight * im.
GetNumChannels() * im.GetSingleElementSizeInBytes());
195 const int w =
static_cast<int>(im.
GetWidth());
196 const int h =
static_cast<int>(im.
GetHeight());
199 const int res = stbir_resize_uint8(im.m_Data.data(), w, h, 0, newData.data(), nW, nH, 0, numChannels);
205 im.m_Data.swap(newData);
206 im.m_Width = newWidth;
207 im.m_Height = newHeight;
211 unsigned int newHeight,
214 const std::array<float, 3>& mean,
215 const std::array<float, 3>& stddev,
218 std::vector<float> out;
219 if (newWidth == 0 || newHeight == 0)
222 "operation can be zero. Requested width: %1%. Requested height: %2%.") % newWidth % newHeight));
233 out = ResizeBilinearAndNormalize(*
this, newWidth, newHeight, scale, mean, stddev);
238 boost::format(
"Unknown resizing method asked ArmNN only supports {STB, BilinearAndNormalized} %1%")
246 const int w =
static_cast<int>(
GetWidth());
247 const int h =
static_cast<int>(
GetHeight());
255 res = stbi_write_png(filePath, w, h, numChannels, m_Data.data(), 0);
260 res = stbi_write_bmp(filePath, w, h, numChannels, m_Data.data());
265 res = stbi_write_tga(filePath, w, h, numChannels, m_Data.data());
270 % static_cast<int>(format)));
280 template <
typename TProcessValueCallable>
283 TProcessValueCallable processValue)
285 const unsigned int h = image.
GetHeight();
286 const unsigned int w = image.
GetWidth();
288 std::vector<float> imageData;
289 imageData.resize(h * w * 3);
291 for (
unsigned int j = 0; j < h; ++j)
293 for (
unsigned int i = 0; i < w; ++i)
299 const unsigned int rDstIndex = GetImageChannelIndex(channelLayout,
ImageChannel::R) * h * w + j * w + i;
300 const unsigned int gDstIndex = GetImageChannelIndex(channelLayout,
ImageChannel::G) * h * w + j * w + i;
301 const unsigned int bDstIndex = GetImageChannelIndex(channelLayout,
ImageChannel::B) * h * w + j * w + i;
319 return value / 255.f;
325 const std::array<float, 3>& mean)
330 const unsigned int channelIndex = GetImageChannelIndex(layout, channel);
331 return value - mean[channelIndex];
338 std::vector<float> imageData;
339 const unsigned int h = image.
GetHeight();
340 const unsigned int w = image.
GetWidth();
342 const unsigned int rDstIndex = GetImageChannelIndex(layout,
ImageChannel::R);
343 const unsigned int gDstIndex = GetImageChannelIndex(layout,
ImageChannel::G);
344 const unsigned int bDstIndex = GetImageChannelIndex(layout,
ImageChannel::B);
346 imageData.resize(h * w * 3);
347 unsigned int offset = 0;
349 for (
unsigned int j = 0; j < h; ++j)
351 for (
unsigned int i = 0; i < w; ++i)
356 imageData[offset+rDstIndex] = float(r) / 255.0f;
357 imageData[offset+gDstIndex] = float(g) / 255.0f;
358 imageData[offset+bDstIndex] = float(b) / 255.0f;
void Write(WriteFormat format, const char *filePath) const
unsigned int GetNumChannels() const
std::string AsString() const
void IgnoreUnused(Ts &&...)
std::vector< float > GetImageDataInArmNnLayoutAsNormalizedFloats(ImageChannelLayout layout, const InferenceTestImage &image)
unsigned int GetWidth() const
std::vector< float > GetImageDataInArmNnLayoutAsFloatsSubtractingMean(ImageChannelLayout layout, const InferenceTestImage &image, const std::array< float, 3 > &mean)
void StbResize(InferenceTestImage &im, const unsigned int newWidth, const unsigned int newHeight)
#define ARMNN_ASSERT(COND)
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
std::vector< float > GetImageDataAsNormalizedFloats(ImageChannelLayout layout, const InferenceTestImage &image)
std::tuple< uint8_t, uint8_t, uint8_t > GetPixelAs3Channels(unsigned int x, unsigned int y) const
unsigned int GetSizeInBytes() const
unsigned int GetHeight() const
std::vector< float > Resize(unsigned int newWidth, unsigned int newHeight, const armnn::CheckLocation &location, const ResizingMethods meth=ResizingMethods::STB, const std::array< float, 3 > &mean={{0.0, 0.0, 0.0}}, const std::array< float, 3 > &stddev={{1.0, 1.0, 1.0}}, const float scale=255.0f)
InferenceTestImage(const char *filePath)
std::vector< float > GetImageDataInArmNnLayoutAsFloats(ImageChannelLayout channelLayout, const InferenceTestImage &image, TProcessValueCallable processValue)