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