38 #ifndef PCL_RECOGNITION_COLOR_GRADIENT_MODALITY
39 #define PCL_RECOGNITION_COLOR_GRADIENT_MODALITY
41 #include <pcl/recognition/quantizable_modality.h>
43 #include <pcl/pcl_base.h>
44 #include <pcl/point_cloud.h>
45 #include <pcl/point_types.h>
46 #include <pcl/recognition/point_types.h>
47 #include <pcl/filters/convolution.h>
57 template <
typename Po
intInT>
107 gradient_magnitude_threshold_ = threshold;
117 gradient_magnitude_threshold_feature_extraction_ = threshold;
126 feature_selection_method_ = method;
133 spreading_size_ = spreading_size;
142 variable_feature_nr_ = enabled;
149 return (filtered_quantized_color_gradients_);
156 return (spreaded_filtered_quantized_color_gradients_);
163 return (color_gradients_);
175 std::vector<QuantizedMultiModFeature> & features)
const;
185 std::vector<QuantizedMultiModFeature> & features)
const;
212 computeGaussianKernel (
const size_t kernel_size,
const float sigma, std::vector <float> & kernel_values);
244 bool variable_feature_nr_;
253 float gradient_magnitude_threshold_;
255 float gradient_magnitude_threshold_feature_extraction_;
261 size_t spreading_size_;
275 template <
typename Po
intInT>
278 : variable_feature_nr_ (false)
280 , feature_selection_method_ (DISTANCE_MAGNITUDE_SCORE)
281 , gradient_magnitude_threshold_ (10.0f)
282 , gradient_magnitude_threshold_feature_extraction_ (55.0f)
283 , color_gradients_ ()
284 , spreading_size_ (8)
285 , quantized_color_gradients_ ()
286 , filtered_quantized_color_gradients_ ()
287 , spreaded_filtered_quantized_color_gradients_ ()
292 template <
typename Po
intInT>
299 template <
typename Po
intInT>
void
304 const int n = int (kernel_size);
305 const int SMALL_GAUSSIAN_SIZE = 7;
306 static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] =
309 {0.25f, 0.5f, 0.25f},
310 {0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f},
311 {0.03125f, 0.109375f, 0.21875f, 0.28125f, 0.21875f, 0.109375f, 0.03125f}
314 const float* fixed_kernel = n % 2 == 1 && n <= SMALL_GAUSSIAN_SIZE && sigma <= 0 ?
315 small_gaussian_tab[n>>1] : 0;
319 kernel_values.resize (n);
320 float* cf = &(kernel_values[0]);
323 double sigmaX = sigma > 0 ? sigma : ((n-1)*0.5 - 1)*0.3 + 0.8;
324 double scale2X = -0.5/(sigmaX*sigmaX);
328 for( i = 0; i < n; i++ )
330 double x = i - (n-1)*0.5;
331 double t = fixed_kernel ? double (fixed_kernel[i]) : std::exp (scale2X*x*x);
338 for (i = 0; i < n; i++ )
340 cf[i] = float (cf[i]*sum);
345 template <
typename Po
intInT>
351 const size_t kernel_size = 7;
352 std::vector<float> kernel_values;
353 computeGaussianKernel (kernel_size, 0.0f, kernel_values);
357 Eigen::ArrayXf gaussian_kernel(kernel_size);
360 gaussian_kernel << kernel_values[0], kernel_values[1], kernel_values[2], kernel_values[3], kernel_values[4], kernel_values[5], kernel_values[6];
364 const uint32_t width = input_->width;
365 const uint32_t height = input_->height;
367 rgb_input_->
resize (width*height);
368 rgb_input_->
width = width;
369 rgb_input_->
height = height;
370 rgb_input_->
is_dense = input_->is_dense;
371 for (
size_t row_index = 0; row_index < height; ++row_index)
373 for (
size_t col_index = 0; col_index < width; ++col_index)
375 (*rgb_input_) (col_index, row_index).r = (*input_) (col_index, row_index).r;
376 (*rgb_input_) (col_index, row_index).g = (*input_) (col_index, row_index).g;
377 (*rgb_input_) (col_index, row_index).b = (*input_) (col_index, row_index).b;
384 convolution.
convolve (*smoothed_input_);
387 computeMaxColorGradientsSobel (smoothed_input_);
390 quantizeColorGradients ();
393 filterQuantizedColorGradients ();
398 spreaded_filtered_quantized_color_gradients_,
403 template <
typename Po
intInT>
411 spreaded_filtered_quantized_color_gradients_,
416 template <
typename Po
intInT>
419 std::vector<QuantizedMultiModFeature> & features)
const
421 const size_t width = mask.
getWidth ();
424 std::list<Candidate> list1;
425 std::list<Candidate> list2;
428 if (feature_selection_method_ == DISTANCE_MAGNITUDE_SCORE)
430 for (
size_t row_index = 0; row_index < height; ++row_index)
432 for (
size_t col_index = 0; col_index < width; ++col_index)
434 if (mask (col_index, row_index) != 0)
436 const GradientXY & gradient = color_gradients_ (col_index, row_index);
437 if (gradient.
magnitude > gradient_magnitude_threshold_feature_extraction_
438 && filtered_quantized_color_gradients_ (col_index, row_index) != 0)
442 candidate.
x =
static_cast<int> (col_index);
443 candidate.
y =
static_cast<int> (row_index);
445 list1.push_back (candidate);
453 if (variable_feature_nr_)
455 list2.push_back (*(list1.begin ()));
457 bool feature_selection_finished =
false;
458 while (!feature_selection_finished)
460 float best_score = 0.0f;
461 typename std::list<Candidate>::iterator best_iter = list1.end ();
462 for (
typename std::list<Candidate>::iterator iter1 = list1.begin (); iter1 != list1.end (); ++iter1)
465 float smallest_distance = std::numeric_limits<float>::max ();
466 for (
typename std::list<Candidate>::iterator iter2 = list2.begin (); iter2 != list2.end (); ++iter2)
468 const float dx =
static_cast<float> (iter1->x) - static_cast<float> (iter2->x);
469 const float dy =
static_cast<float> (iter1->y) - static_cast<float> (iter2->y);
471 const float distance = dx*dx + dy*dy;
473 if (distance < smallest_distance)
475 smallest_distance = distance;
479 const float score = smallest_distance * iter1->gradient.magnitude;
481 if (score > best_score)
489 float min_min_sqr_distance = std::numeric_limits<float>::max ();
490 float max_min_sqr_distance = 0;
491 for (
typename std::list<Candidate>::iterator iter2 = list2.begin (); iter2 != list2.end (); ++iter2)
493 float min_sqr_distance = std::numeric_limits<float>::max ();
494 for (
typename std::list<Candidate>::iterator iter3 = list2.begin (); iter3 != list2.end (); ++iter3)
499 const float dx =
static_cast<float> (iter2->x) - static_cast<float> (iter3->x);
500 const float dy =
static_cast<float> (iter2->y) - static_cast<float> (iter3->y);
502 const float sqr_distance = dx*dx + dy*dy;
504 if (sqr_distance < min_sqr_distance)
506 min_sqr_distance = sqr_distance;
515 const float dx =
static_cast<float> (iter2->x) - static_cast<float> (best_iter->x);
516 const float dy =
static_cast<float> (iter2->y) - static_cast<float> (best_iter->y);
518 const float sqr_distance = dx*dx + dy*dy;
520 if (sqr_distance < min_sqr_distance)
522 min_sqr_distance = sqr_distance;
526 if (min_sqr_distance < min_min_sqr_distance)
527 min_min_sqr_distance = min_sqr_distance;
528 if (min_sqr_distance > max_min_sqr_distance)
529 max_min_sqr_distance = min_sqr_distance;
534 if (best_iter != list1.end ())
540 if (min_min_sqr_distance < 50)
542 feature_selection_finished =
true;
546 list2.push_back (*best_iter);
552 if (list1.size () <= nr_features)
554 for (
typename std::list<Candidate>::iterator iter1 = list1.begin (); iter1 != list1.end (); ++iter1)
558 feature.
x = iter1->x;
559 feature.
y = iter1->y;
561 feature.
quantized_value = filtered_quantized_color_gradients_ (iter1->x, iter1->y);
563 features.push_back (feature);
568 list2.push_back (*(list1.begin ()));
569 while (list2.size () != nr_features)
571 float best_score = 0.0f;
572 typename std::list<Candidate>::iterator best_iter = list1.end ();
573 for (
typename std::list<Candidate>::iterator iter1 = list1.begin (); iter1 != list1.end (); ++iter1)
576 float smallest_distance = std::numeric_limits<float>::max ();
577 for (
typename std::list<Candidate>::iterator iter2 = list2.begin (); iter2 != list2.end (); ++iter2)
579 const float dx =
static_cast<float> (iter1->x) - static_cast<float> (iter2->x);
580 const float dy =
static_cast<float> (iter1->y) - static_cast<float> (iter2->y);
582 const float distance = dx*dx + dy*dy;
584 if (distance < smallest_distance)
586 smallest_distance = distance;
590 const float score = smallest_distance * iter1->gradient.magnitude;
592 if (score > best_score)
599 if (best_iter != list1.end ())
601 list2.push_back (*best_iter);
610 else if (feature_selection_method_ == MASK_BORDER_HIGH_GRADIENTS || feature_selection_method_ == MASK_BORDER_EQUALLY)
613 erode (mask, eroded_mask);
618 for (
size_t row_index = 0; row_index < height; ++row_index)
620 for (
size_t col_index = 0; col_index < width; ++col_index)
622 if (diff_mask (col_index, row_index) != 0)
624 const GradientXY & gradient = color_gradients_ (col_index, row_index);
625 if ((feature_selection_method_ == MASK_BORDER_EQUALLY || gradient.
magnitude > gradient_magnitude_threshold_feature_extraction_)
626 && filtered_quantized_color_gradients_ (col_index, row_index) != 0)
630 candidate.
x =
static_cast<int> (col_index);
631 candidate.
y =
static_cast<int> (row_index);
633 list1.push_back (candidate);
641 if (list1.size () <= nr_features)
643 for (
typename std::list<Candidate>::iterator iter1 = list1.begin (); iter1 != list1.end (); ++iter1)
647 feature.
x = iter1->x;
648 feature.
y = iter1->y;
650 feature.
quantized_value = filtered_quantized_color_gradients_ (iter1->x, iter1->y);
652 features.push_back (feature);
657 size_t distance = list1.size () / nr_features + 1;
658 while (list2.size () != nr_features)
660 const size_t sqr_distance = distance*distance;
661 for (
typename std::list<Candidate>::iterator iter1 = list1.begin (); iter1 != list1.end (); ++iter1)
663 bool candidate_accepted =
true;
665 for (
typename std::list<Candidate>::iterator iter2 = list2.begin (); iter2 != list2.end (); ++iter2)
667 const int dx = iter1->x - iter2->x;
668 const int dy = iter1->y - iter2->y;
669 const unsigned int tmp_distance = dx*dx + dy*dy;
672 if (tmp_distance < sqr_distance)
674 candidate_accepted =
false;
679 if (candidate_accepted)
680 list2.push_back (*iter1);
682 if (list2.size () == nr_features)
689 for (
typename std::list<Candidate>::iterator iter2 = list2.begin (); iter2 != list2.end (); ++iter2)
693 feature.
x = iter2->x;
694 feature.
y = iter2->y;
696 feature.
quantized_value = filtered_quantized_color_gradients_ (iter2->x, iter2->y);
698 features.push_back (feature);
703 template <
typename Po
intInT>
void
706 std::vector<QuantizedMultiModFeature> & features)
const
708 const size_t width = mask.
getWidth ();
711 std::list<Candidate> list1;
712 std::list<Candidate> list2;
715 for (
size_t row_index = 0; row_index < height; ++row_index)
717 for (
size_t col_index = 0; col_index < width; ++col_index)
719 if (mask (col_index, row_index) != 0)
721 const GradientXY & gradient = color_gradients_ (col_index, row_index);
722 if (gradient.
magnitude > gradient_magnitude_threshold_feature_extraction_
723 && filtered_quantized_color_gradients_ (col_index, row_index) != 0)
727 candidate.
x =
static_cast<int> (col_index);
728 candidate.
y =
static_cast<int> (row_index);
730 list1.push_back (candidate);
738 for (
typename std::list<Candidate>::iterator iter1 = list1.begin (); iter1 != list1.end (); ++iter1)
742 feature.
x = iter1->x;
743 feature.
y = iter1->y;
745 feature.
quantized_value = filtered_quantized_color_gradients_ (iter1->x, iter1->y);
747 features.push_back (feature);
752 template <
typename Po
intInT>
757 const int width = cloud->
width;
758 const int height = cloud->
height;
760 color_gradients_.points.resize (width*height);
761 color_gradients_.width = width;
762 color_gradients_.height = height;
764 const float pi = tan (1.0f) * 2;
765 for (
int row_index = 0; row_index < height-2; ++row_index)
767 for (
int col_index = 0; col_index < width-2; ++col_index)
769 const int index0 = row_index*width+col_index;
770 const int index_c = row_index*width+col_index+2;
771 const int index_r = (row_index+2)*width+col_index;
775 const unsigned char r0 = cloud->
points[index0].r;
776 const unsigned char g0 = cloud->
points[index0].g;
777 const unsigned char b0 = cloud->
points[index0].b;
779 const unsigned char r_c = cloud->
points[index_c].r;
780 const unsigned char g_c = cloud->
points[index_c].g;
781 const unsigned char b_c = cloud->
points[index_c].b;
783 const unsigned char r_r = cloud->
points[index_r].r;
784 const unsigned char g_r = cloud->
points[index_r].g;
785 const unsigned char b_r = cloud->
points[index_r].b;
787 const float r_dx =
static_cast<float> (r_c) - static_cast<float> (r0);
788 const float g_dx =
static_cast<float> (g_c) - static_cast<float> (g0);
789 const float b_dx =
static_cast<float> (b_c) - static_cast<float> (b0);
791 const float r_dy =
static_cast<float> (r_r) - static_cast<float> (r0);
792 const float g_dy =
static_cast<float> (g_r) - static_cast<float> (g0);
793 const float b_dy =
static_cast<float> (b_r) - static_cast<float> (b0);
795 const float sqr_mag_r = r_dx*r_dx + r_dy*r_dy;
796 const float sqr_mag_g = g_dx*g_dx + g_dy*g_dy;
797 const float sqr_mag_b = b_dx*b_dx + b_dy*b_dy;
799 if (sqr_mag_r > sqr_mag_g && sqr_mag_r > sqr_mag_b)
803 gradient.
angle = atan2 (r_dy, r_dx) * 180.0f / pi;
804 gradient.
x =
static_cast<float> (col_index);
805 gradient.
y =
static_cast<float> (row_index);
807 color_gradients_ (col_index+1, row_index+1) = gradient;
809 else if (sqr_mag_g > sqr_mag_b)
813 gradient.
angle = atan2 (g_dy, g_dx) * 180.0f / pi;
814 gradient.
x =
static_cast<float> (col_index);
815 gradient.
y =
static_cast<float> (row_index);
817 color_gradients_ (col_index+1, row_index+1) = gradient;
823 gradient.
angle = atan2 (b_dy, b_dx) * 180.0f / pi;
824 gradient.
x =
static_cast<float> (col_index);
825 gradient.
y =
static_cast<float> (row_index);
827 color_gradients_ (col_index+1, row_index+1) = gradient;
830 assert (color_gradients_ (col_index+1, row_index+1).angle >= -180 &&
831 color_gradients_ (col_index+1, row_index+1).angle <= 180);
839 template <
typename Po
intInT>
844 const int width = cloud->
width;
845 const int height = cloud->
height;
847 color_gradients_.points.resize (width*height);
848 color_gradients_.width = width;
849 color_gradients_.height = height;
851 const float pi = tanf (1.0f) * 2.0f;
852 for (
int row_index = 1; row_index < height-1; ++row_index)
854 for (
int col_index = 1; col_index < width-1; ++col_index)
856 const int r7 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index-1)].r);
857 const int g7 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index-1)].g);
858 const int b7 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index-1)].b);
859 const int r8 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index)].r);
860 const int g8 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index)].g);
861 const int b8 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index)].b);
862 const int r9 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index+1)].r);
863 const int g9 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index+1)].g);
864 const int b9 =
static_cast<int> (cloud->
points[(row_index-1)*width + (col_index+1)].b);
865 const int r4 =
static_cast<int> (cloud->
points[(row_index)*width + (col_index-1)].r);
866 const int g4 =
static_cast<int> (cloud->
points[(row_index)*width + (col_index-1)].g);
867 const int b4 =
static_cast<int> (cloud->
points[(row_index)*width + (col_index-1)].b);
868 const int r6 =
static_cast<int> (cloud->
points[(row_index)*width + (col_index+1)].r);
869 const int g6 =
static_cast<int> (cloud->
points[(row_index)*width + (col_index+1)].g);
870 const int b6 =
static_cast<int> (cloud->
points[(row_index)*width + (col_index+1)].b);
871 const int r1 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index-1)].r);
872 const int g1 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index-1)].g);
873 const int b1 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index-1)].b);
874 const int r2 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index)].r);
875 const int g2 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index)].g);
876 const int b2 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index)].b);
877 const int r3 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index+1)].r);
878 const int g3 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index+1)].g);
879 const int b3 =
static_cast<int> (cloud->
points[(row_index+1)*width + (col_index+1)].b);
904 const int r_dx = r9 + 2*r6 + r3 - (r7 + 2*r4 + r1);
905 const int r_dy = r1 + 2*r2 + r3 - (r7 + 2*r8 + r9);
906 const int g_dx = g9 + 2*g6 + g3 - (g7 + 2*g4 + g1);
907 const int g_dy = g1 + 2*g2 + g3 - (g7 + 2*g8 + g9);
908 const int b_dx = b9 + 2*b6 + b3 - (b7 + 2*b4 + b1);
909 const int b_dy = b1 + 2*b2 + b3 - (b7 + 2*b8 + b9);
911 const int sqr_mag_r = r_dx*r_dx + r_dy*r_dy;
912 const int sqr_mag_g = g_dx*g_dx + g_dy*g_dy;
913 const int sqr_mag_b = b_dx*b_dx + b_dy*b_dy;
915 if (sqr_mag_r > sqr_mag_g && sqr_mag_r > sqr_mag_b)
918 gradient.
magnitude = sqrtf (static_cast<float> (sqr_mag_r));
919 gradient.
angle = atan2f (static_cast<float> (r_dy), static_cast<float> (r_dx)) * 180.0f / pi;
920 if (gradient.
angle < -180.0f) gradient.
angle += 360.0f;
921 if (gradient.
angle >= 180.0f) gradient.
angle -= 360.0f;
922 gradient.
x =
static_cast<float> (col_index);
923 gradient.
y =
static_cast<float> (row_index);
925 color_gradients_ (col_index, row_index) = gradient;
927 else if (sqr_mag_g > sqr_mag_b)
930 gradient.
magnitude = sqrtf (static_cast<float> (sqr_mag_g));
931 gradient.
angle = atan2f (static_cast<float> (g_dy), static_cast<float> (g_dx)) * 180.0f / pi;
932 if (gradient.
angle < -180.0f) gradient.
angle += 360.0f;
933 if (gradient.
angle >= 180.0f) gradient.
angle -= 360.0f;
934 gradient.
x =
static_cast<float> (col_index);
935 gradient.
y =
static_cast<float> (row_index);
937 color_gradients_ (col_index, row_index) = gradient;
942 gradient.
magnitude = sqrtf (static_cast<float> (sqr_mag_b));
943 gradient.
angle = atan2f (static_cast<float> (b_dy), static_cast<float> (b_dx)) * 180.0f / pi;
944 if (gradient.
angle < -180.0f) gradient.
angle += 360.0f;
945 if (gradient.
angle >= 180.0f) gradient.
angle -= 360.0f;
946 gradient.
x =
static_cast<float> (col_index);
947 gradient.
y =
static_cast<float> (row_index);
949 color_gradients_ (col_index, row_index) = gradient;
952 assert (color_gradients_ (col_index, row_index).angle >= -180 &&
953 color_gradients_ (col_index, row_index).angle <= 180);
961 template <
typename Po
intInT>
978 const size_t width = input_->width;
979 const size_t height = input_->height;
981 quantized_color_gradients_.resize (width, height);
983 const float angleScale = 16.0f/360.0f;
987 for (
size_t row_index = 0; row_index < height; ++row_index)
989 for (
size_t col_index = 0; col_index < width; ++col_index)
991 if (color_gradients_ (col_index, row_index).magnitude < gradient_magnitude_threshold_)
993 quantized_color_gradients_ (col_index, row_index) = 0;
997 const float angle = 11.25f + color_gradients_ (col_index, row_index).angle + 180.0f;
998 const int quantized_value = (
static_cast<int> (angle * angleScale)) & 7;
999 quantized_color_gradients_ (col_index, row_index) =
static_cast<unsigned char> (quantized_value + 1);
1024 template <
typename Po
intInT>
1029 const size_t width = input_->width;
1030 const size_t height = input_->height;
1032 filtered_quantized_color_gradients_.resize (width, height);
1035 for (
size_t row_index = 1; row_index < height-1; ++row_index)
1037 for (
size_t col_index = 1; col_index < width-1; ++col_index)
1039 unsigned char histogram[9] = {0,0,0,0,0,0,0,0,0};
1042 const unsigned char * data_ptr = quantized_color_gradients_.getData () + (row_index-1)*width+col_index-1;
1043 assert (data_ptr[0] < 9 && data_ptr[1] < 9 && data_ptr[2] < 9);
1044 ++histogram[data_ptr[0]];
1045 ++histogram[data_ptr[1]];
1046 ++histogram[data_ptr[2]];
1049 const unsigned char * data_ptr = quantized_color_gradients_.getData () + row_index*width+col_index-1;
1050 assert (data_ptr[0] < 9 && data_ptr[1] < 9 && data_ptr[2] < 9);
1051 ++histogram[data_ptr[0]];
1052 ++histogram[data_ptr[1]];
1053 ++histogram[data_ptr[2]];
1056 const unsigned char * data_ptr = quantized_color_gradients_.getData () + (row_index+1)*width+col_index-1;
1057 assert (data_ptr[0] < 9 && data_ptr[1] < 9 && data_ptr[2] < 9);
1058 ++histogram[data_ptr[0]];
1059 ++histogram[data_ptr[1]];
1060 ++histogram[data_ptr[2]];
1063 unsigned char max_hist_value = 0;
1064 int max_hist_index = -1;
1075 if (max_hist_value < histogram[1]) {max_hist_index = 0; max_hist_value = histogram[1];}
1076 if (max_hist_value < histogram[2]) {max_hist_index = 1; max_hist_value = histogram[2];}
1077 if (max_hist_value < histogram[3]) {max_hist_index = 2; max_hist_value = histogram[3];}
1078 if (max_hist_value < histogram[4]) {max_hist_index = 3; max_hist_value = histogram[4];}
1079 if (max_hist_value < histogram[5]) {max_hist_index = 4; max_hist_value = histogram[5];}
1080 if (max_hist_value < histogram[6]) {max_hist_index = 5; max_hist_value = histogram[6];}
1081 if (max_hist_value < histogram[7]) {max_hist_index = 6; max_hist_value = histogram[7];}
1082 if (max_hist_value < histogram[8]) {max_hist_index = 7; max_hist_value = histogram[8];}
1084 if (max_hist_index != -1 && max_hist_value >= 5)
1085 filtered_quantized_color_gradients_ (col_index, row_index) =
static_cast<unsigned char> (0x1 << max_hist_index);
1087 filtered_quantized_color_gradients_ (col_index, row_index) = 0;
1094 template <
typename Po
intInT>
1100 const size_t width = mask_in.
getWidth ();
1101 const size_t height = mask_in.
getHeight ();
1103 mask_out.
resize (width, height);
1105 for (
size_t row_index = 1; row_index < height-1; ++row_index)
1107 for (
size_t col_index = 1; col_index < width-1; ++col_index)
1109 if (mask_in (col_index, row_index-1) == 0 ||
1110 mask_in (col_index-1, row_index) == 0 ||
1111 mask_in (col_index+1, row_index) == 0 ||
1112 mask_in (col_index, row_index+1) == 0)
1114 mask_out (col_index, row_index) = 0;
1118 mask_out (col_index, row_index) = 255;
pcl::PointCloud< pcl::GradientXY > & getMaxColorGradients()
Returns a point cloud containing the max-RGB gradients.
Modality based on max-RGB gradients.
size_t modality_index
the index of the corresponding modality.
void quantizeColorGradients()
Quantizes the color gradients.
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
void computeGaussianKernel(const size_t kernel_size, const float sigma, std::vector< float > &kernel_values)
Computes the Gaussian kernel used for smoothing.
void extractAllFeatures(const MaskMap &mask, size_t nr_features, size_t modalityIndex, std::vector< QuantizedMultiModFeature > &features) const
Extracts all possible features from the modality within the specified mask.
void resize(size_t n)
Resize the cloud.
static void getDifferenceMask(const MaskMap &mask0, const MaskMap &mask1, MaskMap &diff_mask)
void setGradientMagnitudeThreshold(const float threshold)
Sets the threshold for the gradient magnitude which is used when quantizing the data.
ColorGradientModality()
Constructor.
virtual void setInputCloud(const typename PointCloudIn::ConstPtr &cloud)
Provide a pointer to the input dataset (overwrites the PCLBase::setInputCloud method) ...
void convolve(const Eigen::ArrayXf &h_kernel, const Eigen::ArrayXf &v_kernel, PointCloudOut &output)
Convolve point cloud with an horizontal kernel along rows then vertical kernel along columns : convol...
uint32_t width
The point cloud width (if organized as an image-structure).
void filterQuantizedColorGradients()
Filters the quantized gradients.
void extractFeatures(const MaskMap &mask, size_t nr_features, size_t modalityIndex, std::vector< QuantizedMultiModFeature > &features) const
Extracts features from this modality within the specified mask.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values).
void setKernel(const Eigen::ArrayXf &kernel)
Set convolving kernel.
QuantizedMap & getSpreadedQuantizedMap()
Returns a reference to the internally computed spreaded quantized map.
PointCloudConstPtr input_
The input point cloud dataset.
bool operator<(const Candidate &rhs)
Operator for comparing to candidates (by magnitude of the gradient).
static void erode(const pcl::MaskMap &mask_in, pcl::MaskMap &mask_out)
Erodes a mask.
void setGradientMagnitudeThresholdForFeatureExtraction(const float threshold)
Sets the threshold for the gradient magnitude which is used for feature extraction.
A point structure representing Euclidean xyz coordinates, and the intensity value.
void setSpreadingSize(const size_t spreading_size)
Sets the spreading size for spreading the quantized data.
virtual ~ColorGradientModality()
Destructor.
boost::shared_ptr< const PointCloud< PointRGBT > > ConstPtr
void computeMaxColorGradientsSobel(const typename pcl::PointCloud< pcl::RGB >::ConstPtr &cloud)
Computes the max-RGB gradients for the specified cloud using sobel.
uint32_t height
The point cloud height (if organized as an image-structure).
void setFeatureSelectionMethod(const FeatureSelectionMethod method)
Sets the feature selection method.
void computeMaxColorGradients(const typename pcl::PointCloud< pcl::RGB >::ConstPtr &cloud)
Computes the max-RGB gradients for the specified cloud.
virtual void processInputDataFromFiltered()
Processes the input data assuming that everything up to filtering is already done/available (so only ...
FeatureSelectionMethod
Different methods for feature selection/extraction.
virtual void processInputData()
Processes the input data (smoothing, computing gradients, quantizing, filtering, spreading).
void resize(size_t width, size_t height)
pcl::PointCloud< PointInT > PointCloudIn
boost::shared_ptr< PointCloud< PointT > > Ptr
void setVariableFeatureNr(const bool enabled)
Sets whether variable feature numbers for feature extraction is enabled.
QuantizedMap & getQuantizedMap()
Returns a reference to the internally computed quantized map.
static void spreadQuantizedMap(const QuantizedMap &input_map, QuantizedMap &output_map, size_t spreading_size)
Candidate for a feature (used in feature extraction methods).
A structure representing RGB color information.
GradientXY gradient
The gradient.
void setInputCloud(const PointCloudInConstPtr &cloud)
Provide a pointer to the input dataset.
unsigned char quantized_value
the quantized value attached to the feature.
Feature that defines a position and quantized value in a specific modality.
Convolution is a mathematical operation on two functions f and g, producing a third function that is ...
Interface for a quantizable modality.