blob: 0c2219d2fc8d31cc6a6969fb9bd68c384983f6cb [file] [log] [blame]
Aron Virginas-Tard089b742019-01-29 11:09:51 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01005
Aron Virginas-Tard089b742019-01-29 11:09:51 +00006#pragma once
7
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01008#include "InferenceTestImage.hpp"
Aron Virginas-Tard089b742019-01-29 11:09:51 +00009#include "ObjectDetectionCommon.hpp"
10
Colm Donelanc42a9872022-02-02 16:35:09 +000011#include <armnnUtils/QuantizeHelper.hpp>
Aron Virginas-Tard089b742019-01-29 11:09:51 +000012
13#include <armnn/TypesUtils.hpp>
Matthew Sloyan80c6b142020-09-08 12:00:32 +010014#include <armnn/utility/NumericCast.hpp>
Aron Virginas-Tard089b742019-01-29 11:09:51 +000015
16#include <array>
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010017#include <memory>
Aron Virginas-Tard089b742019-01-29 11:09:51 +000018#include <string>
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010019#include <vector>
Aron Virginas-Tard089b742019-01-29 11:09:51 +000020
21namespace
22{
23
24struct MobileNetSsdTestCaseData
25{
26 MobileNetSsdTestCaseData(
Narumol Prangnawarat4628d052019-02-25 17:26:05 +000027 const std::vector<uint8_t>& inputData,
28 const std::vector<DetectedObject>& expectedDetectedObject,
29 const std::vector<std::vector<float>>& expectedOutput)
30 : m_InputData(inputData)
31 , m_ExpectedDetectedObject(expectedDetectedObject)
32 , m_ExpectedOutput(expectedOutput)
Aron Virginas-Tard089b742019-01-29 11:09:51 +000033 {}
34
Narumol Prangnawarat4628d052019-02-25 17:26:05 +000035 std::vector<uint8_t> m_InputData;
36 std::vector<DetectedObject> m_ExpectedDetectedObject;
37 std::vector<std::vector<float>> m_ExpectedOutput;
Aron Virginas-Tard089b742019-01-29 11:09:51 +000038};
39
40class MobileNetSsdDatabase
41{
42public:
Narumol Prangnawaratc8bab1b2019-02-15 17:34:51 +000043 explicit MobileNetSsdDatabase(const std::string& imageDir, float scale, int offset);
Aron Virginas-Tard089b742019-01-29 11:09:51 +000044
45 std::unique_ptr<MobileNetSsdTestCaseData> GetTestCaseData(unsigned int testCaseId);
46
47private:
48 std::string m_ImageDir;
Narumol Prangnawaratc8bab1b2019-02-15 17:34:51 +000049 float m_Scale;
50 int m_Offset;
Aron Virginas-Tard089b742019-01-29 11:09:51 +000051};
52
53constexpr unsigned int k_MobileNetSsdImageWidth = 300u;
54constexpr unsigned int k_MobileNetSsdImageHeight = k_MobileNetSsdImageWidth;
55
56// Test cases
57const std::array<ObjectDetectionInput, 1> g_PerTestCaseInput =
58{
59 ObjectDetectionInput
60 {
61 "Cat.jpg",
Narumol Prangnawarat4628d052019-02-25 17:26:05 +000062 {
Narumol Prangnawarat713e95c2019-06-20 17:08:03 +010063 DetectedObject(16.0f, BoundingBox(0.216785252f, 0.079726994f, 0.927124202f, 0.939067304f), 0.79296875f)
Narumol Prangnawarat4628d052019-02-25 17:26:05 +000064 }
Aron Virginas-Tard089b742019-01-29 11:09:51 +000065 }
66};
67
Narumol Prangnawaratc8bab1b2019-02-15 17:34:51 +000068MobileNetSsdDatabase::MobileNetSsdDatabase(const std::string& imageDir, float scale, int offset)
Aron Virginas-Tard089b742019-01-29 11:09:51 +000069 : m_ImageDir(imageDir)
Narumol Prangnawaratc8bab1b2019-02-15 17:34:51 +000070 , m_Scale(scale)
71 , m_Offset(offset)
Aron Virginas-Tard089b742019-01-29 11:09:51 +000072{}
73
74std::unique_ptr<MobileNetSsdTestCaseData> MobileNetSsdDatabase::GetTestCaseData(unsigned int testCaseId)
75{
76 const unsigned int safeTestCaseId =
Matthew Sloyan80c6b142020-09-08 12:00:32 +010077 testCaseId % armnn::numeric_cast<unsigned int>(g_PerTestCaseInput.size());
Aron Virginas-Tard089b742019-01-29 11:09:51 +000078 const ObjectDetectionInput& testCaseInput = g_PerTestCaseInput[safeTestCaseId];
79
80 // Load test case input
81 const std::string imagePath = m_ImageDir + testCaseInput.first;
Narumol Prangnawaratc8bab1b2019-02-15 17:34:51 +000082 std::vector<uint8_t> imageData;
Aron Virginas-Tard089b742019-01-29 11:09:51 +000083 try
84 {
85 InferenceTestImage image(imagePath.c_str());
86
87 // Resize image (if needed)
88 const unsigned int width = image.GetWidth();
89 const unsigned int height = image.GetHeight();
90 if (width != k_MobileNetSsdImageWidth || height != k_MobileNetSsdImageHeight)
91 {
92 image.Resize(k_MobileNetSsdImageWidth, k_MobileNetSsdImageHeight, CHECK_LOCATION());
93 }
94
95 // Get image data as a vector of floats
Narumol Prangnawaratc8bab1b2019-02-15 17:34:51 +000096 std::vector<float> floatImageData = GetImageDataAsNormalizedFloats(ImageChannelLayout::Rgb, image);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010097 imageData = armnnUtils::QuantizedVector<uint8_t>(floatImageData, m_Scale, m_Offset);
Aron Virginas-Tard089b742019-01-29 11:09:51 +000098 }
99 catch (const InferenceTestImageException& e)
100 {
Derek Lamberti08446972019-11-26 16:38:31 +0000101 ARMNN_LOG(fatal) << "Failed to load image for test case " << testCaseId << ". Error: " << e.what();
Aron Virginas-Tard089b742019-01-29 11:09:51 +0000102 return nullptr;
103 }
104
Narumol Prangnawarat4628d052019-02-25 17:26:05 +0000105 std::vector<float> numDetections = { static_cast<float>(testCaseInput.second.size()) };
Aron Virginas-Tard089b742019-01-29 11:09:51 +0000106
Narumol Prangnawarat4628d052019-02-25 17:26:05 +0000107 std::vector<float> detectionBoxes;
108 std::vector<float> detectionClasses;
109 std::vector<float> detectionScores;
110
111 for (DetectedObject expectedObject : testCaseInput.second)
112 {
113 detectionBoxes.push_back(expectedObject.m_BoundingBox.m_YMin);
114 detectionBoxes.push_back(expectedObject.m_BoundingBox.m_XMin);
115 detectionBoxes.push_back(expectedObject.m_BoundingBox.m_YMax);
116 detectionBoxes.push_back(expectedObject.m_BoundingBox.m_XMax);
117
118 detectionClasses.push_back(expectedObject.m_Class);
119
120 detectionScores.push_back(expectedObject.m_Confidence);
121 }
122
123 // Prepare test case expected output
124 std::vector<std::vector<float>> expectedOutputs;
125 expectedOutputs.reserve(4);
126 expectedOutputs.push_back(detectionBoxes);
127 expectedOutputs.push_back(detectionClasses);
128 expectedOutputs.push_back(detectionScores);
129 expectedOutputs.push_back(numDetections);
130
131 return std::make_unique<MobileNetSsdTestCaseData>(imageData, testCaseInput.second, expectedOutputs);
Aron Virginas-Tard089b742019-01-29 11:09:51 +0000132}
133
134} // anonymous namespace