fast_segmentation.hpp
Go to the documentation of this file.
00001 
00063 #ifndef __IMPL_FAST_SEGMENTATION_HPP__
00064 #define __IMPL_FAST_SEGMENTATION_HPP__
00065 
00066 #include <set>
00067 
00068 #include <pcl/common/eigen.h>
00069 #include <Eigen/LU>
00070 
00071 #include "cob_3d_mapping_common/label_defines.h"
00072 #include "cob_3d_segmentation/fast_segmentation.h"
00073 
00074 #define LISTMOD(a,b) ( ((a%b)+b)%b )
00075 
00076 template <typename PointT, typename PointNT, typename PointLabelT, typename OptionsT, typename SensorT, typename ClusterHdlT> void
00077 cob_3d_segmentation::FastSegmentation<PointT,PointNT,PointLabelT,OptionsT,SensorT,ClusterHdlT>::createSeedPoints()
00078 {
00079   int n = labels_->width * labels_->height;
00080   // make sure, image border are NANs
00081   for(size_t i = 0; i<labels_->width; ++i)
00082     (*labels_)[i].label = I_NAN;
00083   for(size_t i = labels_->size() - labels_->width; i<labels_->size(); ++i)
00084     (*labels_)[i].label = I_NAN;
00085   for(size_t i = labels_->width; i<labels_->size(); i+=labels_->width) {
00086     (*labels_)[i].label = I_NAN; (*labels_)[i+labels_->width-1].label = I_NAN; }
00087 
00088   seeds_.clear();
00089   p_seeds_.resize(n);
00090   switch (seed_method_)
00091   {
00092   case SEED_RANDOM:
00093   {
00094     p_seeds_[0] = seeds_.insert(seeds_.end(), 0);
00095     for(unsigned int i = 1; i<n; ++i)
00096     {
00097       //if(surface_->points[i].z != surface_->points[i].z)
00098       if((*labels_)[i].label == I_NAN) {
00099         p_seeds_[i] = p_seeds_[rand()%i];
00100       } else if((*normals_)[i].normal[2] != (*normals_)[i].normal[2]) {
00101         (*labels_)[i].label = I_NAN;
00102         p_seeds_[i] = p_seeds_[rand()%i];
00103         //std::cout << "NAN---" << std::endl;
00104       } else {
00105         p_seeds_[i] = seeds_.insert(p_seeds_[rand()%i],i);
00106       }
00107     }
00108     p_seeds_[0] = seeds_.insert(p_seeds_[rand()%n],0);
00109     seeds_.pop_back();
00110     break;
00111   }
00112 
00113   case SEED_LINEAR:
00114   {
00115     for(unsigned int i = 0; i<n; ++i)
00116     {
00117       //if(surface_->points[i].z != surface_->points[i].z)
00118       if((*labels_)[i].label == I_NAN)
00119         p_seeds_[i] = seeds_.end();
00120       else
00121         p_seeds_[i] = seeds_.insert(seeds_.end(),i);
00122     }
00123     break;
00124   }
00125   }
00126 }
00127 
00128 
00129 template <typename PointT, typename PointNT, typename PointLabelT, typename OptionsT, typename SensorT, typename ClusterHdlT> bool
00130 cob_3d_segmentation::FastSegmentation<PointT,PointNT,PointLabelT,OptionsT,SensorT,ClusterHdlT>::compute()
00131 {
00132   clusters_->setPointCloudIn(surface_);
00133   clusters_->setNormalCloudIn(normals_);
00134   clusters_->setLabelCloudInOut(labels_);
00135   graph_->edges()->setPointCloudIn(surface_);
00136   graph_->edges()->setLabelCloudIn(labels_);
00137 
00138   createSeedPoints();
00139 
00140   int w = labels_->width, h = labels_->height, s = 1;
00141   int mask[4][3] = { { -s, -w,  s }, // from below
00142                      { -w,  s,  w }, // from left
00143                      {  s,  w, -s }, // from above
00144                      {  w, -s, -w } }; // from right
00145   int mask_size = 3;
00146 
00147   clusters_->clear();
00148   clusters_->createCluster(I_NAN);
00149   while(seeds_.size() != 0)
00150   {
00151     unsigned int idx = seeds_.front();
00152     seeds_.pop_front();
00153     ClusterPtr c = clusters_->createCluster();
00154 
00155     std::list<SeedPoint::Ptr> seg_q;
00156     seg_q.push_back( SeedPoint::Ptr(new SeedPoint(idx, 0, 0.0)) );
00157     clusters_->addPoint(c, idx);
00158     (*labels_)[idx].label = c->id();
00159 
00160     while(seg_q.size() != 0)
00161     {
00162       SeedPoint p = *seg_q.front();
00163       seg_q.pop_front();
00164 
00165       for(int i=0; i<mask_size; ++i)
00166       {
00167         int i_idx = p.idx + mask[p.i_came_from][i];
00168         if (i_idx >= w*h || i_idx < 0) continue;
00169 
00170         if(!SensorT::areNeighbors((*surface_)[p.idx].getVector3fMap(), (*surface_)[i_idx].getVector3fMap(),4.0f)) continue;
00171 
00172         int* p_label = &(labels_->points[ i_idx ]).label;
00173         if( hasLabel(*p_label, c->id(), i_idx, p.idx, OptionsT()) ) continue;
00174 
00175         Eigen::Vector3f i_n = c->getOrientation();
00176         //Eigen::Vector3f i_c = c->getCentroid();
00177 
00178         float dot_value = fabs( i_n.dot((*normals_)[i_idx].getNormalVector3fMap()) );
00179 
00180         if(dot_value > n_threshold(c->size()))
00181         {
00182           seg_q.push_back( SeedPoint::Ptr(new SeedPoint(i_idx, LISTMOD(i + p.i_came_from - 1, 4), dot_value)) );
00183           clusters_->addPoint(c,i_idx);
00184           seeds_.erase(p_seeds_[i_idx]);
00185           *p_label = c->id();
00186         }
00187       }
00188     }
00189   }
00190   clusters_->addBorderIndicesToClusters();
00191   return true;
00192 }
00193 
00194 #endif


cob_3d_segmentation
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:03:03