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;
boost::shared_ptr< const PointCloud< PointT > > ConstPtr
static void getDifferenceMask(const MaskMap &mask0, const MaskMap &mask1, MaskMap &diff_mask)
boost::shared_ptr< PointCloud< PointT > > Ptr
Feature that defines a position and quantized value in a specific modality.
void computeMaxColorGradientsSobel(const typename pcl::PointCloud< pcl::RGB >::ConstPtr &cloud)
Computes the max-RGB gradients for the specified cloud using sobel.
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...
void quantizeColorGradients()
Quantizes the color gradients.
uint32_t width
The point cloud width (if organized as an image-structure).
void setFeatureSelectionMethod(const FeatureSelectionMethod method)
Sets the feature selection method.
unsigned char quantized_value
the quantized value attached to the feature.
void resize(size_t width, size_t height)
void setKernel(const Eigen::ArrayXf &kernel)
Set convolving kernel.
A point structure representing Euclidean xyz coordinates, and the intensity value.
GradientXY gradient
The gradient.
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
virtual void setInputCloud(const typename PointCloudIn::ConstPtr &cloud)
Provide a pointer to the input dataset (overwrites the PCLBase::setInputCloud method) ...
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.
A structure representing RGB color information.
QuantizedMap & getQuantizedMap()
Returns a reference to the internally computed quantized map.
QuantizedMap & getSpreadedQuantizedMap()
Returns a reference to the internally computed spreaded quantized map.
Convolution is a mathematical operation on two functions f and g, producing a third function that is ...
void computeGaussianKernel(const size_t kernel_size, const float sigma, std::vector< float > &kernel_values)
Computes the Gaussian kernel used for smoothing.
void setInputCloud(const PointCloudInConstPtr &cloud)
Provide a pointer to the input dataset.
void resize(size_t n)
Resize the cloud.
bool operator<(const Candidate &rhs)
Operator for comparing to candidates (by magnitude of the gradient).
ColorGradientModality()
Constructor.
void setGradientMagnitudeThresholdForFeatureExtraction(const float threshold)
Sets the threshold for the gradient magnitude which is used for feature extraction.
void computeMaxColorGradients(const typename pcl::PointCloud< pcl::RGB >::ConstPtr &cloud)
Computes the max-RGB gradients for the specified cloud.
Interface for a quantizable modality.
virtual void processInputDataFromFiltered()
Processes the input data assuming that everything up to filtering is already done/available (so only ...
pcl::PointCloud< PointInT > PointCloudIn
Modality based on max-RGB gradients.
void filterQuantizedColorGradients()
Filters the quantized gradients.
virtual ~ColorGradientModality()
Destructor.
FeatureSelectionMethod
Different methods for feature selection/extraction.
void setSpreadingSize(const size_t spreading_size)
Sets the spreading size for spreading the quantized data.
virtual void processInputData()
Processes the input data (smoothing, computing gradients, quantizing, filtering, spreading).
PointCloudConstPtr input_
The input point cloud dataset.
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.
static void erode(const pcl::MaskMap &mask_in, pcl::MaskMap &mask_out)
Erodes a mask.
static void spreadQuantizedMap(const QuantizedMap &input_map, QuantizedMap &output_map, size_t spreading_size)
void setGradientMagnitudeThreshold(const float threshold)
Sets the threshold for the gradient magnitude which is used when quantizing the data.
void setVariableFeatureNr(const bool enabled)
Sets whether variable feature numbers for feature extraction is enabled.
pcl::PointCloud< pcl::GradientXY > & getMaxColorGradients()
Returns a point cloud containing the max-RGB gradients.
size_t modality_index
the index of the corresponding modality.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values).
Candidate for a feature (used in feature extraction methods).
uint32_t height
The point cloud height (if organized as an image-structure).