IVGCVSW-4018 Move QuantizeHelper.hpp to armnnUtils
[platform/upstream/armnn.git] / tests / MobileNetSsdDatabase.hpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #pragma once
7
8 #include "InferenceTestImage.hpp"
9 #include "ObjectDetectionCommon.hpp"
10
11 #include <QuantizeHelper.hpp>
12
13 #include <armnn/TypesUtils.hpp>
14
15 #include <boost/log/trivial.hpp>
16 #include <boost/numeric/conversion/cast.hpp>
17
18 #include <array>
19 #include <memory>
20 #include <string>
21 #include <vector>
22
23 namespace
24 {
25
26 struct MobileNetSsdTestCaseData
27 {
28     MobileNetSsdTestCaseData(
29         const std::vector<uint8_t>& inputData,
30         const std::vector<DetectedObject>& expectedDetectedObject,
31         const std::vector<std::vector<float>>& expectedOutput)
32         : m_InputData(inputData)
33         , m_ExpectedDetectedObject(expectedDetectedObject)
34         , m_ExpectedOutput(expectedOutput)
35     {}
36
37     std::vector<uint8_t>            m_InputData;
38     std::vector<DetectedObject>     m_ExpectedDetectedObject;
39     std::vector<std::vector<float>> m_ExpectedOutput;
40 };
41
42 class MobileNetSsdDatabase
43 {
44 public:
45     explicit MobileNetSsdDatabase(const std::string& imageDir, float scale, int offset);
46
47     std::unique_ptr<MobileNetSsdTestCaseData> GetTestCaseData(unsigned int testCaseId);
48
49 private:
50     std::string m_ImageDir;
51     float m_Scale;
52     int m_Offset;
53 };
54
55 constexpr unsigned int k_MobileNetSsdImageWidth  = 300u;
56 constexpr unsigned int k_MobileNetSsdImageHeight = k_MobileNetSsdImageWidth;
57
58 // Test cases
59 const std::array<ObjectDetectionInput, 1> g_PerTestCaseInput =
60 {
61     ObjectDetectionInput
62     {
63         "Cat.jpg",
64         {
65           DetectedObject(16.0f, BoundingBox(0.216785252f, 0.079726994f, 0.927124202f, 0.939067304f), 0.79296875f)
66         }
67     }
68 };
69
70 MobileNetSsdDatabase::MobileNetSsdDatabase(const std::string& imageDir, float scale, int offset)
71     : m_ImageDir(imageDir)
72     , m_Scale(scale)
73     , m_Offset(offset)
74 {}
75
76 std::unique_ptr<MobileNetSsdTestCaseData> MobileNetSsdDatabase::GetTestCaseData(unsigned int testCaseId)
77 {
78     const unsigned int safeTestCaseId =
79         testCaseId % boost::numeric_cast<unsigned int>(g_PerTestCaseInput.size());
80     const ObjectDetectionInput& testCaseInput = g_PerTestCaseInput[safeTestCaseId];
81
82     // Load test case input
83     const std::string imagePath = m_ImageDir + testCaseInput.first;
84     std::vector<uint8_t> imageData;
85     try
86     {
87         InferenceTestImage image(imagePath.c_str());
88
89         // Resize image (if needed)
90         const unsigned int width  = image.GetWidth();
91         const unsigned int height = image.GetHeight();
92         if (width != k_MobileNetSsdImageWidth || height != k_MobileNetSsdImageHeight)
93         {
94             image.Resize(k_MobileNetSsdImageWidth, k_MobileNetSsdImageHeight, CHECK_LOCATION());
95         }
96
97         // Get image data as a vector of floats
98         std::vector<float> floatImageData = GetImageDataAsNormalizedFloats(ImageChannelLayout::Rgb, image);
99         imageData = armnnUtils::QuantizedVector<uint8_t>(floatImageData, m_Scale, m_Offset);
100     }
101     catch (const InferenceTestImageException& e)
102     {
103         BOOST_LOG_TRIVIAL(fatal) << "Failed to load image for test case " << testCaseId << ". Error: " << e.what();
104         return nullptr;
105     }
106
107     std::vector<float> numDetections = { static_cast<float>(testCaseInput.second.size()) };
108
109     std::vector<float> detectionBoxes;
110     std::vector<float> detectionClasses;
111     std::vector<float> detectionScores;
112
113     for (DetectedObject expectedObject : testCaseInput.second)
114     {
115             detectionBoxes.push_back(expectedObject.m_BoundingBox.m_YMin);
116             detectionBoxes.push_back(expectedObject.m_BoundingBox.m_XMin);
117             detectionBoxes.push_back(expectedObject.m_BoundingBox.m_YMax);
118             detectionBoxes.push_back(expectedObject.m_BoundingBox.m_XMax);
119
120             detectionClasses.push_back(expectedObject.m_Class);
121
122             detectionScores.push_back(expectedObject.m_Confidence);
123     }
124
125     // Prepare test case expected output
126     std::vector<std::vector<float>> expectedOutputs;
127     expectedOutputs.reserve(4);
128     expectedOutputs.push_back(detectionBoxes);
129     expectedOutputs.push_back(detectionClasses);
130     expectedOutputs.push_back(detectionScores);
131     expectedOutputs.push_back(numDetections);
132
133     return std::make_unique<MobileNetSsdTestCaseData>(imageData, testCaseInput.second, expectedOutputs);
134 }
135
136 } // anonymous namespace