38 #ifndef PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_STICK_H_
39 #define PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_STICK_H_
46 template <
typename Po
intT>
bool
50 (input_->points[samples[0]].x != input_->points[samples[1]].x)
52 (input_->points[samples[0]].y != input_->points[samples[1]].y)
54 (input_->points[samples[0]].z != input_->points[samples[1]].z))
61 template <
typename Po
intT>
bool
63 const std::vector<int> &samples, Eigen::VectorXf &model_coefficients)
66 if (samples.size () != 2)
68 PCL_ERROR (
"[pcl::SampleConsensusModelStick::computeModelCoefficients] Invalid set of samples given (%zu)!\n", samples.size ());
72 model_coefficients.resize (7);
73 model_coefficients[0] = input_->points[samples[0]].x;
74 model_coefficients[1] = input_->points[samples[0]].y;
75 model_coefficients[2] = input_->points[samples[0]].z;
77 model_coefficients[3] = input_->points[samples[1]].x;
78 model_coefficients[4] = input_->points[samples[1]].y;
79 model_coefficients[5] = input_->points[samples[1]].z;
92 template <
typename Po
intT>
void
94 const Eigen::VectorXf &model_coefficients, std::vector<double> &distances)
97 if (!isModelValid (model_coefficients))
100 float sqr_threshold =
static_cast<float> (radius_max_ * radius_max_);
101 distances.resize (indices_->size ());
104 Eigen::Vector4f line_pt (model_coefficients[0], model_coefficients[1], model_coefficients[2], 0);
105 Eigen::Vector4f line_dir (model_coefficients[3], model_coefficients[4], model_coefficients[5], 0);
106 line_dir.normalize ();
109 for (
size_t i = 0; i < indices_->size (); ++i)
113 float sqr_distance = (line_pt - input_->points[(*indices_)[i]].getVector4fMap ()).cross3 (line_dir).squaredNorm ();
115 if (sqr_distance < sqr_threshold)
117 distances[i] =
sqrt (sqr_distance);
120 distances[i] = 2 *
sqrt (sqr_distance);
125 template <
typename Po
intT>
void
127 const Eigen::VectorXf &model_coefficients,
const double threshold, std::vector<int> &inliers)
130 if (!isModelValid (model_coefficients))
133 float sqr_threshold =
static_cast<float> (threshold * threshold);
136 inliers.resize (indices_->size ());
139 Eigen::Vector4f line_pt1 (model_coefficients[0], model_coefficients[1], model_coefficients[2], 0);
140 Eigen::Vector4f line_pt2 (model_coefficients[3], model_coefficients[4], model_coefficients[5], 0);
141 Eigen::Vector4f line_dir = line_pt2 - line_pt1;
144 line_dir.normalize ();
148 for (
size_t i = 0; i < indices_->size (); ++i)
152 Eigen::Vector4f dir = input_->points[(*indices_)[i]].getVector4fMap () - line_pt1;
159 float sqr_distance = dir.cross3 (line_dir).squaredNorm ();
160 if (sqr_distance < sqr_threshold)
162 inliers[nr_p++] = (*indices_)[i];
164 inliers.resize (nr_p);
168 template <
typename Po
intT>
int
170 const Eigen::VectorXf &model_coefficients,
const double threshold)
173 if (!isModelValid (model_coefficients))
176 float sqr_threshold =
static_cast<float> (threshold * threshold);
178 int nr_i = 0, nr_o = 0;
181 Eigen::Vector4f line_pt1 (model_coefficients[0], model_coefficients[1], model_coefficients[2], 0);
182 Eigen::Vector4f line_pt2 (model_coefficients[3], model_coefficients[4], model_coefficients[5], 0);
183 Eigen::Vector4f line_dir = line_pt2 - line_pt1;
184 line_dir.normalize ();
190 for (
size_t i = 0; i < indices_->size (); ++i)
194 Eigen::Vector4f dir = input_->points[(*indices_)[i]].getVector4fMap () - line_pt1;
201 float sqr_distance = dir.cross3 (line_dir).squaredNorm ();
203 if (sqr_distance < sqr_threshold)
205 else if (sqr_distance < 4 * sqr_threshold)
209 return (nr_i - nr_o < 0 ? 0 : nr_i - nr_o);
213 template <
typename Po
intT>
void
215 const std::vector<int> &inliers,
const Eigen::VectorXf &model_coefficients, Eigen::VectorXf &optimized_coefficients)
218 if (!isModelValid (model_coefficients))
220 optimized_coefficients = model_coefficients;
225 if (inliers.size () <= 2)
227 PCL_ERROR (
"[pcl::SampleConsensusModelStick::optimizeModelCoefficients] Not enough inliers found to support a model (%zu)! Returning the same coefficients.\n", inliers.size ());
228 optimized_coefficients = model_coefficients;
232 optimized_coefficients.resize (7);
235 Eigen::Vector4f centroid;
236 Eigen::Matrix3f covariance_matrix;
240 optimized_coefficients[0] = centroid[0];
241 optimized_coefficients[1] = centroid[1];
242 optimized_coefficients[2] = centroid[2];
245 Eigen::Vector3f eigen_values;
246 Eigen::Vector3f eigen_vector;
250 optimized_coefficients.template segment<3> (3) = eigen_vector;
254 template <
typename Po
intT>
void
256 const std::vector<int> &inliers,
const Eigen::VectorXf &model_coefficients,
PointCloud &projected_points,
bool copy_data_fields)
259 if (!isModelValid (model_coefficients))
263 Eigen::Vector4f line_pt (model_coefficients[0], model_coefficients[1], model_coefficients[2], 0);
264 Eigen::Vector4f line_dir (model_coefficients[3], model_coefficients[4], model_coefficients[5], 0);
266 projected_points.
header = input_->header;
267 projected_points.
is_dense = input_->is_dense;
270 if (copy_data_fields)
273 projected_points.
points.resize (input_->points.size ());
274 projected_points.
width = input_->width;
275 projected_points.
height = input_->height;
279 for (
size_t i = 0; i < projected_points.
points.size (); ++i)
284 for (
size_t i = 0; i < inliers.size (); ++i)
286 Eigen::Vector4f pt (input_->points[inliers[i]].x, input_->points[inliers[i]].y, input_->points[inliers[i]].z, 0);
288 float k = (pt.dot (line_dir) - line_pt.dot (line_dir)) / line_dir.dot (line_dir);
290 Eigen::Vector4f pp = line_pt + k * line_dir;
292 projected_points.
points[inliers[i]].x = pp[0];
293 projected_points.
points[inliers[i]].y = pp[1];
294 projected_points.
points[inliers[i]].z = pp[2];
300 projected_points.
points.resize (inliers.size ());
301 projected_points.
width =
static_cast<uint32_t
> (inliers.size ());
302 projected_points.
height = 1;
306 for (
size_t i = 0; i < inliers.size (); ++i)
311 for (
size_t i = 0; i < inliers.size (); ++i)
313 Eigen::Vector4f pt (input_->points[inliers[i]].x, input_->points[inliers[i]].y, input_->points[inliers[i]].z, 0);
315 float k = (pt.dot (line_dir) - line_pt.dot (line_dir)) / line_dir.dot (line_dir);
317 Eigen::Vector4f pp = line_pt + k * line_dir;
319 projected_points.
points[i].x = pp[0];
320 projected_points.
points[i].y = pp[1];
321 projected_points.
points[i].z = pp[2];
327 template <
typename Po
intT>
bool
329 const std::set<int> &indices,
const Eigen::VectorXf &model_coefficients,
const double threshold)
332 if (!isModelValid (model_coefficients))
336 Eigen::Vector4f line_pt (model_coefficients[0], model_coefficients[1], model_coefficients[2], 0);
337 Eigen::Vector4f line_dir (model_coefficients[3] - model_coefficients[0], model_coefficients[4] - model_coefficients[1], model_coefficients[5] - model_coefficients[2], 0);
339 line_dir.normalize ();
341 float sqr_threshold =
static_cast<float> (threshold * threshold);
343 for (std::set<int>::const_iterator it = indices.begin (); it != indices.end (); ++it)
347 if ((line_pt - input_->points[*it].getVector4fMap ()).cross3 (line_dir).squaredNorm () > sqr_threshold)
354 #define PCL_INSTANTIATE_SampleConsensusModelStick(T) template class PCL_EXPORTS pcl::SampleConsensusModelStick<T>;
356 #endif // PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_STICK_H_