cluster_handler.h
Go to the documentation of this file.
00001 
00063 #ifndef __COB_3D_SEGMENTATION_CLUSTER_HANDLER_H__
00064 #define __COB_3D_SEGMENTATION_CLUSTER_HANDLER_H__
00065 
00066 #include <cob_3d_mapping_common/point_types.h>
00067 #include <cob_3d_mapping_common/label_defines.h>
00068 #include "cob_3d_segmentation/cluster_types.h"
00069 
00070 #include <list>
00071 #include <iomanip>
00072 
00073 #include <pcl/point_cloud.h>
00074 #include <pcl/point_types.h>
00075 #include <pcl/common/eigen.h>
00076 
00077 
00078 namespace cob_3d_segmentation
00079 {
00080   template<typename ClusterT>
00081   class ClusterHandlerBase
00082   {
00083   public:
00084     typedef ClusterT ClusterType;
00085     typedef typename std::list<ClusterT>::iterator ClusterPtr;
00086     typedef typename std::list<ClusterT>::reverse_iterator reverse_iterator;
00087     typedef typename std::list<ClusterT>::size_type size_type;
00088 
00089   public:
00090     ClusterHandlerBase() : clusters_()
00091       , id_to_cluster_()
00092       , max_cid_(0)
00093       , color_tab_()
00094     {
00095       const float rand_max_inv = 1.0f/ RAND_MAX;
00096 
00097       for (size_t i=0; i<2048; ++i)
00098       {
00099         int r = (float)rand() * rand_max_inv * 255;
00100         int g = (float)rand() * rand_max_inv * 255;
00101         int b = (float)rand() * rand_max_inv * 255;
00102         color_tab_.push_back( r << 16 | g << 8 | b );
00103       }
00104     }
00105     virtual ~ClusterHandlerBase() { };
00106 
00107     inline ClusterPtr begin() { return clusters_.begin(); }
00108     inline ClusterPtr end() { return clusters_.end(); }
00109     inline reverse_iterator rbegin() { return clusters_.rbegin(); }
00110     inline reverse_iterator rend() { return clusters_.rend(); }
00111     inline std::pair<ClusterPtr,ClusterPtr> getClusters()
00112     { return std::make_pair(clusters_.begin(),clusters_.end()); }
00113     inline std::pair<reverse_iterator, reverse_iterator> getClustersReverse()
00114     { return std::make_pair(clusters_.rbegin(), clusters_.rend()); }
00115 
00116     inline size_type numClusters() const { return clusters_.size(); }
00117     inline void sortBySize() { clusters_.sort(); }
00118     virtual void clear() { clusters_.clear(); id_to_cluster_.clear(); max_cid_ = 0; }
00119     virtual void erase(ClusterPtr c) { clusters_.erase(c); }
00120 
00121     inline ClusterPtr getCluster(const int id)
00122     {
00123       return ( (id_to_cluster_.find(id) == id_to_cluster_.end())
00124                ? clusters_.end()
00125                : id_to_cluster_.find(id)->second );
00126     }
00127 
00128     inline ClusterPtr createCluster(int id = 0)
00129     {
00130       clusters_.push_back(ClusterType( (id<=max_cid_ ? ++max_cid_ : max_cid_ = id) ));
00131       return (id_to_cluster_[max_cid_] = --clusters_.end());
00132     }
00133 
00134     std::string colorHumanReadable(int id)
00135     {
00136       std::stringstream ss;
00137       ss << "0x" << std::setfill('0') << std::setw(6) << std::right
00138          << std::hex << id << std::dec;
00139       return ss.str();
00140     }
00141 
00142     void mapClusterColor(pcl::PointCloud<PointXYZRGB>::Ptr color_cloud)
00143     {
00144       uint32_t rgb; int t = 0;
00145       for(reverse_iterator c = clusters_.rbegin(); c != clusters_.rend(); ++c, ++t)
00146       {
00147         if (c->id() == I_NAN) { rgb = LabelColorMap::m.at(I_NAN); }
00148         else if (c->id() == I_BORDER) { rgb = LabelColorMap::m.at(I_BORDER); }
00149         else { rgb = color_tab_[t]; }
00150         for(typename ClusterType::iterator it = c->begin(); it != c->end(); ++it)
00151         { color_cloud->points[*it].rgb = *reinterpret_cast<float*>(&rgb); }
00152         c->label_color = rgb;
00153       }
00154     }
00155 
00156     void mapTypeColor(pcl::PointCloud<PointXYZRGB>::Ptr color_cloud)
00157     {
00158       uint32_t rgb;
00159       for(ClusterPtr c = clusters_.begin(); c != clusters_.end(); ++c)
00160       {
00161         rgb = LabelColorMap::m.at(c->type);
00162         for (typename ClusterType::iterator it = c->begin(); it != c->end(); ++it)
00163           color_cloud->points[*it].rgb = *reinterpret_cast<float*>(&rgb);
00164       }
00165     }
00166 
00167     virtual void addPoint(ClusterPtr c, int idx) = 0;
00168     virtual void merge(ClusterPtr source, ClusterPtr target) = 0;
00169 
00170   protected:
00171     std::list<ClusterType> clusters_;
00172     std::map<int,ClusterPtr> id_to_cluster_;
00173     int max_cid_;
00174     std::vector<int> color_tab_;
00175   };
00176 
00177 
00178   template<typename LabelT, typename PointT, typename PointNT>
00179   class DepthClusterHandler : public ClusterHandlerBase<DepthCluster>
00180   {
00181   public:
00182     typedef boost::shared_ptr<DepthClusterHandler<LabelT,PointT,PointNT> > Ptr;
00183 
00184     typedef pcl::PointCloud<LabelT> LabelCloud;
00185     typedef typename LabelCloud::Ptr LabelCloudPtr;
00186     typedef pcl::PointCloud<PointT> PointCloud;
00187     typedef typename PointCloud::ConstPtr PointCloudConstPtr;
00188     typedef pcl::PointCloud<PointNT> NormalCloud;
00189     typedef typename NormalCloud::ConstPtr NormalCloudConstPtr;
00190 
00191   public:
00192     DepthClusterHandler()
00193     { };
00194     ~DepthClusterHandler() { };
00195 
00196     void addPoint(ClusterPtr c, int idx)
00197     {
00198       c->addIndex(idx);
00199       c->sum_points_ += surface_->points[idx].getVector3fMap();
00200       c->sum_orientations_ += normals_->points[idx].getNormalVector3fMap();
00201       c->sum_rgb_(0) += surface_->points[idx].r;
00202       c->sum_rgb_(1) += surface_->points[idx].g;
00203       c->sum_rgb_(2) += surface_->points[idx].b;
00204       c->color_.addColor(surface_->points[idx].r,
00205                          surface_->points[idx].g,
00206                          surface_->points[idx].b);
00207     }
00208 
00209     inline void updateNormal(ClusterPtr c, const Eigen::Vector3f& normal) const
00210     {
00211       c->sum_orientations_ += normal;
00212     }
00213 
00214     inline void clearOrientation(ClusterPtr c) const
00215     {
00216       c->sum_orientations_ = Eigen::Vector3f::Zero();
00217     }
00218 
00219     inline void merge(ClusterPtr source, ClusterPtr target)
00220     {
00221       for (ClusterType::iterator idx = source->begin(); idx != source->end(); ++idx)
00222       {
00223         addPoint(target, *idx);
00224         labels_->points[*idx].label = target->id();
00225       }
00226       erase(source);
00227     }
00228 
00229     inline void setLabelCloudInOut(LabelCloudPtr labels) { labels_ = labels; }
00230     inline void setPointCloudIn(PointCloudConstPtr points) { surface_ = points; }
00231     inline void setNormalCloudIn(NormalCloudConstPtr normals) { normals_ = normals; }
00232 
00233     void computeClusterComponents(ClusterPtr c);
00234     void computeCurvature(ClusterPtr c);
00235     void computePointCurvature(ClusterPtr c, int search_size);
00236     bool computePrincipalComponents(ClusterPtr c);
00237     void computeNormalIntersections(ClusterPtr c);
00238     //void computeColorHistogram(ClusterPtr c);
00239 
00240     void addBorderIndicesToClusters()
00241     {
00242       int w = labels_->width;
00243       int mask[] = { -w, 1, w, -1 };
00244       int curr_label, count;
00245 
00246       for (size_t y = w; y < labels_->size() - w; y+=w)
00247       {
00248         //std::cout << "adding border points for cluster " << (*labels_)[y].label << std::endl;
00249         for (size_t i=y+1; i < y+w-1; ++i)
00250         {
00251           curr_label = (*labels_)[i].label;
00252           if(curr_label == I_NAN) continue;
00253           count = 0;
00254           for (int m=0; m<4; ++m) count += (curr_label != (*labels_)[ i+mask[m] ].label);
00255           if(count >= 4 || count < 1) continue;
00256           id_to_cluster_[curr_label]->border_points.push_back(PolygonPoint(i%w,i/w));
00257         }
00258       }
00259     }
00260 
00261     void mapClusterBorders(pcl::PointCloud<pcl::PointXYZRGB>::Ptr points)
00262     {
00263       //uint32_t color = LBL_BORDER;
00264       for (ClusterPtr c = clusters_.begin(); c != clusters_.end(); ++c)
00265       {
00266         for(std::vector<PolygonPoint>::iterator bp = c->border_points.begin();
00267             bp != c->border_points.end(); ++bp)
00268         {
00269           points->points[bp->y*points->width+bp->x].rgb = LBL_BORDER;
00270         }
00271       }
00272     }
00273 
00274     void mapClusterNormalIntersectionResults(
00275       pcl::PointCloud<pcl::PointXYZ>::Ptr ints_centroids,
00276       pcl::PointCloud<pcl::Normal>::Ptr comp1,
00277       pcl::PointCloud<pcl::Normal>::Ptr comp2,
00278       pcl::PointCloud<pcl::Normal>::Ptr comp3,
00279       pcl::PointCloud<pcl::PointXYZ>::Ptr centroids,
00280       pcl::PointCloud<pcl::Normal>::Ptr connection)
00281     {
00282       ints_centroids->width = comp1->width = comp2->width = comp3->width
00283         = centroids->width = connection->width = numClusters();
00284       ints_centroids->height = comp1->height = comp2->height = comp3->height
00285         = centroids->width = connection->height = 1;
00286       ints_centroids->resize(numClusters());
00287       comp1->resize(numClusters());
00288       comp2->resize(numClusters());
00289       comp3->resize(numClusters());
00290       centroids->resize(numClusters());
00291       connection->resize(numClusters());
00292 
00293       int i = 0;
00294       for (ClusterPtr c = clusters_.begin(); c != clusters_.end(); ++c)
00295       {
00296         if (c->type != I_CYL) continue;
00297         ints_centroids->points[i].getVector3fMap() = c->pca_inter_centroid;
00298         comp1->points[i].getNormalVector3fMap()
00299           = c->pca_inter_comp1 * c->pca_inter_values(2);
00300         comp2->points[i].getNormalVector3fMap()
00301           = c->pca_inter_comp2 * c->pca_inter_values(1);
00302         comp3->points[i].getNormalVector3fMap()
00303           = c->pca_inter_comp3 * c->pca_inter_values(0);
00304         centroids->points[i].getVector3fMap() = c->getCentroid();
00305         connection->points[i].getNormalVector3fMap()
00306           = c->pca_inter_centroid - c->getCentroid();
00307         ++i;
00308       }
00309     }
00310 
00311   private:
00312     LabelCloudPtr labels_;
00313     PointCloudConstPtr surface_;
00314     NormalCloudConstPtr normals_;
00315   };
00316 
00317 }
00318 
00319 #endif


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