• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
38 namespace arm_compute
39 {
40 namespace test
41 {
42 namespace validation
43 {
44 template <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>
56 class HOGMultiDetectionValidationFixture : public framework::Fixture
57 {
58 public:
59     template <typename...>
setup(std::string image,std::vector<HOGInfo> models,Format format,BorderMode border_mode,bool non_maxima_suppression)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 
84 protected:
85     template <typename V>
fill(V && tensor,const std::string image,Format format)86     void fill(V &&tensor, const std::string image, Format format)
87     {
88         library->fill(tensor, image, format);
89     }
90 
initialize_batch(const std::vector<HOGInfo> & models,MultiHOGType & multi_hog,std::vector<std::vector<U>> & descriptors,DetectionWindowStrideType & detection_window_strides)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 
compute_target(const std::string image,Format & format,BorderMode & border_mode,T constant_border_value,const std::vector<HOGInfo> & models,std::vector<std::vector<U>> & descriptors,unsigned int max_num_detection_windows,float threshold,bool non_max_suppression,float min_distance)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 
compute_reference(const std::string image,Format format,BorderMode border_mode,T constant_border_value,const std::vector<HOGInfo> & models,const std::vector<std::vector<U>> & descriptors,unsigned int max_num_detection_windows,float threshold,bool non_max_suppression,float min_distance)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 */
194