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