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
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
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
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
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 },
00142 { -w, s, w },
00143 { s, w, -s },
00144 { w, -s, -w } };
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
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