Skip to content

Commit a9da50b

Browse files
authored
Fix crash in SpinImageEstimation (PointCloudLibrary#5586)
* Fix crash in SpinImageEstimation The image width (set by the user) must fit together with the size of the output histogram. `setImageWidth` now checks the given parameter and provides advice if they do not work well together. Minor additional change: in the constructor, change the assert to an if-statement since the support_angle_cos should always be checked. Fixes PointCloudLibrary#1834 Fixes PointCloudLibrary#5039 (already closed, but same issue)
1 parent 407ee41 commit a9da50b

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

features/include/pcl/features/impl/spin_image.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,13 @@ pcl::SpinImageEstimation<PointInT, PointNT, PointOutT>::SpinImageEstimation (
5353
unsigned int image_width, double support_angle_cos, unsigned int min_pts_neighb) :
5454
input_normals_ (), rotation_axes_cloud_ (),
5555
is_angular_ (false), rotation_axis_ (), use_custom_axis_(false), use_custom_axes_cloud_ (false),
56-
is_radial_ (false), image_width_ (image_width), support_angle_cos_ (support_angle_cos),
56+
is_radial_ (false), support_angle_cos_ (support_angle_cos),
5757
min_pts_neighb_ (min_pts_neighb)
5858
{
59-
assert (support_angle_cos_ <= 1.0 && support_angle_cos_ >= 0.0); // may be permit negative cosine?
59+
if (0.0 > support_angle_cos || support_angle_cos > 1.0) { // may be permit negative cosine?
60+
throw PCLException ("Cosine of support angle should be between 0 and 1", "spin_image.hpp", "SpinImageEstimation");
61+
}
62+
setImageWidth(image_width);
6063

6164
feature_name_ = "SpinImageEstimation";
6265
}

features/include/pcl/features/spin_image.h

+24-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ namespace pcl
6969
*
7070
* With the default parameters, pcl::Histogram<153> is a good choice for PointOutT.
7171
* Of course the dimension of this descriptor must change to match the number
72-
* of bins set by the parameters.
72+
* of bins set by the parameters. If you use SpinImageEstimation with something
73+
* other than pcl::Histogram<153>, you may need to put `#define PCL_NO_PRECOMPILE 1`
74+
* before including `pcl/features/spin_image.h`.
7375
*
7476
* For further information please see:
7577
*
@@ -131,7 +133,27 @@ namespace pcl
131133
void
132134
setImageWidth (unsigned int bin_count)
133135
{
134-
image_width_ = bin_count;
136+
const unsigned int necessary_desc_size = (bin_count+1)*(2*bin_count+1);
137+
if (necessary_desc_size > static_cast<unsigned int>(PointOutT::descriptorSize())) {
138+
for(int i=0; ; ++i) { // Find the biggest possible image_width_
139+
if(((i+1)*(2*i+1)) <= PointOutT::descriptorSize()) {
140+
image_width_ = i;
141+
} else {
142+
break;
143+
}
144+
}
145+
PCL_ERROR("[pcl::SpinImageEstimation] The chosen image width is too large, setting it to %u instead. "
146+
"Consider using pcl::Histogram<%u> as output type of SpinImageEstimation "
147+
"(possibly with `#define PCL_NO_PRECOMPILE 1`).\n", image_width_, ((bin_count+1)*(2*bin_count+1)));
148+
} else if (necessary_desc_size < static_cast<unsigned int>(PointOutT::descriptorSize())) {
149+
image_width_ = bin_count;
150+
PCL_WARN("[pcl::SpinImageEstimation] The chosen image width is smaller than the output histogram allows. "
151+
"This is not an error, but the last few histogram bins will not be set. "
152+
"Consider using pcl::Histogram<%u> as output type of SpinImageEstimation "
153+
"(possibly with `#define PCL_NO_PRECOMPILE 1`).\n", ((bin_count+1)*(2*bin_count+1)));
154+
} else {
155+
image_width_ = bin_count;
156+
}
135157
}
136158

137159
/** \brief Sets the maximum angle for the point normal to get to support region.

0 commit comments

Comments
 (0)