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>
152 computeMaxColorGradients ();
155 computeDominantQuantizedGradients ();
162 template <
typename Po
intInT>
167 const int width = input_->width;
168 const int height = input_->height;
170 color_gradients_.resize (width*height);
171 color_gradients_.width = width;
172 color_gradients_.height = height;
174 constexpr
float pi = std::tan(1.0f)*4;
175 for (
int row_index = 0; row_index < height-2; ++row_index)
177 for (
int col_index = 0; col_index < width-2; ++col_index)
179 const int index0 = row_index*width+col_index;
180 const int index_c = row_index*width+col_index+2;
181 const int index_r = (row_index+2)*width+col_index;
183 const unsigned char r0 = (*input_)[index0].r;
184 const unsigned char g0 = (*input_)[index0].g;
185 const unsigned char b0 = (*input_)[index0].b;
187 const unsigned char r_c = (*input_)[index_c].r;
188 const unsigned char g_c = (*input_)[index_c].g;
189 const unsigned char b_c = (*input_)[index_c].b;
191 const unsigned char r_r = (*input_)[index_r].r;
192 const unsigned char g_r = (*input_)[index_r].g;
193 const unsigned char b_r = (*input_)[index_r].b;
195 const float r_dx =
static_cast<float> (r_c) -
static_cast<float> (r0);
196 const float g_dx =
static_cast<float> (g_c) -
static_cast<float> (g0);
197 const float b_dx =
static_cast<float> (b_c) -
static_cast<float> (b0);
199 const float r_dy =
static_cast<float> (r_r) -
static_cast<float> (r0);
200 const float g_dy =
static_cast<float> (g_r) -
static_cast<float> (g0);
201 const float b_dy =
static_cast<float> (b_r) -
static_cast<float> (b0);
203 const float sqr_mag_r = r_dx*r_dx + r_dy*r_dy;
204 const float sqr_mag_g = g_dx*g_dx + g_dy*g_dy;
205 const float sqr_mag_b = b_dx*b_dx + b_dy*b_dy;
208 gradient.
x = col_index;
209 gradient.
y = row_index;
210 if (sqr_mag_r > sqr_mag_g && sqr_mag_r > sqr_mag_b)
213 gradient.
angle = std::atan2 (r_dy, r_dx) * 180.0f / pi;
215 else if (sqr_mag_g > sqr_mag_b)
218 gradient.
angle = std::atan2 (g_dy, g_dx) * 180.0f / pi;
223 gradient.
angle = std::atan2 (b_dy, b_dx) * 180.0f / pi;
226 assert (color_gradients_ (col_index+1, row_index+1).angle >= -180 &&
227 color_gradients_ (col_index+1, row_index+1).angle <= 180);
229 color_gradients_ (col_index+1, row_index+1) = gradient;
237 template <
typename Po
intInT>
242 const std::size_t input_width = input_->width;
243 const std::size_t input_height = input_->height;
245 const std::size_t output_width = input_width / bin_size_;
246 const std::size_t output_height = input_height / bin_size_;
248 dominant_quantized_color_gradients_.resize (output_width, output_height);
250 constexpr std::size_t num_gradient_bins = 7;
252 constexpr
float divisor = 180.0f / (num_gradient_bins - 1.0f);
254 unsigned char * peak_pointer = dominant_quantized_color_gradients_.getData ();
255 std::fill_n(peak_pointer, output_width*output_height, 0);
257 for (std::size_t row_bin_index = 0; row_bin_index < output_height; ++row_bin_index)
259 for (std::size_t col_bin_index = 0; col_bin_index < output_width; ++col_bin_index)
261 const std::size_t x_position = col_bin_index * bin_size_;
262 const std::size_t y_position = row_bin_index * bin_size_;
264 float max_gradient = 0.0f;
265 std::size_t max_gradient_pos_x = 0;
266 std::size_t max_gradient_pos_y = 0;
269 for (std::size_t row_sub_index = 0; row_sub_index < bin_size_; ++row_sub_index)
271 for (std::size_t col_sub_index = 0; col_sub_index < bin_size_; ++col_sub_index)
273 const float magnitude = color_gradients_ (col_sub_index + x_position, row_sub_index + y_position).magnitude;
275 if (magnitude > max_gradient)
277 max_gradient = magnitude;
278 max_gradient_pos_x = col_sub_index;
279 max_gradient_pos_y = row_sub_index;
284 if (max_gradient >= gradient_magnitude_threshold_)
286 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);
287 const std::size_t bin_index =
static_cast<std::size_t
> ((angle >= 180 ? angle-180 : angle)/divisor);
289 *peak_pointer |= 1 << bin_index;
292 if (*peak_pointer == 0)
294 *peak_pointer |= 1 << 7;
303 template <
typename Po
intInT>
309 const std::size_t input_width = input_->width;
310 const std::size_t input_height = input_->height;
312 const std::size_t output_width = input_width / bin_size_;
313 const std::size_t output_height = input_height / bin_size_;
315 const std::size_t sub_start_x = region.
x / bin_size_;
316 const std::size_t sub_start_y = region.
y / bin_size_;
317 const std::size_t sub_width = region.
width / bin_size_;
318 const std::size_t sub_height = region.
height / bin_size_;
321 map.
resize (sub_width, sub_height);
323 constexpr std::size_t num_gradient_bins = 7;
324 constexpr std::size_t max_num_of_gradients = 7;
326 const float divisor = 180.0f / (num_gradient_bins - 1.0f);
328 float global_max_gradient = 0.0f;
329 float local_max_gradient = 0.0f;
331 unsigned char * peak_pointer = map.
getData ();
333 for (std::size_t row_bin_index = 0; row_bin_index < sub_height; ++row_bin_index)
335 for (std::size_t col_bin_index = 0; col_bin_index < sub_width; ++col_bin_index)
337 std::vector<std::size_t> x_coordinates;
338 std::vector<std::size_t> y_coordinates;
339 std::vector<float> values;
341 for (
int row_pixel_index = -
static_cast<int> (bin_size_)/2;
342 row_pixel_index <= static_cast<int> (bin_size_)/2;
343 row_pixel_index +=
static_cast<int> (bin_size_)/2)
345 const std::size_t y_position = row_pixel_index + (sub_start_y + row_bin_index)*bin_size_;
347 if (y_position < 0 || y_position >= input_height)
350 for (
int col_pixel_index = -
static_cast<int> (bin_size_)/2;
351 col_pixel_index <= static_cast<int> (bin_size_)/2;
352 col_pixel_index +=
static_cast<int> (bin_size_)/2)
354 const std::size_t x_position = col_pixel_index + (sub_start_x + col_bin_index)*bin_size_;
355 std::size_t counter = 0;
357 if (x_position < 0 || x_position >= input_width)
362 local_max_gradient = 0.0f;
363 for (std::size_t row_sub_index = 0; row_sub_index < bin_size_; ++row_sub_index)
365 for (std::size_t col_sub_index = 0; col_sub_index < bin_size_; ++col_sub_index)
367 const float magnitude = color_gradients_ (col_sub_index + x_position, row_sub_index + y_position).magnitude;
369 if (magnitude > local_max_gradient)
370 local_max_gradient = magnitude;
375 if (local_max_gradient > global_max_gradient)
377 global_max_gradient = local_max_gradient;
384 std::size_t max_gradient_pos_x;
385 std::size_t max_gradient_pos_y;
390 for (std::size_t row_sub_index = 0; row_sub_index < bin_size_; ++row_sub_index)
392 for (std::size_t col_sub_index = 0; col_sub_index < bin_size_; ++col_sub_index)
394 const float magnitude = color_gradients_ (col_sub_index + x_position, row_sub_index + y_position).magnitude;
396 if (magnitude > max_gradient)
398 max_gradient = magnitude;
399 max_gradient_pos_x = col_sub_index;
400 max_gradient_pos_y = row_sub_index;
407 if (local_max_gradient < gradient_magnitude_threshold_)
415 counter >= max_num_of_gradients)
422 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);
423 const std::size_t bin_index =
static_cast<std::size_t
> ((angle >= 180 ? angle-180 : angle)/divisor);
425 *peak_pointer |= 1 << bin_index;
427 x_coordinates.push_back (max_gradient_pos_x + x_position);
428 y_coordinates.push_back (max_gradient_pos_y + y_position);
429 values.push_back (max_gradient);
431 color_gradients_ (max_gradient_pos_x + x_position, max_gradient_pos_y + y_position).magnitude = -1.0f;
435 for (std::size_t value_index = 0; value_index < values.size (); ++value_index)
437 color_gradients_ (x_coordinates[value_index], y_coordinates[value_index]).magnitude = values[value_index];
440 x_coordinates.clear ();
441 y_coordinates.clear ();
446 if (*peak_pointer == 0)
448 *peak_pointer |= 1 << 7;
ColorGradientDOTModality(std::size_t bin_size)
void computeMaxColorGradients()
QuantizedMap & getDominantQuantizedMap()
void setGradientMagnitudeThreshold(const float threshold)
QuantizedMap computeInvariantQuantizedMap(const MaskMap &mask, const RegionXY ®ion)
void computeDominantQuantizedGradients()
virtual ~ColorGradientDOTModality()=default
virtual void setInputCloud(const typename PointCloudIn::ConstPtr &cloud)
Provide a pointer to the input dataset (overwrites the PCLBase::setInputCloud method)
virtual void processInputData()
PointCloudConstPtr input_
The input point cloud dataset.
shared_ptr< const PointCloud< PointInT > > ConstPtr
unsigned char * getData()
void resize(std::size_t width, std::size_t height)
Defines all the PCL implemented PointT point type structures.
bool operator<(const Candidate &rhs)
A point structure representing Euclidean xyz coordinates, and the intensity value.
Defines a region in XY-space.
int x
x-position of the region.
int width
width of the region.
int y
y-position of the region.
int height
height of the region.