contrib/brl/bbas/bsta/algo/bsta_mean_shift.txx
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/algo/bsta_mean_shift.txx
00002 #ifndef bsta_mean_shift_txx_
00003 #define bsta_mean_shift_txx_
00004 //:
00005 // \file
00006 #include "bsta_mean_shift.h"
00007 
00008 #include <vcl_map.h>
00009 
00010 template <class T, unsigned n>
00011 bool
00012 bsta_mean_shift<T,n>::find_modes(bsta_sample_set<T,n>& set, vnl_random & rng, float percentage, T epsilon)
00013 {
00014   typedef typename bsta_parzen_sphere<T,n>::vector_type vect_t;
00015 
00016   // initialize seeds by picking given percentage of the sample set randomly
00017   int size = set.size();
00018   int seed_size = (int)vcl_ceil(percentage*size/100.0f);
00019   vcl_cout << "size: " << size << " seed_size: " << seed_size << vcl_endl;
00020 
00021   set.initialize_assignments();
00022 
00023   vcl_cout << "initialized assignment_, its size: " << set.assignments().size()  << vcl_endl;
00024 
00025   for (int i = 0; i < seed_size; i++)
00026   {
00027     // randomly pick one of the samples as seed
00028     double rn = rng.drand32();
00029     int s_id = (int)vcl_floor(rn*(size-1)+0.5f);
00030     if (set.assignment(s_id) >= 0) { // has already been assigned to a mode
00031       i--;
00032       continue;
00033     }
00034     vnl_vector_fixed<T,n> dif(T(10e4));
00035 
00036     vect_t current = set.sample(s_id);
00037 
00038     unsigned cnt = 0;
00039     while (dif.magnitude() > epsilon) {
00040       vect_t mean;
00041       if (set.mean(current, mean)) {
00042         vect_t v_dif = mean-current;
00043         dif = vnl_vector_fixed<T,n>(v_dif);
00044         current = mean;
00045       }
00046       cnt++;
00047       if (cnt > max_iter_)
00048         break;
00049     }
00050     if (cnt < max_iter_) {
00051       // found a stable mode
00052       modes_.push_back(current);
00053       set.set_assignment(s_id, modes_.size()-1);
00054     }
00055   }
00056 
00057   return true;
00058 }
00059 
00060 //: use all the samples to get its mode, no need for random seed picking
00061 template <class T, unsigned n>
00062 bool
00063 bsta_mean_shift<T,n>::find_modes(bsta_sample_set<T,n>& set, T epsilon)
00064 {
00065   typedef typename bsta_distribution<T,n>::vector_type vect_t;
00066 
00067   int size = set.size();
00068   set.initialize_assignments();
00069 
00070   for (int i = 0; i < size; i++)
00071   {
00072     vnl_vector_fixed<T,n> dif(T(10e4));
00073     vect_t current = set.sample(i);
00074 
00075     unsigned cnt = 0;
00076     while (dif.magnitude() > epsilon) {
00077       vect_t mean;
00078       if (set.mean(current, mean)) {
00079         vect_t v_dif = mean-current;
00080         dif = vnl_vector_fixed<T,n>(v_dif);
00081         current = mean;
00082       }
00083       cnt++;
00084       if (cnt > max_iter_)
00085         break;
00086     }
00087     if (cnt < max_iter_) {
00088       // found a stable mode
00089       modes_.push_back(current);
00090       set.set_assignment(i, modes_.size()-1);
00091     }
00092   }
00093 
00094   return true;
00095 }
00096 
00097 //: merge the mode with samples less than cnt to one of the modes depending on its samples mean-shift paths
00098 template <class T, unsigned n>
00099 bool
00100 bsta_mean_shift<T,n>::merge_modes(bsta_sample_set<T,n>& set, int cnt, T epsilon)
00101 {
00102   typedef typename bsta_distribution<T,n>::vector_type vect_t;
00103   vcl_vector<bool> eliminated_modes(modes_.size(), false);
00104 
00105   for (unsigned m = 0; m < modes_.size(); m++)
00106   {
00107     if (set.mode_size(m) < cnt)
00108     {
00109       // eliminate this mode
00110       eliminated_modes[m] = true;
00111       for (unsigned i = 0; i < set.size(); i++) {
00112         if (set.assignment(i) == (int)m) {
00113           // find a new mode using mean-shift procedure
00114           vnl_vector_fixed<T,n> dif(T(10e4));
00115           vect_t current = set.sample(i);
00116           unsigned count = 0;
00117           while (dif.magnitude() > epsilon) {
00118             vect_t mean;
00119             if (set.mean(current, mean)) {
00120               vect_t v_dif = mean-current;
00121               dif = vnl_vector_fixed<T,n>(v_dif);
00122               current = mean;
00123             }
00124             count++;
00125             if (count > max_iter_)
00126               break;
00127           }
00128           // found a mode, check which other modes, this one is most closest to
00129           vnl_vector_fixed<T,n> dif_min(T(10e4));
00130           unsigned mm_min = m;
00131           for (unsigned mm = 0; mm < modes_.size(); mm++) {
00132             if (eliminated_modes[mm])
00133               continue;
00134 
00135             vect_t v_dif = modes_[mm]- current;
00136             vnl_vector_fixed<T,n> dif(v_dif);
00137             if (dif.magnitude() < dif_min.magnitude()) {
00138               dif_min = dif; mm_min = mm;
00139             }
00140           }
00141           set.set_assignment(i, mm_min);
00142         }
00143       }
00144     }
00145   }
00146 
00147   // re-arrange the assignment vector with the new mode ids
00148   vcl_vector<vect_t > new_modes;
00149   for (unsigned i = 0; i < modes_.size(); i++) {
00150     if (!eliminated_modes[i]) {
00151       new_modes.push_back(modes_[i]);
00152       for (unsigned jj = 0; jj < set.assignments().size(); jj++) {
00153         if (set.assignment(jj) == (int)i)
00154           set.set_assignment(jj, new_modes.size()-1);
00155       }
00156     }
00157   }
00158 
00159   modes_.clear();
00160   modes_ = new_modes;
00161 
00162   return true;
00163 }
00164 
00165 
00166 template <class T, unsigned n>
00167 bool
00168 bsta_mean_shift<T,n>::trim_modes(bsta_sample_set<T,n>& set, T epsilon)
00169 {
00170   typedef typename bsta_distribution<T,n>::vector_type vect_t;
00171 
00172   if (!modes_.size())
00173     return false;
00174 
00175   vcl_vector<bool> trimmed(modes_.size(), false);
00176   for (unsigned i = 0; i < modes_.size(); i++) {
00177     if (trimmed[i])
00178       continue;
00179 
00180     vect_t v_i = modes_[i];
00181     for (unsigned j = i+1; j < modes_.size(); j++) {
00182       if (trimmed[j])
00183         continue;
00184       vect_t v_j = modes_[j];
00185       vect_t dif = v_i - v_j;
00186       vnl_vector_fixed<T,n> v_dif(dif);
00187       if (v_dif.magnitude() < epsilon) {
00188         trimmed[j] = true;
00189         // assign all the samples of the trimmed mode to this new mode v_i
00190         for (unsigned kk = 0; kk < set.assignments().size(); kk++) {
00191           if (set.assignment(kk) == (int)j) {
00192             set.set_assignment(kk, i);
00193           }
00194         }
00195       }
00196     }
00197   }
00198   vcl_vector<vect_t > new_modes;
00199   for (unsigned i = 0; i < modes_.size(); i++) {
00200     if (!trimmed[i]) {
00201       new_modes.push_back(modes_[i]);
00202       for (unsigned jj = 0; jj < set.assignments().size(); jj++) {
00203         if (set.assignment(jj) == (int)i)
00204           set.set_assignment(jj, new_modes.size()-1);
00205       }
00206     }
00207   }
00208 
00209   modes_.clear();
00210   modes_ = new_modes;
00211   return true;
00212 }
00213 
00214 #define BSTA_SAMPLE_SET_INSTANTIATE(T,n) \
00215 template class bsta_sample_set<T,n >
00216 
00217 #define BSTA_MEAN_SHIFT_INSTANTIATE(T,n) \
00218 template class bsta_mean_shift<T,n >
00219 
00220 
00221 #endif // bsta_mean_shift_txx_