1 // 2 // Copyright © 2017 Arm Ltd. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 #pragma once 6 7 #include <armnn/Exceptions.hpp> 8 #include <VerificationHelpers.hpp> 9 10 #include <array> 11 #include <cstdint> 12 #include <vector> 13 #include <utility> 14 15 class InferenceTestImageException : public armnn::Exception 16 { 17 public: 18 using Exception::Exception; 19 }; 20 21 class InferenceTestImageLoadFailed : public InferenceTestImageException 22 { 23 public: 24 using InferenceTestImageException::InferenceTestImageException; 25 }; 26 27 class InferenceTestImageOutOfBoundsAccess : public InferenceTestImageException 28 { 29 public: 30 using InferenceTestImageException::InferenceTestImageException; 31 }; 32 33 class InferenceTestImageResizeFailed : public InferenceTestImageException 34 { 35 public: 36 using InferenceTestImageException::InferenceTestImageException; 37 }; 38 39 class InferenceTestImageWriteFailed : public InferenceTestImageException 40 { 41 public: 42 using InferenceTestImageException::InferenceTestImageException; 43 }; 44 45 class UnknownImageChannelLayout : public InferenceTestImageException 46 { 47 public: 48 using InferenceTestImageException::InferenceTestImageException; 49 }; 50 51 class InferenceTestImage 52 { 53 public: 54 enum class WriteFormat 55 { 56 Png, 57 Bmp, 58 Tga 59 }; 60 61 // Common names used to identify a channel in a pixel. 62 enum class ResizingMethods 63 { 64 STB, 65 BilinearAndNormalized, 66 }; 67 68 explicit InferenceTestImage(const char* filePath); 69 70 InferenceTestImage(InferenceTestImage&&) = delete; 71 InferenceTestImage(const InferenceTestImage&) = delete; 72 InferenceTestImage& operator=(const InferenceTestImage&) = delete; 73 InferenceTestImage& operator=(InferenceTestImage&&) = delete; 74 GetWidth() const75 unsigned int GetWidth() const { return m_Width; } GetHeight() const76 unsigned int GetHeight() const { return m_Height; } GetNumChannels() const77 unsigned int GetNumChannels() const { return m_NumChannels; } GetNumElements() const78 unsigned int GetNumElements() const { return GetWidth() * GetHeight() * GetNumChannels(); } GetSizeInBytes() const79 unsigned int GetSizeInBytes() const { return GetNumElements() * GetSingleElementSizeInBytes(); } 80 81 // Returns the pixel identified by the given coordinates as a 3-channel value. 82 // Channels beyond the third are dropped. If the image provides less than 3 channels, the non-existent 83 // channels of the pixel will be filled with 0. Channels are returned in RGB order (that is, the first element 84 // of the tuple corresponds to the Red channel, whereas the last element is the Blue channel). 85 std::tuple<uint8_t, uint8_t, uint8_t> GetPixelAs3Channels(unsigned int x, unsigned int y) const; 86 87 void StbResize(InferenceTestImage& im, const unsigned int newWidth, const unsigned int newHeight); 88 89 90 std::vector<float> Resize(unsigned int newWidth, 91 unsigned int newHeight, 92 const armnn::CheckLocation& location, 93 const ResizingMethods meth = ResizingMethods::STB, 94 const std::array<float, 3>& mean = {{0.0, 0.0, 0.0}}, 95 const std::array<float, 3>& stddev = {{1.0, 1.0, 1.0}}, 96 const float scale = 255.0f); 97 98 void Write(WriteFormat format, const char* filePath) const; 99 100 private: GetSingleElementSizeInBytes()101 static unsigned int GetSingleElementSizeInBytes() 102 { 103 return sizeof(decltype(std::declval<InferenceTestImage>().m_Data[0])); 104 } 105 106 std::vector<uint8_t> m_Data; 107 unsigned int m_Width; 108 unsigned int m_Height; 109 unsigned int m_NumChannels; 110 }; 111 112 // Common names used to identify a channel in a pixel. 113 enum class ImageChannel 114 { 115 R, 116 G, 117 B 118 }; 119 120 // Channel layouts handled by the test framework. 121 enum class ImageChannelLayout 122 { 123 Rgb, 124 Bgr 125 }; 126 127 // Reads the contents of an inference test image as 3-channel pixels whose channel values have been normalized (scaled) 128 // and now lie in the range [0,1]. Channel data is stored according to the ArmNN layout (CHW). The order in which 129 // channels appear in the resulting vector is defined by the provided layout. 130 std::vector<float> GetImageDataInArmNnLayoutAsNormalizedFloats(ImageChannelLayout layout, 131 const InferenceTestImage& image); 132 133 // Reads the contents of an inference test image as 3-channel pixels, whose value is the result of subtracting the mean 134 // from the values in the original image. Channel data is stored according to the ArmNN layout (CHW). The order in 135 // which channels appear in the resulting vector is defined by the provided layout. The order of the channels of the 136 // provided mean should also match the given layout. 137 std::vector<float> GetImageDataInArmNnLayoutAsFloatsSubtractingMean(ImageChannelLayout layout, 138 const InferenceTestImage& image, 139 const std::array<float, 3>& mean); 140 141 // Reads the contents of an inference test image as 3-channel pixels and returns the image data as normalized float 142 // values. The returned image stay in the original order (HWC) order. The C order may be changed according to the 143 // supplied layout value. 144 std::vector<float> GetImageDataAsNormalizedFloats(ImageChannelLayout layout, 145 const InferenceTestImage& image); 146