quad_regression.h
Go to the documentation of this file.
00001 
00063 #ifndef SEGMENTATION_QUAD_REGR_H_
00064 #define SEGMENTATION_QUAD_REGR_H_
00065 
00066 
00067 #include <visualization_msgs/MarkerArray.h>
00068 #include "../point_types.h"
00069 #include "quad_regression_algo.h"
00070 
00071 namespace Segmentation
00072 {
00073 
00074 
00075   //example for parent: QPPF::QuadRegression<QPPF::Degree2, Point, QPPF::CameraModel_Kinect<Point> >
00076 
00080   template <typename Point, typename PointLabel, typename Parent>
00081   class Segmentation_QuadRegression : public GeneralSegmentation<Point, PointLabel>, public Parent
00082   {
00083 
00084     void back_check_repeat(); 
00085 
00086     boost::shared_ptr<const pcl::PointCloud<PointLabel> > compute_labeled_pc();
00087     boost::shared_ptr<const pcl::PointCloud<PointLabel> > compute_reconstructed_pc();
00088 
00089   public:
00091     virtual ~Segmentation_QuadRegression() {
00092     }
00093 
00095     virtual boost::shared_ptr<const pcl::PointCloud<PointLabel> > getOutputCloud() {
00096       return compute_labeled_pc();
00097     }
00098 
00100     virtual boost::shared_ptr<const pcl::PointCloud<PointLabel> > getReconstructedOutputCloud() {
00101       return compute_reconstructed_pc();
00102     }
00103 
00105     virtual void setInputCloud (const boost::shared_ptr<const pcl::PointCloud<Point> > &cloud)
00106     {
00107       this->Parent::setInputCloud(cloud);
00108     }
00109 
00110     virtual bool compute();
00111 
00112     virtual bool extractImages();
00113 
00115     operator cob_3d_mapping_msgs::ShapeArray() const;
00116 
00118     operator visualization_msgs::Marker() const;
00119 
00120     /*** evaluation purposes ***/
00121     void compute_accuracy(float &mean, float &var, float &mean_weighted, float &var_weighted, size_t &used, size_t &mem, size_t &points, float &avg_dist, const boost::shared_ptr<const pcl::PointCloud<PointLabel> > &labeled_pc, double &true_positive, double &false_positive);
00122 
00124     std::istream &serialize(std::istream &is);
00126     std::ostream &serialize(std::ostream &is) const;
00127   };
00128 
00129 #include "impl/quad_regression.hpp"
00130 
00131 #if 0
00132 
00133 #define getInd(x, y) ((x)+(y)*levels_[i].w)
00134 #define getInd1(x, y) ((x)+(y)*levels_[i-1].w)
00135 #define getInd2(x, y) ((x)+(y)*levels_[i+2].w)
00136 #define getInd3(x, y) ((x)+(y)*levels_[i+1].w)
00137 #define getIndPC(x, y) ((x)+(y)*pc.width)
00138 
00142   template <typename Point, typename PointLabel>
00143   class Segmentation_QuadRegression : public GeneralSegmentation<Point, PointLabel>
00144   {
00145     //------------STRUCTURES-----------
00146 
00150     struct SKINECTPARAMS {
00151       float f,dx,dy;
00152     };
00153 
00154     //-----------CONSTANTS-------------
00155     const unsigned int MIN_LOD; 
00156     const unsigned int FINAL_LOD; 
00157     const unsigned int GO_DOWN_TO_LVL; 
00158 
00159     //------------MEMBERS---------------
00160     boost::shared_ptr<const pcl::PointCloud<Point> > input_;
00161 
00162     std::vector<SubStructure::ParamC> levels_; 
00163     std::vector<Segmentation::S_POLYGON> polygons_;
00164     int *ch_; 
00165     SKINECTPARAMS kinect_params_; 
00166 
00167     bool *outline_check_;         
00168     size_t outline_check_size_;    
00169     float filter_;                
00170     bool only_planes_;            
00171 
00172 #ifdef STOP_TIME
00173     double execution_time_quadtree_, execution_time_growing_, execution_time_polyextraction_;
00174 #endif
00175 
00176     void prepare(const pcl::PointCloud<Point> &pc); 
00177     void getKinectParams(const pcl::PointCloud<Point> &pc); 
00178 
00179     void buildTree(const pcl::PointCloud<Point> &pc); 
00180     void calc(); 
00181     void back_check_repeat(); 
00182 
00183     void grow(SubStructure::Model &model, const int i, const int x, const int y);
00184     void grow(SubStructure::VISITED_LIST<SubStructure::SVALUE> &list, SubStructure::Model &model, const int i, const int mark, bool first_lvl);
00185 
00186     inline bool filterOccupied(const int i, const int x, const int y, const int mark) const {
00187       if(i>=(int)levels_.size())
00188         return false;
00189       if(levels_[i].data[getInd(x,y)].occopied==mark)
00190         return true;
00191       return filterOccupied(i+1,x/2,y/2,mark);
00192     }
00193 
00194     inline int otherOccupied(const int i, const int x, const int y, const int mark) const {
00195       if(i>=(int)levels_.size() || x<0 || y<0 || x>=(int)levels_[i].w || y>=(int)levels_[i].h)
00196         return -1;
00197       if(levels_[i].data[getInd(x,y)].occopied>=0 && levels_[i].data[getInd(x,y)].occopied!=mark)
00198         return levels_[i].data[getInd(x,y)].occopied;
00199       return otherOccupied(i+1,x/2,y/2,mark);
00200     }
00201 
00202     inline int isOccupied(const int i, const int x, const int y) const {
00203       if(i>=(int)levels_.size())
00204         return -1;
00205       if(levels_[i].data[getInd(x,y)].occopied>=0)
00206         return levels_[i].data[getInd(x,y)].occopied;
00207       return isOccupied(i+1,x/2,y/2);
00208     }
00209 
00210     inline bool checkModelAt(const SubStructure::Model &model, const int i, const int x, const int y, const float thr) const {
00211       if(i==0)
00212         return model.check_tangent(levels_[i].data[getInd(x,y)], thr);
00213 
00214       return //model.check(levels_[i].data[getInd(x,y)], thr) &&
00215           model.check_tangent(levels_[i-1].data[getInd1(2*x,2*y)], thr) &&
00216           model.check_tangent(levels_[i-1].data[getInd1(2*x,2*y+1)], thr) &&
00217           model.check_tangent(levels_[i-1].data[getInd1(2*x+1,2*y)], thr) &&
00218           model.check_tangent(levels_[i-1].data[getInd1(2*x+1,2*y+1)], thr);
00219     }
00220 
00221     inline void addPoint(const int i, const int x, const int y, const int mark, S_POLYGON &poly, const SubStructure::Model &model, const float v=0.f) {
00222 
00223 #if 0
00224       for(int xx=-1; xx<2; xx++)
00225         for(int yy=-1; yy<2; yy++)
00226           if(x+xx>=0 && y+yy>=0 && x+xx<(int)levels_[i].w && y+yy<(int)levels_[i].h
00227               && filterOccupied(i,x+xx,y+yy,mark) //&& (levels_[i].data[getInd(x+xx,y+yy)].occopied==mark||levels_[i+1].data[getInd3((x+xx)/2,(y+yy)/2)].occopied==mark)
00228       //&& poly.model_.check_tangent(levels_[i].data[getInd(x+xx,y+yy)],0.02f)
00229           ){
00230             Eigen::Vector3f p;
00231             p(0) = levels_[i].data[getInd(x+xx,y+yy)].model_(0,1)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00232             p(1) = levels_[i].data[getInd(x+xx,y+yy)].model_(0,3)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00233             p(2) = levels_[i].data[getInd(x+xx,y+yy)].z_(0)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00234 
00235 
00236             //            Eigen::Vector3f p = poly.project2plane(levels_[i].data[getInd(x+xx,y+yy)].model_(0,1)/levels_[i].data[getInd(x+xx,y+yy)].z_(0),
00237             //                                                   levels_[i].data[getInd(x+xx,y+yy)].model_(0,3)/levels_[i].data[getInd(x+xx,y+yy)].z_(0),
00238             //                                                   model,v);
00239 
00240             p.head<2>() = poly.nextPoint(p);
00241             /*
00242 Eigen::Vector2f vv;
00243       vv(0) = (p-poly.param_.col(0)).dot(poly.proj2plane_.col(0))/poly.proj2plane_.col(0).squaredNorm();
00244       vv(1) = (p-poly.param_.col(0)).dot(poly.proj2plane_.col(1))/poly.proj2plane_.col(1).squaredNorm();
00245             p.head<2>() = vv;*/
00246 
00247             if(!pcl_isfinite(p.sum())) continue;
00248             p(2) = v;
00249             poly.segments_.back().push_back(p);
00250             return;
00251           }
00252       for(int xx=-1; xx<2; xx++)
00253         for(int yy=-1; yy<2; yy++)
00254           if(x+xx>=0 && y+yy>=0 && x+xx<(int)levels_[i].w && y+yy<(int)levels_[i].h
00255               && poly.model_.check_tangent(levels_[i].data[getInd(x+xx,y+yy)],0.02f)){
00256             Eigen::Vector3f p;
00257             p(0) = levels_[i].data[getInd(x+xx,y+yy)].model_(0,1)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00258             p(1) = levels_[i].data[getInd(x+xx,y+yy)].model_(0,3)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00259             p(2) = levels_[i].data[getInd(x+xx,y+yy)].z_(0)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00260             /*            p.head<2>() = poly.nextPoint(p);
00261 
00262 Eigen::Vector2f vv;
00263       vv(0) = (p-poly.param_.col(0)).dot(poly.proj2plane_.col(0))/poly.proj2plane_.col(0).squaredNorm();
00264       vv(1) = (p-poly.param_.col(0)).dot(poly.proj2plane_.col(1))/poly.proj2plane_.col(1).squaredNorm();
00265             p.head<2>() = vv;
00266              */
00267             if(!pcl_isfinite(p.sum())) continue;
00268             p(2) = v;
00269             poly.segments_.back().push_back(p);
00270             return;
00271           }
00272 
00273       //      for(int xx=-2; xx<3; xx++)
00274       //        for(int yy=-2; yy<3; yy++)
00275       //          if(x+xx>=0 && y+yy>=0 && x+xx<levels_[i].w && y+yy<levels_[i].h && levels_[i].data[getInd(x+xx,y+yy)].occopied==mark){
00276       //            Eigen::Vector3f p;
00277       //            p(0) = levels_[i].data[getInd(x+xx,y+yy)].model_(0,1)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00278       //            p(1) = levels_[i].data[getInd(x+xx,y+yy)].model_(0,3)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00279       //            p(2) = levels_[i].data[getInd(x+xx,y+yy)].z_(0)/levels_[i].data[getInd(x+xx,y+yy)].model_(0,0);
00280       //            //p.head<2>() = poly.nextPoint(p);
00281       //
00282       //            p.head<2>() -= poly.getCenter();
00283       //            p(0)/=poly.proj2plane_(0,0);
00284       //            p(1)/=poly.proj2plane_(1,1);
00285       //
00286       //            if(!pcl_isfinite(p.sum())) continue;
00287       //            p(2) = v;
00288       //            poly.segments_.back().push_back(p);
00289       //            return;
00290       //          }
00291 #endif
00292 
00293 #ifdef DO_NOT_DOWNSAMPLE_
00294       const int fact=1;
00295 #else
00296       const int fact=2;
00297 #endif
00298 
00299       /*{
00300         Eigen::Vector3f p = poly.project2plane(((x<<(i+fact-1))-kinect_params_.dx)/kinect_params_.f,
00301                                                ((y<<(i+fact-1))-kinect_params_.dy)/kinect_params_.f,
00302                                                model,v);
00303       poly.segments_.back().push_back(p);
00304 #ifdef USE_BOOST_POLYGONS_
00305 poly.segments2d_.back().push_back(BoostPoint(x,y));
00306 #elif defined(BACK_CHECK_REPEAT)
00307 Eigen::Vector2i p2;
00308 p2(0) = x;
00309 p2(1) = y;
00310 poly.segments2d_.back().push_back(p2);
00311 #endif
00312       }
00313       return;*/
00314 
00315       Eigen::Vector3f p = poly.project2plane(((x<<(i+fact-1))-kinect_params_.dx)/kinect_params_.f,
00316                                              ((y<<(i+fact-1))-kinect_params_.dy)/kinect_params_.f,
00317                                              model,v);
00318 
00319 #if 0
00320       poly.segments_.back().push_back(p);
00321 #ifdef USE_BOOST_POLYGONS_
00322       poly.segments2d_.back().push_back(BoostPoint(x,y));
00323 #elif defined(BACK_CHECK_REPEAT)
00324       Eigen::Vector2i p2;
00325       p2(0) = x;
00326       p2(1) = y;
00327       poly.segments2d_.back().push_back(p2);
00328 #endif
00329 
00330       return;
00331 #endif
00332 
00333       Eigen::Vector3f vp = poly.project2world(p.head<2>());
00334 
00335       float d = poly.middle_(2);
00336       d*=d;
00337 
00338       static const int rel_motion_pattern[][2] = { {0,0}, {-1,-1}, {-1,0}, {-1,1}, {0,-1}, {0,1}, {1,-1}, {1,0}, {1,1}
00339       //, {-2,-2}, {-2,-1}, {-2,0}, {-2,1}, {-2,2}, {-1,-2}, {-1,2}, {0,-2}, {0,2}, {1,-2}, {1,2}, {2,-2}, {2,-1}, {2,0}, {2,1}, {2,2}
00340       //, {-3,-3}, {-3,-2}, {-3,-1}, {-3,0}, {-3,1}, {-3,2}, {-3,3}, {-2,-3}, {-2,3}, {-1,-3}, {-1,3}, {0,-3}, {0,3}, {1,-3}, {1,3}, {2,-3}, {2,3}, {3,-3}, {3,-2}, {3,-1}, {3,0}, {3,1}, {3,2}, {3,3}, {-4,-4}, {-4,-3}, {-4,-2}, {-4,-1}, {-4,0}, {-4,1}, {-4,2}, {-4,3}, {-4,4}, {-3,-4}, {-3,4}, {-2,-4}, {-2,4}, {-1,-4}, {-1,4}, {0,-4}, {0,4}, {1,-4}, {1,4}, {2,-4}, {2,4}, {3,-4}, {3,4}, {4,-4}, {4,-3}, {4,-2}, {4,-1}, {4,0}, {4,1}, {4,2}, {4,3}, {4,4}
00341       };
00342 
00343 
00344       const pcl::PointCloud<Point> &pc = *input_;
00345       //      for(int xx=-4; xx<5; xx++)
00346       //        for(int yy=-4; yy<5; yy++)
00347       for(size_t i=0; i<sizeof(rel_motion_pattern)/sizeof(rel_motion_pattern[0]); i++) {
00348         int xx=rel_motion_pattern[i][0];
00349         int yy=rel_motion_pattern[i][1];
00350 
00351         if(fact*x+xx>=0 && fact*y+yy>=0 && fact*x+xx<(int)pc.width && fact*y+yy<(int)pc.height) {
00352           Eigen::Vector3f p = poly.project2plane((((fact*x+xx)<<(i))-kinect_params_.dx)/kinect_params_.f,
00353                                                  (((fact*y+yy)<<(i))-kinect_params_.dy)/kinect_params_.f,
00354                                                  model,v);
00355 
00356           if( (poly.project2world(p.head<2>())-pc[getIndPC(fact*x+xx,fact*y+yy)].getVector3fMap()).squaredNorm()<std::max(0.0005f,0.0005f*d)
00357           && (poly.project2world(p.head<2>())-vp).squaredNorm()<0.02f)
00358           {
00359             poly.segments_.back().push_back(p);/*
00360           Eigen::Vector2f p = poly.nextPoint(pc[getIndPC(fact*x+xx,fact*y+yy)].getVector3fMap());
00361 
00362           if( (poly.project2world(p)-pc[getIndPC(fact*x+xx,fact*y+yy)].getVector3fMap()).squaredNorm()<std::max(0.0005f,0.0005f*d)
00363           && (poly.project2world(p)-vp).squaredNorm()<0.02f
00364           )
00365           {
00366             Eigen::Vector3f p3;
00367             p3.head<2>()=p;
00368             poly.segments_.back().push_back(p3);*/
00369 
00370             //            std::cout<<"P\n"<<poly.project2world(p.head<2>())<<"\n";
00371             //            std::cout<<"C\n"<<pc[getIndPC(2*x+xx,2*y+yy)].getVector3fMap()<<"\n";
00372 
00373 #ifdef USE_BOOST_POLYGONS_
00374             poly.segments2d_.back().push_back(BoostPoint(x,y));
00375 #elif defined(BACK_CHECK_REPEAT)
00376             Eigen::Vector2i p2;
00377             p2(0) = x+xx/fact;
00378             p2(1) = y+yy/fact;
00379             poly.segments2d_.back().push_back(p2);
00380 #endif
00381 
00382             return;
00383           }
00384         }
00385 
00386       }
00387 #if 0
00388       for(int xx=-8; xx<9; xx++)
00389         for(int yy=-8; yy<9; yy++)
00390           if(fact*x+xx>=0 && fact*y+yy>=0 && fact*x+xx<(int)pc.width && fact*y+yy<(int)pc.height) {
00391             Eigen::Vector3f p = poly.project2plane((((fact*x+xx)<<(i))-kinect_params_.dx)/kinect_params_.f,
00392                                                    (((fact*y+yy)<<(i))-kinect_params_.dy)/kinect_params_.f,
00393                                                    model,v);
00394 
00395             if( (poly.project2world(p.head<2>())-pc[getIndPC(fact*x+xx,fact*y+yy)].getVector3fMap()).squaredNorm()<std::max(0.0005f,0.0005f*d)
00396             && (poly.project2world(p.head<2>())-vp).squaredNorm()<0.02f)
00397             {
00398               poly.segments_.back().push_back(p);
00399 
00400               //            std::cout<<"P\n"<<poly.project2world(p.head<2>())<<"\n";
00401               //            std::cout<<"C\n"<<pc[getIndPC(2*x+xx,2*y+yy)].getVector3fMap()<<"\n";
00402 
00403               //            std::cout<<"P\n"<<poly.project2world(p.head<2>())<<"\n";
00404               //            std::cout<<"C\n"<<pc[getIndPC(2*x+xx,2*y+yy)].getVector3fMap()<<"\n";
00405 
00406 #ifdef USE_BOOST_POLYGONS_
00407               poly.segments2d_.back().push_back(BoostPoint(x,y));
00408 #elif defined(BACK_CHECK_REPEAT)
00409               Eigen::Vector2i p2;
00410               p2(0) = x+xx/fact;
00411               p2(1) = y+yy/fact;
00412               poly.segments2d_.back().push_back(p2);
00413 #endif
00414 
00415               return;
00416             }
00417           }
00418 #endif
00419 
00420       if(poly.normalAt(p.head<2>())(2)>0.5f)
00421       {
00422         poly.segments_.back().push_back(p);
00423 #ifdef USE_BOOST_POLYGONS_
00424         poly.segments2d_.back().push_back(BoostPoint(x,y));
00425 #elif defined(BACK_CHECK_REPEAT)
00426         Eigen::Vector2i p2;
00427         p2(0) = x;
00428         p2(1) = y;
00429         poly.segments2d_.back().push_back(p2);
00430 #endif
00431       }
00432     }
00433 
00434     int getPos(int *ch, const int xx, const int yy, const int w, const int h);
00435 
00436     void outline(int *ch, const int w, const int h, std::vector<SubStructure::SXY> &out, const int i, S_POLYGON &poly, const SubStructure::Model &model, const int mark);
00437 
00438     boost::shared_ptr<const pcl::PointCloud<PointLabel> > compute_labeled_pc();
00439     boost::shared_ptr<const pcl::PointCloud<PointLabel> > compute_reconstructed_pc();
00440 
00441   public:
00443     Segmentation_QuadRegression();
00444 
00446     virtual ~Segmentation_QuadRegression() {
00447       delete [] ch_;
00448       delete [] outline_check_;
00449     }
00450 
00452     virtual void setInputCloud (const boost::shared_ptr<const pcl::PointCloud<Point> > &cloud)
00453     {
00454       input_ = cloud;
00455       if(levels_.size()==0)
00456         prepare(*cloud);
00457       else if(kinect_params_.f == 0.f)
00458         getKinectParams(*cloud);
00459     }
00460 
00462     virtual boost::shared_ptr<const pcl::PointCloud<PointLabel> > getOutputCloud() {
00463       return compute_labeled_pc();
00464     }
00465 
00467     virtual boost::shared_ptr<const pcl::PointCloud<PointLabel> > getReconstructedOutputCloud() {
00468       return compute_reconstructed_pc();
00469     }
00470 
00471     virtual bool compute();
00472 
00473     virtual bool extractImages();
00474 
00476     operator cob_3d_mapping_msgs::ShapeArray() const;
00477 
00479     operator visualization_msgs::Marker() const;
00480 
00482     const std::vector<Segmentation::S_POLYGON> &getPolygons() const {return polygons_;}
00483 
00484     /*** evaluation purposes ***/
00485     void compute_accuracy(float &mean, float &var, size_t &used, size_t &mem, size_t &points, float &avg_dist);
00486 
00487 #ifdef STOP_TIME
00488     void getExecutionTimes(double &quadtree, double &growing, double &extraction)
00489     {
00490       quadtree = execution_time_quadtree_;
00491       extraction = execution_time_polyextraction_;
00492       growing = execution_time_growing_ - extraction;
00493     }
00494 #endif
00495 
00496     void setFilter(const float f) {filter_=f;}
00497     void setOnlyPlanes(const bool b) {only_planes_=b;}
00498 
00499   };
00500 
00501 #include "impl/quad_regression.hpp"
00502 
00503 #undef getInd
00504 #undef getInd1
00505 #undef getInd2
00506 #undef getIndPC
00507 #endif
00508 }
00509 
00510 #endif /* SEGMENTATION_QUAD_REGR_H_ */


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