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