40 #include <pcl/pcl_base.h>
41 #include <pcl/point_cloud.h>
44 #include <pcl/recognition/dot_modality.h>
45 #include <pcl/recognition/point_types.h>
46 #include <pcl/recognition/quantized_map.h>
51 template <
typename Po
intInT>
81 gradient_magnitude_threshold_ = threshold;
93 return (dominant_quantized_color_gradients_);
125 std::size_t bin_size_;
127 float gradient_magnitude_threshold_;
138 template <
typename Po
intInT>
141 : bin_size_ (bin_size), gradient_magnitude_threshold_ (80.0f), color_gradients_ (), dominant_quantized_color_gradients_ ()
146 template <
typename Po
intInT>
153 template <
typename Po
intInT>
159 computeMaxColorGradients ();
162 computeDominantQuantizedGradients ();
169 template <
typename Po
intInT>
174 const int width = input_->width;
175 const int height = input_->height;
177 color_gradients_.resize (width*height);
178 color_gradients_.width = width;
179 color_gradients_.height = height;
181 constexpr
float pi = std::tan(1.0f)*4;
182 for (
int row_index = 0; row_index < height-2; ++row_index)
184 for (
int col_index = 0; col_index < width-2; ++col_index)
186 const int index0 = row_index*width+col_index;
187 const int index_c = row_index*width+col_index+2;
188 const int index_r = (row_index+2)*width+col_index;
190 const unsigned char r0 = (*input_)[index0].r;
191 const unsigned char g0 = (*input_)[index0].g;
192 const unsigned char b0 = (*input_)[index0].b;
194 const unsigned char r_c = (*input_)[index_c].r;
195 const unsigned char g_c = (*input_)[index_c].g;
196 const unsigned char b_c = (*input_)[index_c].b;
198 const unsigned char r_r = (*input_)[index_r].r;
199 const unsigned char g_r = (*input_)[index_r].g;
200 const unsigned char b_r = (*input_)[index_r].b;
202 const float r_dx =
static_cast<float> (r_c) -
static_cast<float> (r0);
203 const float g_dx =
static_cast<float> (g_c) -
static_cast<float> (g0);
204 const float b_dx =
static_cast<float> (b_c) -
static_cast<float> (b0);
206 const float r_dy =
static_cast<float> (r_r) -
static_cast<float> (r0);
207 const float g_dy =
static_cast<float> (g_r) -
static_cast<float> (g0);
208 const float b_dy =
static_cast<float> (b_r) -
static_cast<float> (b0);
210 const float sqr_mag_r = r_dx*r_dx + r_dy*r_dy;
211 const float sqr_mag_g = g_dx*g_dx + g_dy*g_dy;
212 const float sqr_mag_b = b_dx*b_dx + b_dy*b_dy;
215 gradient.
x = col_index;
216 gradient.
y = row_index;
217 if (sqr_mag_r > sqr_mag_g && sqr_mag_r > sqr_mag_b)
220 gradient.
angle = std::atan2 (r_dy, r_dx) * 180.0f / pi;
222 else if (sqr_mag_g > sqr_mag_b)
225 gradient.
angle = std::atan2 (g_dy, g_dx) * 180.0f / pi;
230 gradient.
angle = std::atan2 (b_dy, b_dx) * 180.0f / pi;
233 assert (color_gradients_ (col_index+1, row_index+1).angle >= -180 &&
234 color_gradients_ (col_index+1, row_index+1).angle <= 180);
236 color_gradients_ (col_index+1, row_index+1) = gradient;
244 template <
typename Po
intInT>
249 const std::size_t input_width = input_->width;
250 const std::size_t input_height = input_->height;
252 const std::size_t output_width = input_width / bin_size_;
253 const std::size_t output_height = input_height / bin_size_;
255 dominant_quantized_color_gradients_.resize (output_width, output_height);
257 constexpr std::size_t num_gradient_bins = 7;
259 constexpr
float divisor = 180.0f / (num_gradient_bins - 1.0f);
261 unsigned char * peak_pointer = dominant_quantized_color_gradients_.getData ();
262 memset (peak_pointer, 0, output_width*output_height);
264 for (std::size_t row_bin_index = 0; row_bin_index < output_height; ++row_bin_index)
266 for (std::size_t col_bin_index = 0; col_bin_index < output_width; ++col_bin_index)
268 const std::size_t x_position = col_bin_index * bin_size_;
269 const std::size_t y_position = row_bin_index * bin_size_;
271 float max_gradient = 0.0f;
272 std::size_t max_gradient_pos_x = 0;
273 std::size_t max_gradient_pos_y = 0;
276 for (std::size_t row_sub_index = 0; row_sub_index < bin_size_; ++row_sub_index)
278 for (std::size_t col_sub_index = 0; col_sub_index < bin_size_; ++col_sub_index)
280 const float magnitude = color_gradients_ (col_sub_index + x_position, row_sub_index + y_position).magnitude;
282 if (magnitude > max_gradient)
284 max_gradient = magnitude;
285 max_gradient_pos_x = col_sub_index;
286 max_gradient_pos_y = row_sub_index;
291 if (max_gradient >= gradient_magnitude_threshold_)
293 const std::size_t angle =
static_cast<std::size_t
> (180 + color_gradients_ (max_gradient_pos_x + x_position, max_gradient_pos_y + y_position).angle + 0.5f);
294 const std::size_t bin_index =
static_cast<std::size_t
> ((angle >= 180 ? angle-180 : angle)/divisor);
296 *peak_pointer |= 1 << bin_index;
299 if (*peak_pointer == 0)
301 *peak_pointer |= 1 << 7;
310 template <
typename Po
intInT>
316 const std::size_t input_width = input_->width;
317 const std::size_t input_height = input_->height;
319 const std::size_t output_width = input_width / bin_size_;
320 const std::size_t output_height = input_height / bin_size_;
322 const std::size_t sub_start_x = region.
x / bin_size_;
323 const std::size_t sub_start_y = region.
y / bin_size_;
324 const std::size_t sub_width = region.
width / bin_size_;
325 const std::size_t sub_height = region.
height / bin_size_;
328 map.
resize (sub_width, sub_height);
330 constexpr std::size_t num_gradient_bins = 7;
331 constexpr std::size_t max_num_of_gradients = 7;
333 const float divisor = 180.0f / (num_gradient_bins - 1.0f);
335 float global_max_gradient = 0.0f;
336 float local_max_gradient = 0.0f;
338 unsigned char * peak_pointer = map.
getData ();
340 for (std::size_t row_bin_index = 0; row_bin_index < sub_height; ++row_bin_index)
342 for (std::size_t col_bin_index = 0; col_bin_index < sub_width; ++col_bin_index)
344 std::vector<std::size_t> x_coordinates;
345 std::vector<std::size_t> y_coordinates;
346 std::vector<float> values;
348 for (
int row_pixel_index = -
static_cast<int> (bin_size_)/2;
349 row_pixel_index <= static_cast<int> (bin_size_)/2;
350 row_pixel_index +=
static_cast<int> (bin_size_)/2)
352 const std::size_t y_position = row_pixel_index + (sub_start_y + row_bin_index)*bin_size_;
354 if (y_position < 0 || y_position >= input_height)
357 for (
int col_pixel_index = -
static_cast<int> (bin_size_)/2;
358 col_pixel_index <= static_cast<int> (bin_size_)/2;
359 col_pixel_index +=
static_cast<int> (bin_size_)/2)
361 const std::size_t x_position = col_pixel_index + (sub_start_x + col_bin_index)*bin_size_;
362 std::size_t counter = 0;
364 if (x_position < 0 || x_position >= input_width)
369 local_max_gradient = 0.0f;
370 for (std::size_t row_sub_index = 0; row_sub_index < bin_size_; ++row_sub_index)
372 for (std::size_t col_sub_index = 0; col_sub_index < bin_size_; ++col_sub_index)
374 const float magnitude = color_gradients_ (col_sub_index + x_position, row_sub_index + y_position).magnitude;
376 if (magnitude > local_max_gradient)
377 local_max_gradient = magnitude;
382 if (local_max_gradient > global_max_gradient)
384 global_max_gradient = local_max_gradient;
391 std::size_t max_gradient_pos_x;
392 std::size_t max_gradient_pos_y;
397 for (std::size_t row_sub_index = 0; row_sub_index < bin_size_; ++row_sub_index)
399 for (std::size_t col_sub_index = 0; col_sub_index < bin_size_; ++col_sub_index)
401 const float magnitude = color_gradients_ (col_sub_index + x_position, row_sub_index + y_position).magnitude;
403 if (magnitude > max_gradient)
405 max_gradient = magnitude;
406 max_gradient_pos_x = col_sub_index;
407 max_gradient_pos_y = row_sub_index;
414 if (local_max_gradient < gradient_magnitude_threshold_)
422 counter >= max_num_of_gradients)
429 const std::size_t angle =
static_cast<std::size_t
> (180 + color_gradients_ (max_gradient_pos_x + x_position, max_gradient_pos_y + y_position).angle + 0.5f);
430 const std::size_t bin_index =
static_cast<std::size_t
> ((angle >= 180 ? angle-180 : angle)/divisor);
432 *peak_pointer |= 1 << bin_index;
434 x_coordinates.push_back (max_gradient_pos_x + x_position);
435 y_coordinates.push_back (max_gradient_pos_y + y_position);
436 values.push_back (max_gradient);
438 color_gradients_ (max_gradient_pos_x + x_position, max_gradient_pos_y + y_position).magnitude = -1.0f;
442 for (std::size_t value_index = 0; value_index < values.size (); ++value_index)
444 color_gradients_ (x_coordinates[value_index], y_coordinates[value_index]).magnitude = values[value_index];
447 x_coordinates.clear ();
448 y_coordinates.clear ();
453 if (*peak_pointer == 0)
455 *peak_pointer |= 1 << 7;