42 void validate_models(
const std::vector<HOGInfo> &models)
46 for(
size_t i = 1; i < models.size(); ++i)
49 "All HOG parameters must have the same phase type");
52 "All HOG parameters must have the same normalization_type");
55 "All HOG parameters must have the same l2 hysteresis threshold if you use L2 hysteresis normalization type");
62 const size_t num_candidates = multi_windows.size();
63 size_t num_detections = 0;
78 if(lhs.
score > rhs.score)
82 if(rhs.score > lhs.
score)
90 const float min_distance_pow2 = min_distance * min_distance;
93 for(
size_t i = 0; i < num_candidates; ++i)
95 if(0.0f != multi_windows.at(i).score)
98 cur.
x = multi_windows.at(i).x;
99 cur.
y = multi_windows.at(i).y;
100 cur.
width = multi_windows.at(i).width;
101 cur.
height = multi_windows.at(i).height;
102 cur.
idx_class = multi_windows.at(i).idx_class;
103 cur.
score = multi_windows.at(i).score;
106 multi_windows.at(num_detections) = cur;
109 const float xc = cur.
x + cur.
width * 0.5f;
110 const float yc = cur.
y + cur.
height * 0.5f;
112 for(
size_t k = i + 1; k < (num_candidates) && (cur.
idx_class == multi_windows.at(k).idx_class); ++k)
114 const float xn = multi_windows.at(k).x + multi_windows.at(k).width * 0.5f;
115 const float yn = multi_windows.at(k).y + multi_windows.at(k).height * 0.5f;
117 const float dx = std::fabs(xn - xc);
118 const float dy = std::fabs(yn - yc);
120 if(dx < min_distance && dy < min_distance)
122 const float d = dx * dx + dy * dy;
124 if(d < min_distance_pow2)
127 multi_windows.at(k).score = 0.0f;
134 multi_windows.resize(num_detections);
137 template <
typename T>
139 const std::vector<HOGInfo> &models, std::vector<std::vector<float>> descriptors,
143 validate_models(models);
145 const size_t width = src.
shape().x();
146 const size_t height = src.
shape().y();
147 const size_t num_models = models.size();
150 size_t prev_num_bins = models[0].num_bins();
151 Size2D prev_cell_size = models[0].cell_size();
152 Size2D prev_block_size = models[0].block_size();
153 Size2D prev_block_stride = models[0].block_stride();
155 std::vector<size_t> input_orient_bin;
156 std::vector<size_t> input_hog_detect;
157 std::vector<std::pair<size_t, size_t>> input_block_norm;
159 input_orient_bin.push_back(0);
160 input_hog_detect.push_back(0);
161 input_block_norm.emplace_back(0, 0);
165 for(
size_t i = 1; i < num_models; ++i)
167 size_t cur_num_bins = models[i].num_bins();
168 Size2D cur_cell_size = models[i].cell_size();
169 Size2D cur_block_size = models[i].block_size();
170 Size2D cur_block_stride = models[i].block_stride();
173 if((cur_num_bins != prev_num_bins) || (cur_cell_size.
width != prev_cell_size.
width) || (cur_cell_size.
height != prev_cell_size.
height))
175 prev_num_bins = cur_num_bins;
176 prev_cell_size = cur_cell_size;
177 prev_block_size = cur_block_size;
178 prev_block_stride = cur_block_stride;
181 input_orient_bin.push_back(i);
182 input_block_norm.emplace_back(i, input_orient_bin.size() - 1);
184 else if((cur_block_size.
width != prev_block_size.
width) || (cur_block_size.
height != prev_block_size.
height) || (cur_block_stride.
width != prev_block_stride.
width)
185 || (cur_block_stride.
height != prev_block_stride.
height))
187 prev_block_size = cur_block_size;
188 prev_block_stride = cur_block_stride;
191 input_block_norm.emplace_back(i, input_orient_bin.size() - 1);
195 input_hog_detect.push_back(input_block_norm.size() - 1);
198 size_t num_orient_bin = input_orient_bin.size();
199 size_t num_block_norm = input_block_norm.size();
200 size_t num_hog_detect = input_hog_detect.size();
202 std::vector<SimpleTensor<float>> hog_spaces(num_orient_bin);
203 std::vector<SimpleTensor<float>> hog_norm_spaces(num_block_norm);
215 for(
size_t i = 0; i < num_orient_bin; ++i)
217 const size_t idx_multi_hog = input_orient_bin[i];
219 const size_t num_bins = models[idx_multi_hog].num_bins();
220 const size_t num_cells_x = width / models[idx_multi_hog].cell_size().width;
221 const size_t num_cells_y = height / models[idx_multi_hog].cell_size().height;
224 TensorShape hog_space_shape(num_cells_x, num_cells_y);
235 for(
size_t i = 0; i < num_block_norm; ++i)
237 const size_t idx_multi_hog = input_block_norm[i].first;
238 const size_t idx_orient_bin = input_block_norm[i].second;
241 TensorInfo tensor_info(models[idx_multi_hog], src.shape().x(), src.shape().y());
248 std::vector<DetectionWindow> multi_windows;
251 for(
size_t i = 0; i < num_hog_detect; ++i)
253 const size_t idx_block_norm = input_hog_detect[i];
256 const Size2D detection_window_stride = models[i].block_stride();
258 std::vector<DetectionWindow> windows =
hog_detector(hog_norm_spaces[idx_block_norm], descriptors[i],
259 max_num_detection_windows, models[i], detection_window_stride, threshold, i);
261 multi_windows.insert(multi_windows.end(), windows.begin(), windows.end());
265 if(non_maxima_suppression)
270 return multi_windows;
274 const std::vector<HOGInfo> &models, std::vector<std::vector<float>> descriptors,
BorderMode
Methods available to handle borders.
L2-norm followed by clipping.
uint16_t x
Top-left x coordinate.
float score
Confidence value for the detection window.
size_t num_channels() const override
The number of channels for each tensor element.
void hog_orientation_binning(const SimpleTensor< T > &mag, const SimpleTensor< U > &phase, SimpleTensor< V > &hog_space, const HOGInfo &hog_info)
1 channel, 1 F32 per channel
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
SimpleTensor< uint8_t > phase(const SimpleTensor< T > &gx, const SimpleTensor< T > &gy, PhaseType phase_type)
TensorShape shape() const override
Shape of the tensor.
This file contains all available output stages for GEMMLowp on OpenCL.
size_t height
Height of the image region or rectangle.
uint16_t width
Width of the detection window.
uint16_t idx_class
Index of the class.
uint16_t height
Height of the detection window.
Simple tensor object that stores elements in a consecutive chunk of memory.
std::vector< DetectionWindow > hog_detector(const SimpleTensor< T > &src, const std::vector< T > &descriptor, unsigned int max_num_detection_windows, const HOGInfo &hog_info, const Size2D &detection_window_stride, float threshold, uint16_t idx_class)
x and y gradient dimension
size_t width
Width of the image region or rectangle.
SimpleTensor< T > non_maxima_suppression(const SimpleTensor< T > &src, BorderMode border_mode, T constant_border_value)
Class for specifying the size of an image or rectangle.
Detection window used for the object detection.
uint16_t y
Top-left y coordinate.
Store the tensor's metadata.
void detection_windows_non_maxima_suppression(std::vector< DetectionWindow > &multi_windows, float min_distance)
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
SimpleTensor< T > threshold(const SimpleTensor< T > &src, T threshold, T false_value, T true_value, ThresholdType type, T upper)
SimpleTensor< T > magnitude(const SimpleTensor< T > &gx, const SimpleTensor< T > &gy, MagnitudeType magnitude_type)
convolution configure & src
std::vector< DetectionWindow > hog_multi_detection(const SimpleTensor< T > &src, BorderMode border_mode, T constant_border_value, const std::vector< HOGInfo > &models, std::vector< std::vector< float >> descriptors, unsigned int max_num_detection_windows, float threshold, bool non_maxima_suppression, float min_distance)
#define ARM_COMPUTE_ERROR_ON_MSG(cond,...)
void hog_block_normalization(SimpleTensor< T > &desc, const SimpleTensor< T > &hog_space, const HOGInfo &hog_info)