cluster_classifier.hpp
Go to the documentation of this file.
00001 
00063 #ifndef __IMPL_CLUSTER_CLASSIFIER_HPP__
00064 #define __IMPL_CLUSTER_CLASSIFIER_HPP__
00065 
00066 #include "cob_3d_segmentation/cluster_classifier.h"
00067 #include <cob_3d_features/organized_normal_estimation.h>
00068 
00069 #include <pcl/common/eigen.h>
00070 
00071 #include <boost/tuple/tuple.hpp>
00072 
00073 template <typename ClusterHandlerT, typename PointT, typename NormalT, typename LabelT> void
00074 cob_3d_segmentation::ClusterClassifier<ClusterHandlerT,PointT,NormalT,LabelT>::classifyOld()
00075 {
00076   ClusterPtr c_it, c_end;
00077   for ( boost::tie(c_it,c_end) = clusters_->getClusters(); c_it != c_end; ++c_it)
00078   {
00079     if ( c_it->size() < 5 ) continue;
00080     if ( c_it->type == I_EDGE || c_it->type == I_NAN || c_it->type == I_BORDER) continue;
00081 
00082     clusters_->computeClusterComponents(c_it);
00083 
00084     if (!c_it->is_planar_)
00085     {
00086 
00087       recomputeClusterNormals(c_it);
00088       clusters_->computeCurvature(c_it);
00089       if (c_it->max_curvature < 0.02)
00090         c_it->type = I_PLANE;
00091       else if (c_it->max_curvature < 9.0 * c_it->min_curvature)
00092         c_it->type = I_SPHERE;
00093       else
00094         c_it->type = I_CYL;
00095 
00096       //c_it->type = I_CORNER;
00097     }
00098     else c_it->type = I_PLANE;
00099   }
00100 }
00101 
00102 template <typename ClusterHandlerT, typename PointT, typename NormalT, typename LabelT> void
00103 cob_3d_segmentation::ClusterClassifier<ClusterHandlerT,PointT,NormalT,LabelT>::classify()
00104 {
00105   ClusterPtr c_it, c_end;
00106   float pc_min, pc_max;
00107   test.clear();
00108   test_plane.clear();
00109   test_cyl.clear();
00110   test_sph.clear();
00111   for ( boost::tie(c_it,c_end) = clusters_->getClusters(); c_it != c_end; ++c_it)
00112   {
00113     if ( c_it->size() < 5 ) continue;
00114     if ( c_it->type == I_EDGE || c_it->type == I_NAN || c_it->type == I_BORDER) continue;
00115 
00116     clusters_->computeClusterComponents(c_it);
00117 
00118     if (!c_it->is_planar_)
00119     {
00120       int w_size = std::min( std::floor(std::sqrt(c_it->size() / 16.0f)) + 5, 30.0f );
00121       int steps = std::floor(w_size / 5);
00122       int w_size_n = std::min( std::floor(std::sqrt(c_it->size() / 16.0f)) + 8, 30.0f );
00123       int steps_n = std::floor(w_size / 5);
00124       recomputeClusterNormals(c_it, w_size_n, steps_n);
00125       std::vector<int> geometry(NUM_LABELS, 0);
00126       int valid_points = 0;
00127       for (typename ClusterType::iterator idx=c_it->begin(); idx != c_it->end(); ++idx)
00128       {
00129         Eigen::Vector3f min_direction;
00130         if (!computeClusterPointCurvature(*idx, w_size, steps, pc_min, pc_max, min_direction))
00131         {
00132           test.push_back(*idx);
00133           continue;
00134         }
00135         ++valid_points;
00136 
00137         if (pc_max < 0.01) { ++geometry[I_PLANE]; test_plane.push_back(*idx); }
00138         else if(pc_max > 9.0 * pc_min)
00139         {
00140           ++geometry[I_CYL];
00141           test_cyl.push_back(*idx);
00142           c_it->pca_inter_comp1 += min_direction;
00143         }
00144         else { ++geometry[I_SPHERE]; test_sph.push_back(*idx); }
00145       }
00146       c_it->pca_inter_comp1 = c_it->pca_inter_comp1.normalized();
00147       c_it->pca_inter_values(2) = 1.0;
00148 
00149       int max = 0; size_t max_idx = 0;
00150       for (size_t i=0; i<geometry.size(); ++i)
00151         if ( (max=std::max(max,geometry[i])) == geometry[i] ) max_idx=i;
00152 
00153       if (max == 0) { c_it->type = I_EDGE; }
00154       else
00155       {
00156         c_it->type = max_idx;
00157         c_it->type_probability = static_cast<float>(max) / static_cast<float>(valid_points);
00158         //std::cout << "Label: " << max_idx << " : #" << c_it->type_probability << std::endl;
00159 
00160           if(c_it->type_probability < 0.60) { c_it->type = I_SPHERE; }
00161           /*else
00162             {
00163             std::cout <<c_it->pca_inter_comp1(0) <<", "
00164             <<c_it->pca_inter_comp1(1) <<", "
00165             <<c_it->pca_inter_comp1(2) <<" | " << valid_points << std::endl;
00166             }*/
00167           //else { clusters_->computeNormalIntersections(c_it); }
00168 
00169       }
00170     }
00171     else c_it->type = I_PLANE;
00172   }
00173 }
00174 
00175 template <typename ClusterHandlerT, typename PointT, typename NormalT, typename LabelT> void
00176 cob_3d_segmentation::ClusterClassifier<ClusterHandlerT,PointT,NormalT,LabelT>::recomputeClusterNormals(ClusterPtr c)
00177 {
00178   int w_size = std::min( std::floor(std::sqrt(c->size() / 16.0f)) + 5, 30.0f);
00179   int steps = std::floor(w_size / 5);
00180   recomputeClusterNormals(c, w_size, steps);
00181 }
00182 
00183 template <typename ClusterHandlerT, typename PointT, typename NormalT, typename LabelT> void
00184 cob_3d_segmentation::ClusterClassifier<ClusterHandlerT,PointT,NormalT,LabelT>::recomputeClusterNormals(
00185   ClusterPtr c,
00186   int w_size,
00187   int steps)
00188 {
00189   clusters_->clearOrientation(c);
00190   for (typename ClusterType::iterator idx = c->begin(); idx != c->end(); ++ idx)
00191   {
00192     Eigen::Vector3f new_normal;
00193     cob_3d_features::OrganizedNormalEstimationHelper::computeSegmentNormal<PointT,LabelT>(
00194       new_normal, *idx, surface_, labels_, w_size, steps);
00195     normals_->points[*idx].getNormalVector3fMap() = new_normal;
00196     clusters_->updateNormal(c, new_normal);
00197   }
00198 }
00199 
00200 template <typename ClusterHandlerT, typename PointT, typename NormalT, typename LabelT> bool
00201 cob_3d_segmentation::ClusterClassifier<ClusterHandlerT,PointT,NormalT,LabelT>::computeClusterPointCurvature(
00202   int index, int r, int steps, float& pc_min, float& pc_max, Eigen::Vector3f& pc_min_direction)
00203 {
00204   const int w = surface_->width, s = surface_->height * surface_->width;
00205   const int l_idx = labels_->points[index].label;
00206 
00207   // compute mask boundary constrains first,
00208   const int w_rem = index%w;
00209   const int x_max = std::min(2*r, r + w - w_rem - 1); // max offset at each line
00210   const int y_min = std::max(index - r*w - r, w_rem - r);
00211   const int y_max = std::min(index + r*w - r, s - (w - w_rem) - r);
00212 
00213   const Eigen::Vector3f n_idx(normals_->points[index].normal);
00214   const Eigen::Matrix3f M = Eigen::Matrix3f::Identity() - n_idx * n_idx.transpose();
00215 
00216   std::vector<Eigen::Vector3f> normals_projected;
00217   Eigen::Vector3f centroid = Eigen::Vector3f::Zero();
00218 
00219   for (int y = y_min; y <= y_max; y += steps*w) // y: beginning of each line
00220   {
00221     for (int idx = y; idx < y + x_max; idx+=steps)
00222     {
00223       if ( labels_->points[idx].label != l_idx ) { continue; }
00224       NormalT const* n_i = &(normals_->points[idx]);
00225       if ( pcl_isnan(n_i->normal[2]) ) continue;
00226       normals_projected.push_back( M * n_i->getNormalVector3fMap() );
00227       centroid += normals_projected.back();
00228     }
00229   }
00230   if (normals_projected.size() < 0.5 * pow(ceil(static_cast<float>(2*r+1)/static_cast<float>(steps)), 2)) { return false; }
00231   float num_p_inv = 1.0f / normals_projected.size();
00232   centroid *= num_p_inv;
00233   Eigen::Matrix3f cov = Eigen::Matrix3f::Zero();
00234   for (std::vector<Eigen::Vector3f>::iterator n_it = normals_projected.begin(); n_it != normals_projected.end(); ++n_it)
00235   {
00236     Eigen::Vector3f demean = *n_it - centroid;
00237     cov += demean * demean.transpose();
00238   }
00239   Eigen::Vector3f eigenvalues;
00240   Eigen::Matrix3f eigenvectors;
00241   pcl::eigen33(cov, eigenvectors, eigenvalues);
00242   pc_max = eigenvalues(2) * num_p_inv;
00243   pc_min = eigenvalues(1) * num_p_inv;
00244   pc_min_direction = eigenvectors.col(1);
00245   return true;
00246 }
00247 
00248 /*
00249 template <typename ClusterHandlerT, typename PointT, typename NormalT, typename LabelT> void
00250 cob_3d_segmentation::ClusterClassifier<ClusterHandlerT,PointT,NormalT,LabelT>::computeClusterPointCurvature(ClusterPtr c)
00251 {
00252 
00253   for (typename ClusterType::iterator idx=c->begin(); idx != c->end(); ++idx)
00254   {
00255 
00256 
00257     if (eigenvalues(2) < 0.01) ++geometry[I_PLANE];
00258     else if(eigenvalues(2) < 0.11)
00259     {
00260       if(eigenvalues(2) < 7.0 * eigenvalues(1)) ++geometry[I_SPHERE];
00261       else ++geometry[I_CYL];
00262     }
00263     else ++geometry[I_UNDEF];
00264   }
00265   int max = 0; size_t max_idx = 0;
00266   for (size_t i=0; i<geometry.size(); ++i)
00267     if ( (max=std::max(max,geometry[i])) == geometry[i] ) max_idx=i;
00268   c->type = max_idx;
00269 }
00270 */
00271 
00272 #endif


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