Main Page | Modules | Namespace List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ransac.h

Go to the documentation of this file.
00001 #ifndef TAG_RANSAC_H_
00002 #define TAG_RANSAC_H_
00003 
00004 #include <vector>
00005 #include <algorithm>
00006 
00007 namespace tag {
00008 
00014 
00015  template <class T> void randomTuple(const std::vector<T>& cdf, std::vector<unsigned int>& t, T maxp) {
00016      for (size_t i=0; i<t.size(); i++) {
00017      try_again:
00018      double x = drand48()* maxp;
00019      size_t r = std::min(cdf.size()-1, (size_t)(std::lower_bound(cdf.begin(), cdf.end(), (T)x) - cdf.begin()));
00020      for (size_t j=0; j<i; j++)
00021          if (r == t[j])
00022          goto try_again;
00023      t[i] = r;
00024      }
00025  }
00026 
00027  template <class T> void randomTuple(T& t, unsigned int bound)
00028  {
00029      for (size_t i=0; i<t.size(); i++) {
00030      try_again:
00031      size_t r = (size_t)(drand48() * bound);
00032      for (size_t j=0; j<i; j++)
00033          if (r == t[j])
00034          goto try_again;
00035      t[i] = r;
00036      }
00037  }
00038 
00039 
00060 
00061 template <class Obs, class Trans, class Tol> size_t find_RANSAC_inliers(const std::vector<Obs>& observations, int sample_size, const Tol& tolerance, size_t N,
00062                                     Trans& best, std::vector<bool>& inlier)
00063 {
00064     std::vector<bool> thisInlier(observations.size());
00065     size_t bestScore = 0;
00066     std::vector<size_t> sample_index(sample_size);
00067     std::vector<Obs> sample(sample_size);
00068     while (N--) {
00069     randomTuple(sample_index, observations.size());
00070     for (int i=0;i<sample_size; i++)
00071         sample[i] = observations[sample_index[i]];
00072     Trans thisT(best);
00073     thisT.estimate(sample.begin(), sample.end());
00074     size_t score = 0;
00075     for (size_t i=0; i<observations.size(); i++) {
00076         const Obs& o = observations[i];
00077         if (thisT.isInlier(o, tolerance)) {
00078         thisInlier[i] = true;
00079         score++;
00080         } else
00081         thisInlier[i] = false;
00082     }
00083     if (score > bestScore) {
00084         bestScore = score;
00085         inlier = thisInlier;
00086         best = thisT;
00087     }
00088     }
00089     return bestScore;
00090 }
00091 
00112 template <class Obs, class Trans, class Tol> double find_MSAC_inliers(const std::vector<Obs>& observations, int sample_size, const Tol& tolerance, size_t N,
00113                                     Trans& best, std::vector<bool>& inlier)
00114 {
00115     std::vector<bool> thisInlier(observations.size());
00116     const double toleranceSquared = tolerance * tolerance;
00117     double bestScore = observations.size() * toleranceSquared;
00118 
00119     std::vector<size_t> sample_index(sample_size);
00120     std::vector<Obs> sample(sample_size);
00121     while (N--) {
00122     randomTuple(sample_index, observations.size());
00123     for (int i=0;i<sample_size; i++)
00124         sample[i] = observations[sample_index[i]];
00125     Trans thisT(best);
00126     thisT.estimate(sample.begin(), sample.end());
00127     double score = 0;
00128     for (size_t i=0; i<observations.size(); i++) {
00129         const Obs& o = observations[i];
00130         const double s = thisT.score(o);
00131         if (s < toleranceSquared) {
00132         thisInlier[i] = true;
00133         score += s;
00134         } else {
00135         thisInlier[i] = false;
00136         score += toleranceSquared;
00137         }
00138     }
00139     if (score < bestScore) {
00140         bestScore = score;
00141         inlier = thisInlier;
00142         best = thisT;
00143     }
00144     }
00145     return bestScore;
00146 }
00147 
00148  inline double getShrinkRatio(unsigned int H, unsigned int N, unsigned int B)
00149  {
00150      return pow(double(H), -double(B)/N);
00151  }
00152 
00178 
00179 
00180      template <class Obs, class Trans, class Tol, class Prob>
00181     size_t find_RANSAC_inliers_guided_breadth_first(const std::vector<Obs>& observations, const Prob& prob, int sample_size, const Tol& tolerance, size_t N, size_t block_size,
00182                             Trans& best, std::vector<bool>& inlier)
00183     {
00184     std::vector<Trans> hypotheses(N,best);
00185     std::vector<std::pair<int,size_t> > score(N);
00186     std::vector<size_t> sample_index(sample_size);
00187     std::vector<Obs> sample(sample_size);
00188     std::vector<double> cdf(observations.size());
00189     cdf[0] = prob(observations[0]);
00190     for (size_t i=1; i<observations.size(); ++i)
00191         cdf[i] = cdf[i-1] + prob(observations[i]);
00192     const double psum = cdf.back();
00193 
00194     for (size_t i=0; i<hypotheses.size(); i++) {
00195         do {
00196         randomTuple(cdf, sample_index, psum);
00197         for (int s=0; s<sample_size; ++s)
00198             sample[s] = observations[sample_index[s]];
00199         }
00200         while (!hypotheses[i].estimate(sample.begin(), sample.end()));
00201         score[i] = std::make_pair(0,i);
00202     }
00203     size_t m = 0;
00204     const double factor = getShrinkRatio(N, observations.size(), block_size);
00205     while (m < observations.size()) {
00206         size_t end = std::min(observations.size(), m+block_size);
00207         for (size_t i=0; i<score.size(); i++) {
00208         const Trans& thisT = hypotheses[score[i].second];
00209         size_t s = 0;
00210         for (size_t j=m; j!=end; j++) {
00211             if (thisT.isInlier(observations[j], tolerance))
00212             ++s;
00213         }
00214         score[i].first += s;
00215         }
00216         unsigned int cutoff = (unsigned int)(score.size() * factor);
00217         if (cutoff == 0)
00218         break;
00219         std::nth_element(score.begin(), score.end(), score.begin()+cutoff, std::greater<std::pair<int,size_t> >());
00220         score.resize(cutoff);
00221         m = end;
00222     }
00223     size_t best_index = std::max_element(score.begin(), score.end())->second;
00224     best = hypotheses[best_index];
00225     size_t count = 0;
00226     inlier.resize(observations.size());
00227     for (size_t i=0; i<observations.size(); i++) {
00228         if (best.isInlier(observations[i], tolerance)) {
00229         inlier[i] = true;
00230         ++count;
00231         } else
00232         inlier[i] = false;
00233     }
00234     return count;
00235     }
00236 
00259 
00260 
00261     template <class Obs, class Trans, class Tol> size_t find_RANSAC_inliers_breadth_first(const std::vector<Obs>& observations, int sample_size, const Tol& tolerance, size_t N, size_t block_size,
00262                                               Trans& best, std::vector<bool>& inlier)
00263     {
00264     std::vector<Trans> hypotheses(N,best);
00265     std::vector<std::pair<int,size_t> > score(N);
00266     std::vector<size_t> sample_index(sample_size);
00267     std::vector<Obs> sample(sample_size);
00268     for (size_t i=0; i<hypotheses.size(); i++) {
00269         do {
00270         randomTuple(sample_index, observations.size());
00271         for (int s=0; s<sample_size; ++s)
00272             sample[s] = observations[sample_index[s]];
00273         }
00274         while (!hypotheses[i].estimate(sample.begin(), sample.end()));
00275         score[i] = std::make_pair(0,i);
00276     }
00277     size_t m = 0;
00278     const double factor = getShrinkRatio(N, observations.size(), block_size);
00279     while (m < observations.size()) {
00280         size_t end = std::min(observations.size(), m+block_size);
00281         for (size_t i=0; i<score.size(); i++) {
00282         const Trans& thisT = hypotheses[score[i].second];
00283         size_t s = 0;
00284         for (size_t j=m; j!=end; j++) {
00285             if (thisT.isInlier(observations[j], tolerance))
00286             ++s;
00287         }
00288         score[i].first += s;
00289         }
00290         unsigned int cutoff = (unsigned int)(score.size() * factor);
00291         if (cutoff == 0)
00292         break;
00293         std::nth_element(score.begin(), score.end(), score.begin()+cutoff, std::greater<std::pair<int,size_t> >());
00294         score.resize(cutoff);
00295         m = end;
00296     }
00297     size_t best_index = std::max_element(score.begin(), score.end())->second;
00298     best = hypotheses[best_index];
00299     size_t count = 0;
00300     inlier.resize(observations.size());
00301     for (size_t i=0; i<observations.size(); i++) {
00302         if (best.isInlier(observations[i], tolerance)) {
00303         inlier[i] = true;
00304         ++count;
00305         } else
00306         inlier[i] = false;
00307     }
00308     return count;
00309     }
00310 
00311 
00318 template <class T, class U>
00319 void remove_if_false(std::vector<T>& v, const std::vector<U>& flag) {
00320     assert(v.size() <= flag.size());
00321     unsigned int i=0,j;
00322     while (i<v.size() && flag[i])
00323         i++;
00324     j = i++;
00325     for (;i<v.size();i++) {
00326         if (flag[i])
00327             v[j++] = v[i];
00328     }
00329     v.resize(j);
00330 }
00331 
00332 } // namespace tag
00333 
00334 #endif

Generated on Wed Aug 8 14:30:35 2007 for TooN Algorithm Library - tag by  doxygen 1.3.9.1