blob: 039f3f4b745be03a71bdbae56404caf41873237e [file] [log] [blame]
John Richardson7f4a8192018-02-05 15:12:22 +00001/*
2 * Copyright (c) 2018 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef ARM_COMPUTE_TEST_HOG_MULTI_DETECTION_FIXTURE
25#define ARM_COMPUTE_TEST_HOG_MULTI_DETECTION_FIXTURE
26
27#include "arm_compute/core/HOGInfo.h"
28#include "arm_compute/core/TensorShape.h"
29#include "arm_compute/core/Types.h"
30#include "tests/AssetsLibrary.h"
31#include "tests/Globals.h"
32#include "tests/IAccessor.h"
33#include "tests/IHOGAccessor.h"
34#include "tests/framework/Asserts.h"
35#include "tests/framework/Fixture.h"
36#include "tests/validation/reference/HOGMultiDetection.h"
37
38namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
44template <typename TensorType,
45 typename HOGType,
46 typename MultiHOGType,
47 typename DetectionWindowArrayType,
48 typename DetectionWindowStrideType,
49 typename AccessorType,
50 typename Size2DArrayAccessorType,
51 typename DetectionWindowArrayAccessorType,
52 typename HOGAccessorType,
53 typename FunctionType,
54 typename T,
55 typename U>
56class HOGMultiDetectionValidationFixture : public framework::Fixture
57{
58public:
59 template <typename...>
60 void setup(std::string image, std::vector<HOGInfo> models, Format format, BorderMode border_mode, bool non_maxima_suppression)
61 {
62 // Only defined borders supported
63 ARM_COMPUTE_ERROR_ON(border_mode == BorderMode::UNDEFINED);
64
65 // Generate a random constant value
66 std::mt19937 gen(library->seed());
67 std::uniform_int_distribution<T> int_dist(0, 255);
68 const T constant_border_value = int_dist(gen);
69
70 // Initialize descriptors vector
71 std::vector<std::vector<U>> descriptors(models.size());
72
73 // Use default values for threshold and min_distance
74 const float threshold = 0.f;
75 const float min_distance = 1.f;
76
77 // Maximum number of detection windows per batch
78 const unsigned int max_num_detection_windows = 100000;
79
80 _target = compute_target(image, format, border_mode, constant_border_value, models, descriptors, max_num_detection_windows, threshold, non_maxima_suppression, min_distance);
81 _reference = compute_reference(image, format, border_mode, constant_border_value, models, descriptors, max_num_detection_windows, threshold, non_maxima_suppression, min_distance);
82 }
83
84protected:
85 template <typename V>
86 void fill(V &&tensor, const std::string image, Format format)
87 {
88 library->fill(tensor, image, format);
89 }
90
91 void initialize_batch(const std::vector<HOGInfo> &models, MultiHOGType &multi_hog,
92 std::vector<std::vector<U>> &descriptors, DetectionWindowStrideType &detection_window_strides)
93 {
94 for(unsigned i = 0; i < models.size(); ++i)
95 {
96 auto hog_model = reinterpret_cast<HOGType *>(multi_hog.model(i));
97 hog_model->init(models[i]);
98
99 // Initialise descriptor (linear SVM coefficients).
100 std::random_device::result_type seed = 0;
101 descriptors.at(i) = generate_random_real(models[i].descriptor_size(), -0.505f, 0.495f, seed);
102
103 // Copy HOG descriptor values to HOG memory
104 {
105 HOGAccessorType hog_accessor(*hog_model);
106 std::memcpy(hog_accessor.descriptor(), descriptors.at(i).data(), descriptors.at(i).size() * sizeof(U));
107 }
108
109 // Initialize detection window stride
110 Size2DArrayAccessorType accessor(detection_window_strides);
111 accessor.at(i) = models[i].block_stride();
112 }
113 }
114
115 std::vector<DetectionWindow> compute_target(const std::string image, Format &format, BorderMode &border_mode, T constant_border_value,
116 const std::vector<HOGInfo> &models, std::vector<std::vector<U>> &descriptors, unsigned int max_num_detection_windows,
117 float threshold, bool non_max_suppression, float min_distance)
118 {
119 MultiHOGType multi_hog(models.size());
120 DetectionWindowArrayType detection_windows(max_num_detection_windows);
121 DetectionWindowStrideType detection_window_strides(models.size());
122
123 // Resize detection window_strides for index access
124 detection_window_strides.resize(models.size());
125
126 // Initialiize MultiHOG and detection windows
127 initialize_batch(models, multi_hog, descriptors, detection_window_strides);
128
129 // Get image shape for src tensor
130 TensorShape shape = library->get_image_shape(image);
131
132 // Create tensors
133 TensorType src = create_tensor<TensorType>(shape, data_type_from_format(format));
134 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
135
136 // Create and configure function
137 FunctionType hog_multi_detection;
138 hog_multi_detection.configure(&src, &multi_hog, &detection_windows, &detection_window_strides, border_mode, constant_border_value, threshold, non_max_suppression, min_distance);
139
140 // Reset detection windows
141 detection_windows.clear();
142
143 // Allocate tensors
144 src.allocator()->allocate();
145 ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
146
147 // Fill tensors
148 fill(AccessorType(src), image, format);
149
150 // Compute function
151 hog_multi_detection.run();
152
153 // Copy detection windows
154 std::vector<DetectionWindow> windows;
155 DetectionWindowArrayAccessorType accessor(detection_windows);
156
157 for(size_t i = 0; i < accessor.num_values(); i++)
158 {
159 DetectionWindow win;
160 win.x = accessor.at(i).x;
161 win.y = accessor.at(i).y;
162 win.width = accessor.at(i).width;
163 win.height = accessor.at(i).height;
164 win.idx_class = accessor.at(i).idx_class;
165 win.score = accessor.at(i).score;
166
167 windows.push_back(win);
168 }
169
170 return windows;
171 }
172
173 std::vector<DetectionWindow> compute_reference(const std::string image, Format format, BorderMode border_mode, T constant_border_value,
174 const std::vector<HOGInfo> &models, const std::vector<std::vector<U>> &descriptors, unsigned int max_num_detection_windows,
175 float threshold, bool non_max_suppression, float min_distance)
176 {
177 // Create reference
178 SimpleTensor<T> src{ library->get_image_shape(image), data_type_from_format(format) };
179
180 // Fill reference
181 fill(src, image, format);
182
183 // NOTE: Detection window stride fixed to block stride
184 return reference::hog_multi_detection(src, border_mode, constant_border_value, models, descriptors, max_num_detection_windows, threshold, non_max_suppression, min_distance);
185 }
186
187 std::vector<DetectionWindow> _target{};
188 std::vector<DetectionWindow> _reference{};
189};
190} // namespace validation
191} // namespace test
192} // namespace arm_compute
193#endif /* ARM_COMPUTE_TEST_HOG_MULTI_DETECTION_FIXTURE */