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
00033 #include <algorithm>
00034 #include <cfloat>
00035 #include <door_handle_detector/sample_consensus/lmeds.h>
00036
00037 namespace sample_consensus
00038 {
00040
00044 LMedS::LMedS (SACModel *model, double threshold) : SAC (model)
00045 {
00046 this->threshold_ = threshold;
00047
00048 this->max_iterations_ = 50;
00049
00050 this->iterations_ = 0;
00051 }
00052
00054
00057 LMedS::LMedS (SACModel* model) : SAC (model) { }
00058
00060
00063 bool
00064 LMedS::computeModel (int debug)
00065 {
00066 iterations_ = 0;
00067 double d_best_penalty = DBL_MAX;
00068
00069 std::vector<int> best_model;
00070 std::vector<int> best_inliers;
00071 std::vector<int> selection;
00072 std::vector<double> distances;
00073
00074
00075 while (iterations_ < max_iterations_)
00076 {
00077
00078 sac_model_->getSamples (iterations_, selection);
00079
00080 if (selection.size () == 0) break;
00081
00082
00083 sac_model_->computeModelCoefficients (selection);
00084
00085 double d_cur_penalty = 0;
00086
00087
00088
00089 sac_model_->getDistancesToModel (sac_model_->getModelCoefficients (), distances);
00090 if (distances.size () == 0)
00091 {
00092 iterations_ += 1;
00093 continue;
00094 }
00095
00096 std::sort (distances.begin (), distances.end ());
00097
00098
00099 int mid = sac_model_->getIndices ()->size () / 2;
00100
00101
00102 if (sac_model_->getIndices ()->size () % 2 == 0)
00103 d_cur_penalty = (sqrt (distances[mid-1]) + sqrt (distances[mid])) / 2;
00104 else
00105 d_cur_penalty = sqrt (distances[mid]);
00106
00107
00108 if (d_cur_penalty < d_best_penalty)
00109 {
00110 d_best_penalty = d_cur_penalty;
00111 best_model = selection;
00112 }
00113
00114 iterations_ += 1;
00115 if (debug > 1)
00116 std::cerr << "[LMedS::computeModel] Trial " << iterations_ << " out of "<< max_iterations_ << ". Best penalty is : " << d_best_penalty << "." << std::endl;
00117 }
00118
00119 if (best_model.size () != 0)
00120 {
00121
00122
00123
00124
00125
00126
00127 sac_model_->computeModelCoefficients (best_model);
00128
00129 std::vector<double> distances;
00130 sac_model_->getDistancesToModel (sac_model_->getModelCoefficients (), distances);
00131 if (distances.size () == 0)
00132 ROS_WARN ("Distances to model _after_ model estimation have size 0!");
00133
00134 best_inliers.resize (sac_model_->getIndices ()->size ());
00135 int n_inliers_count = 0;
00136 for (unsigned int i = 0; i < sac_model_->getIndices ()->size (); i++)
00137 {
00138
00139 if (distances[i] <= threshold_)
00140 {
00141 best_inliers[n_inliers_count] = sac_model_->getIndices ()->at (i);
00142 n_inliers_count++;
00143 }
00144 }
00145 best_inliers.resize (n_inliers_count);
00146
00147 if (debug > 0)
00148 std::cerr << "[LMedS::computeModel] Model found: " << n_inliers_count << " inliers" << std::endl;
00149 sac_model_->setBestModel (best_model);
00150 sac_model_->setBestInliers (best_inliers);
00151 return (true);
00152 }
00153 else
00154 if (debug > 0)
00155 std::cerr << "[LMedS::computeModel] Unable to find a solution!" << std::endl;
00156 return (false);
00157 }
00158 }