40 #ifndef PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_REGISTRATION_H_
41 #define PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_REGISTRATION_H_
46 template <
typename Po
intT>
bool
49 return ((input_->points[samples[1]].getArray4fMap () - input_->points[samples[0]].getArray4fMap ()).matrix ().squaredNorm () > sample_dist_thresh_ &&
50 (input_->points[samples[2]].getArray4fMap () - input_->points[samples[0]].getArray4fMap ()).matrix ().squaredNorm () > sample_dist_thresh_ &&
51 (input_->points[samples[2]].getArray4fMap () - input_->points[samples[1]].getArray4fMap ()).matrix ().squaredNorm () > sample_dist_thresh_);
55 template <
typename Po
intT>
bool
60 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::computeModelCoefficients] No target dataset given!\n");
64 if (samples.size () != 3)
67 std::vector<int> indices_tgt (3);
68 for (
int i = 0; i < 3; ++i)
69 indices_tgt[i] = correspondences_[samples[i]];
71 estimateRigidTransformationSVD (*input_, samples, *target_, indices_tgt, model_coefficients);
76 template <
typename Po
intT>
void
79 if (indices_->size () != indices_tgt_->size ())
81 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::getDistancesToModel] Number of source indices (%zu) differs than number of target indices (%zu)!\n", indices_->size (), indices_tgt_->size ());
87 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::getDistanceToModel] No target dataset given!\n");
91 if (!isModelValid (model_coefficients))
96 distances.resize (indices_->size ());
99 Eigen::Matrix4f transform;
100 transform.row (0) = model_coefficients.segment<4>(0);
101 transform.row (1) = model_coefficients.segment<4>(4);
102 transform.row (2) = model_coefficients.segment<4>(8);
103 transform.row (3) = model_coefficients.segment<4>(12);
105 for (
size_t i = 0; i < indices_->size (); ++i)
107 Eigen::Vector4f pt_src = input_->points[(*indices_)[i]].getVector4fMap ();
109 Eigen::Vector4f pt_tgt = target_->points[(*indices_tgt_)[i]].getVector4fMap ();
112 Eigen::Vector4f p_tr (transform * pt_src);
115 distances[i] = (p_tr - pt_tgt).norm ();
120 template <
typename Po
intT>
void
123 if (indices_->size () != indices_tgt_->size ())
125 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::selectWithinDistance] Number of source indices (%zu) differs than number of target indices (%zu)!\n", indices_->size (), indices_tgt_->size ());
131 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::selectWithinDistance] No target dataset given!\n");
135 double thresh = threshold * threshold;
138 if (!isModelValid (model_coefficients))
144 inliers.resize (indices_->size ());
146 Eigen::Matrix4f transform;
147 transform.row (0) = model_coefficients.segment<4>(0);
148 transform.row (1) = model_coefficients.segment<4>(4);
149 transform.row (2) = model_coefficients.segment<4>(8);
150 transform.row (3) = model_coefficients.segment<4>(12);
153 for (
size_t i = 0; i < indices_->size (); ++i)
155 Eigen::Vector4f pt_src = input_->points[(*indices_)[i]].getVector4fMap ();
157 Eigen::Vector4f pt_tgt = target_->points[(*indices_tgt_)[i]].getVector4fMap ();
160 Eigen::Vector4f p_tr (transform * pt_src);
162 if ((p_tr - pt_tgt).squaredNorm () < thresh)
163 inliers[nr_p++] = (*indices_)[i];
165 inliers.resize (nr_p);
169 template <
typename Po
intT>
int
171 const Eigen::VectorXf &model_coefficients,
const double threshold)
173 if (indices_->size () != indices_tgt_->size ())
175 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::countWithinDistance] Number of source indices (%zu) differs than number of target indices (%zu)!\n", indices_->size (), indices_tgt_->size ());
180 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::countWithinDistance] No target dataset given!\n");
184 double thresh = threshold * threshold;
187 if (!isModelValid (model_coefficients))
190 Eigen::Matrix4f transform;
191 transform.row (0) = model_coefficients.segment<4>(0);
192 transform.row (1) = model_coefficients.segment<4>(4);
193 transform.row (2) = model_coefficients.segment<4>(8);
194 transform.row (3) = model_coefficients.segment<4>(12);
197 for (
size_t i = 0; i < indices_->size (); ++i)
199 Eigen::Vector4f pt_src = input_->points[(*indices_)[i]].getVector4fMap ();
201 Eigen::Vector4f pt_tgt = target_->points[(*indices_tgt_)[i]].getVector4fMap ();
204 Eigen::Vector4f p_tr (transform * pt_src);
206 if ((p_tr - pt_tgt).squaredNorm () < thresh)
213 template <
typename Po
intT>
void
216 if (indices_->size () != indices_tgt_->size ())
218 PCL_ERROR (
"[pcl::SampleConsensusModelRegistration::optimizeModelCoefficients] Number of source indices (%zu) differs than number of target indices (%zu)!\n", indices_->size (), indices_tgt_->size ());
219 optimized_coefficients = model_coefficients;
224 if (!isModelValid (model_coefficients) || !target_)
226 optimized_coefficients = model_coefficients;
230 std::vector<int> indices_src (inliers.size ());
231 std::vector<int> indices_tgt (inliers.size ());
232 for (
size_t i = 0; i < inliers.size (); ++i)
235 indices_src[i] = (*indices_)[inliers[i]];
236 indices_tgt[i] = (*indices_tgt_)[inliers[i]];
239 estimateRigidTransformationSVD (*input_, indices_src, *target_, indices_tgt, optimized_coefficients);
243 template <
typename Po
intT>
void
246 const std::vector<int> &indices_src,
248 const std::vector<int> &indices_tgt,
249 Eigen::VectorXf &transform)
251 transform.resize (16);
252 Eigen::Vector4f centroid_src, centroid_tgt;
258 Eigen::MatrixXf cloud_src_demean;
261 Eigen::MatrixXf cloud_tgt_demean;
265 Eigen::Matrix3f H = (cloud_src_demean * cloud_tgt_demean.transpose ()).topLeftCorner<3, 3>();
268 Eigen::JacobiSVD<Eigen::Matrix3f> svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
269 Eigen::Matrix3f u = svd.matrixU ();
270 Eigen::Matrix3f v = svd.matrixV ();
273 if (u.determinant () * v.determinant () < 0)
275 for (
int x = 0; x < 3; ++x)
279 Eigen::Matrix3f R = v * u.transpose ();
282 transform.segment<3> (0) = R.row (0); transform[12] = 0;
283 transform.segment<3> (4) = R.row (1); transform[13] = 0;
284 transform.segment<3> (8) = R.row (2); transform[14] = 0;
286 Eigen::Vector3f t = centroid_tgt.head<3> () - R * centroid_src.head<3> ();
287 transform[3] = t[0]; transform[7] = t[1]; transform[11] = t[2]; transform[15] = 1.0;
290 #define PCL_INSTANTIATE_SampleConsensusModelRegistration(T) template class PCL_EXPORTS pcl::SampleConsensusModelRegistration<T>;
292 #endif // PCL_SAMPLE_CONSENSUS_IMPL_SAC_MODEL_REGISTRATION_H_