00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <pcl_cloud_algos/box_fit2_algo.h>
00031
00032
00033
00034 #include <pcl/sample_consensus/ransac.h>
00035 #include <pcl/sample_consensus/impl/ransac.hpp>
00036
00037
00038
00039
00040
00041 using namespace std;
00042 using namespace pcl_cloud_algos;
00043 using namespace pcl;
00044
00045
00046 void RobustBoxEstimation::getMinAndMax(Eigen::VectorXf model_coefficients, boost::shared_ptr<SACModelOrientation<PointXYZINormal> > model, std::vector<int> &min_max_indices, std::vector<float> &min_max_distances)
00047 {
00048
00049 boost::shared_ptr<vector<int> > inliers = model->getIndices();
00050 boost::shared_ptr<vector<int> > indices = model->getIndices();
00051
00052
00053 min_max_indices.resize (6);
00054 min_max_distances.resize (6);
00055 min_max_distances[0] = min_max_distances[2] = min_max_distances[4] = +DBL_MAX;
00056 min_max_distances[1] = min_max_distances[3] = min_max_distances[5] = -DBL_MAX;
00057
00058
00059 Eigen::Vector3f nm;
00060 nm[0] = model_coefficients[0];
00061 nm[1] = model_coefficients[1];
00062 nm[2] = model_coefficients[2];
00063
00064 Eigen::Vector3f nc = model->axis_.cross (nm);
00065
00066
00067 for (std::vector<int>::iterator it = inliers->begin (); it != inliers->end (); it++)
00068
00069 {
00070
00071 Eigen::Vector3f point (cloud_->points[(*indices)[*it]].x, cloud_->points[(*indices)[*it]].y, cloud_->points[(*indices)[*it]].z);
00072
00073
00074 double dists[3];
00075 dists[0] = nm.dot(point);
00076 dists[1] = nc.dot(point);
00077 dists[2] = model->axis_.dot(point);
00078 for (int d=0; d<3; d++)
00079 {
00080 if (min_max_distances[2*d+0] > dists[d]) { min_max_distances[2*d+0] = dists[d]; min_max_indices[2*d+0] = *it; }
00081 if (min_max_distances[2*d+1] < dists[d]) { min_max_distances[2*d+1] = dists[d]; min_max_indices[2*d+1] = *it; }
00082 }
00083 }
00084
00085 }
00086 std::vector<std::string> RobustBoxEstimation::requires ()
00087 {
00088 std::vector<std::string> requires;
00089
00090 requires.push_back("x");
00091 requires.push_back("y");
00092 requires.push_back("z");
00093
00094 requires.push_back("nx");
00095 requires.push_back("ny");
00096 requires.push_back("nz");
00097 return requires;
00098 }
00099
00100 void RobustBoxEstimation::pre ()
00101 {
00102 BoxEstimation::pre ();
00103 nh_.param("eps_angle", eps_angle_, eps_angle_);
00104 nh_.param("success_probability", success_probability_, success_probability_);
00105 }
00106
00108
00111 bool RobustBoxEstimation::find_model(boost::shared_ptr<const pcl::PointCloud <pcl::PointXYZINormal> > cloud, std::vector<double> &coeff)
00112 {
00113 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Looking for box in a cluster of %u points", (unsigned)cloud->points.size ());
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 SACModelOrientation<PointXYZINormal>::Ptr model (new SACModelOrientation<PointXYZINormal> (cloud));
00131 model->axis_[0] = 0 ;
00132 model->axis_[1] = 0 ;
00133 model->axis_[2] = 1 ;
00134 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Axis is (%g,%g,%g) and maximum angular difference %g",
00135 model->axis_[0], model->axis_[1], model->axis_[2], eps_angle_);
00136
00137
00138 Eigen::VectorXf refined;
00139 vector<int> inliers;
00141 if (success_probability_ > 0 && success_probability_ < 1)
00142 {
00143 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Using RANSAC with stop probability of %g and model refinement", success_probability_);
00144
00145
00146 RandomSampleConsensus<PointXYZINormal>::Ptr sac (new RandomSampleConsensus<PointXYZINormal> (model, eps_angle_));
00147 sac->setProbability (success_probability_);
00148 if (!sac->computeModel ())
00149 {
00150 if (verbosity_level_ > -2) ROS_ERROR ("[RobustBoxEstimation] No model found using the angular threshold of %g!", eps_angle_);
00151 return false;
00152 }
00153
00154
00155 sac->getInliers(inliers);
00156 if (verbosity_level_ > 1) cerr << "number of inliers: " << inliers.size () << endl;
00157
00158 std::vector<int> best_sample;
00159 std::vector<int> best_inliers;
00160 Eigen::VectorXf model_coefficients;
00161 for (unsigned i = 0; i < cloud->points.size (); i++)
00162 {
00163 std::vector<int> selection (1);
00164 selection[0] = i;
00165 model->computeModelCoefficients (selection, model_coefficients);
00166
00167 model->selectWithinDistance (model_coefficients, eps_angle_, inliers);
00168 if (best_inliers.size () < inliers.size ())
00169 {
00170 best_inliers = inliers;
00171 best_sample = selection;
00172 }
00173 }
00174
00175
00176 if (best_inliers.size () > 0)
00177 {
00178 model->computeModelCoefficients (best_sample, refined);
00179
00181 inliers = best_inliers;
00182
00183
00184
00185
00186 }
00188
00189
00190
00191
00192
00193
00194
00195
00196 }
00197 else
00198 {
00199 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Using exhaustive search in %ld points", cloud->points.size ());
00200
00201
00202 std::vector<int> best_sample;
00203 std::vector<int> best_inliers;
00204 Eigen::VectorXf model_coefficients;
00205 for (unsigned i = 0; i < cloud->points.size (); i++)
00206 {
00207 std::vector<int> selection (1);
00208 selection[0] = i;
00209 model->computeModelCoefficients (selection, model_coefficients);
00210
00211 model->selectWithinDistance (model_coefficients, eps_angle_, inliers);
00212 if (best_inliers.size () < inliers.size ())
00213 {
00214 best_inliers = inliers;
00215 best_sample = selection;
00216 }
00217 }
00218
00219
00220 if (best_inliers.size () > 0)
00221 {
00222 model->computeModelCoefficients (best_sample, refined);
00223
00225 inliers = best_inliers;
00226
00227
00228
00229
00230 }
00231 else
00232 {
00233 if (verbosity_level_ > -2) ROS_ERROR ("[RobustBoxEstimation] No model found using the angular threshold of %g!", eps_angle_);
00234 return false;
00235 }
00236 }
00237
00238
00239 coeff[12+0] = model->axis_[0];
00240 coeff[12+1] = model->axis_[1];
00241 coeff[12+2] = model->axis_[2];
00242
00243
00244 coeff[9+0] = model->axis_[1]*refined[2] - model->axis_[2]*refined[1];
00245 coeff[9+1] = model->axis_[2]*refined[0] - model->axis_[0]*refined[2];
00246 coeff[9+2] = model->axis_[0]*refined[1] - model->axis_[1]*refined[0];
00247
00248
00249 refined[0] = - (model->axis_[1]*coeff[9+2] - model->axis_[2]*coeff[9+1]);
00250 refined[1] = - (model->axis_[2]*coeff[9+0] - model->axis_[0]*coeff[9+2]);
00251 refined[2] = - (model->axis_[0]*coeff[9+1] - model->axis_[1]*coeff[9+0]);
00252
00253 ROS_INFO("refined[0]: %f", refined[0]);
00254 ROS_INFO("refined[1]: %f", refined[1]);
00255 ROS_INFO("refined[2]: %f", refined[2]);
00256 coeff[6+0] = refined[0];
00257 coeff[6+1] = refined[1];
00258 coeff[6+2] = refined[2];
00259
00260
00261
00262
00263
00264
00265
00266 vector<int> min_max_indices;
00267 vector<float> min_max_distances;
00268
00269
00270
00271
00272
00273 getMinAndMax (refined, model, min_max_indices, min_max_distances);
00274
00275
00276
00277
00278
00279
00280
00281 coeff[3+0] = min_max_distances.at (1) - min_max_distances.at (0);
00282 coeff[3+1] = min_max_distances.at (3) - min_max_distances.at (2);
00283 coeff[3+2] = min_max_distances.at (5) - min_max_distances.at (4);
00284
00285
00286 double dist[3];
00287 dist[0] = min_max_distances[0] + coeff[3+0] / 2;
00288 dist[1] = min_max_distances[2] + coeff[3+1] / 2;
00289 dist[2] = min_max_distances[4] + coeff[3+2] / 2;
00290
00291
00292 coeff[0] = dist[0]*coeff[6+0] + dist[1]*coeff[9+0] + dist[2]*coeff[12+0];
00293 coeff[1] = dist[0]*coeff[6+1] + dist[1]*coeff[9+1] + dist[2]*coeff[12+1];
00294 coeff[2] = dist[0]*coeff[6+2] + dist[1]*coeff[9+2] + dist[2]*coeff[12+2];
00295
00296
00297
00298 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Cluster center x: %g, y: %g, z: %g", coeff[0], coeff[1], coeff[2]);
00299
00300
00301 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Dimensions x: %g, y: %g, z: %g",
00302 coeff[3+0], coeff[3+1], coeff[3+2]);
00303 if (verbosity_level_ > 0) ROS_INFO ("[RobustBoxEstimation] Direction vectors: \n\t%g %g %g \n\t%g %g %g \n\t%g %g %g",
00304 coeff[3+3], coeff[3+4], coeff[3+5],
00305 coeff[3+6], coeff[3+7], coeff[3+8],
00306 coeff[3+9], coeff[3+10],coeff[3+11]);
00307
00308 return true;
00309 }
00310
00311 #ifdef CREATE_NODE
00312 int main (int argc, char* argv[])
00313 {
00314 return standalone_node <RobustBoxEstimation> (argc, argv);
00315 }
00316 #endif
00317