lmeds.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * $Id$
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     // Maximum number of trials before we give up.
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     // Iterate
00075     while (iterations_ < max_iterations_)
00076     {
00077       // Get X samples which satisfy the model criteria
00078       sac_model_->getSamples (iterations_, selection);
00079 
00080       if (selection.size () == 0) break;
00081 
00082       // Search for inliers in the point cloud for the current plane model M
00083       sac_model_->computeModelCoefficients (selection);
00084 
00085       double d_cur_penalty = 0;
00086       // d_cur_penalty = sum (min (dist, threshold))
00087 
00088       // Iterate through the 3d points and calculate the distances from them to the model
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       // d_cur_penalty = median (distances)
00099       int mid = sac_model_->getIndices ()->size () / 2;
00100 
00101       // Do we have a "middle" point or should we "estimate" one ?
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       // Better match ?
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       // Classify the data points into inliers and outliers
00122       // Sigma = 1.4826 * (1 + 5 / (n-d)) * sqrt (M)
00123       // NOTE: See "Robust Regression Methods for Computer Vision: A Review"
00124 //      double sigma = 1.4826 * (1 + 5 / (sac_model_->getIndices ()->size () - best_model.size ())) * sqrt (d_best_penalty);
00125 //      double threshold = 2.5 * sigma;
00126 
00127       sac_model_->computeModelCoefficients (best_model);
00128       // Iterate through the 3d points and calculate the distances from them to the model
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 //        if (distances[i] <= threshold)
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 }


door_handle_detector
Author(s): Radu Bogdan Rusu, Marius
autogenerated on Wed Dec 11 2013 14:17:00