quad_regression_algo.hpp
Go to the documentation of this file.
00001 /*
00002  * quad_regression_algo.hpp
00003  *
00004  *  Created on: 14.02.2013
00005  *      Author: josh
00006  */
00007 
00008 #include "../sub_structures/poly2d.hpp"
00009 
00010 #include <cob_3d_mapping_common/stop_watch.h>
00011 
00012 // ------------- CAMERA MODEL -------------
00013 
00014 
00015 
00016 template <typename Point>
00017 void CameraModel_Kinect<Point>::getParams(const pcl::PointCloud<Point> &pc) {
00018   if(f != 0.f) return;
00019 
00020   Point p1, p2;
00021   p1=p1;
00022   p2=p2;
00023   int i1=-1, i2=-1;
00024 
00025   // find one point
00026   for(size_t x=0; x<pc.width; x+=8) {
00027     for(size_t y=0; y<pc.height; y+=8) {
00028       int ind = ((x)+(y)*pc.width);
00029       if(pcl_isfinite(pc[ind].z)&&pc[ind].z<10.f) {
00030         p1=pc[ind];
00031         i1=ind;
00032         x=pc.width;
00033         break;
00034       }
00035     }
00036   }
00037 
00038   // find another point
00039   for(int x=pc.width-1; x>=0; x-=8) {
00040     for(int y=pc.height-1; y>=0; y-=8) {
00041       int ind = ((x)+(y)*pc.width);
00042       if(pcl_isfinite(pc[ind].z)&&pc[ind].z!=p1.z&&pc[ind].z<10.f) {
00043         p2=pc[ind];
00044         i2=ind;
00045         x=-1;
00046         break;
00047       }
00048     }
00049   }
00050 
00051   if(i1==-1||i2==-1) {
00052     ROS_WARN("no valid points");
00053     return;
00054   }
00055 
00056   //solve equation $...$ to retrieve f, dx and dy of camera
00057   int x=i1%pc.width;
00058   int y=i1/pc.width;
00059   float ax1,ax2, bx1,bx2;
00060   float ay1,ay2, by1,by2;
00061 
00062   ax1=p1.z/p1.x*x;
00063   bx1=p1.z/p1.x;
00064   ay1=p1.z/p1.y*y;
00065   by1=p1.z/p1.y;
00066 
00067   x=i2%pc.width;
00068   y=i2/pc.width;
00069   ax2=p2.z/p2.x*x;
00070   bx2=p2.z/p2.x;
00071   ay2=p2.z/p2.y*y;
00072   by2=p2.z/p2.y;
00073 
00074   dx = (ax1-ax2)/(bx1-bx2);
00075   dy = (ay1-ay2)/(by1-by2);
00076   f = ax1 - bx1*dx;
00077 }
00078 
00079 
00080 
00081 template <typename Point>
00082 void CameraModel_SR4500<Point>::getParams(const pcl::PointCloud<Point> &pc) {
00083   if(f != 0.f) return;
00084 
00085   dx = 176/2;
00086   dy = 144/2;
00087   f = 1/std::tan(0.39f*M_PI/180);
00088 }
00089 
00090 // ------------- QUAD REGRESSION -------------
00091 
00092 template <int Degree, typename Point, typename CameraModel>
00093 QuadRegression<Degree, Point, CameraModel>::QuadRegression():
00094 #ifdef SICK
00095 MIN_LOD(4), FINAL_LOD(0), GO_DOWN_TO_LVL(4),
00096 #else
00097 MIN_LOD(8), FINAL_LOD(0), GO_DOWN_TO_LVL(3),
00098 #endif
00099 ch_(NULL), outline_check_(0), outline_check_size_(0),
00100 filter_(-1.f), only_planes_(false)
00101 {
00102   Contour2D::generateSpline2D();
00103 }
00104 
00105 
00106 template <int Degree, typename Point, typename CameraModel>
00107 bool QuadRegression<Degree, Point, CameraModel>::compute() {
00108   polygons_.clear();
00109   this->buildTree(*input_);
00110   calc();
00111   return true;
00112 }
00113 
00114 
00115 template <int Degree, typename Point, typename CameraModel>
00116 void QuadRegression<Degree, Point, CameraModel>::prepare(const pcl::PointCloud<Point> &pc) {
00117   int w=input_->width;
00118   int h=input_->height;
00119 
00120   if(w<=1||h<=1) {
00121     ROS_ERROR("need ordered pointcloud");
00122     return;
00123   }
00124 
00125   for(int i=0; i<5; i++){
00126     levels_.push_back(SubStructure::ParamC<Degree>(w,h));
00127 
00128     w/=2;
00129     h/=2;
00130   }
00131 
00132   ch_=new int[levels_[0].w*levels_[0].h];
00133   memset(ch_,0,levels_[0].w*levels_[0].h*4);
00134 }
00135 
00136 
00137 template <int Degree, typename Point, typename CameraModel>
00138 void QuadRegression_Downsampled<Degree, Point, CameraModel>::prepare(const pcl::PointCloud<Point> &pc) {
00139   int w=this->input_->width/2;
00140   int h=this->input_->height/2;
00141 
00142   if(w<=1||h<=1) {
00143     ROS_ERROR("need ordered pointcloud");
00144     return;
00145   }
00146 
00147   for(int i=0; i<4; i++){
00148     this->levels_.push_back(SubStructure::ParamC<Degree>(w,h));
00149 
00150     w/=2;
00151     h/=2;
00152   }
00153 
00154   this->ch_=new int[this->levels_[0].w*this->levels_[0].h];
00155   memset(this->ch_,0,this->levels_[0].w*this->levels_[0].h*4);
00156 }
00157 
00158 
00159 template <int Degree, typename Point, typename CameraModel>
00160 void QuadRegression<Degree, Point, CameraModel>::buildTree(const pcl::PointCloud<Point> &pc) {
00161 #ifdef STOP_TIME
00162   PrecisionStopWatch ssw;
00163   ssw.precisionStart();
00164 #endif
00165 
00166   //go through all levels
00167   for(size_t i=0; i<levels_.size(); i++) {
00168 
00169     SubStructure::ParamC<Degree> *lvl = &levels_[i];
00170     if(i==0) {  
00171       Eigen::Vector3f v;
00172       int j = 0;
00173       for(size_t y=0; y<lvl->h; y++) {
00174         for(size_t x=0; x<lvl->w; x++) {
00175           v(0) = pc[j].x;
00176           v(1) = pc[j].y;
00177           v(2) = pc[j].z;
00178           lvl->data[j]=v;
00179           lvl->data[j].occopied=-1;
00180 
00181           ++j;
00182         }
00183       }
00184     }
00185     else { //other levels take lower level
00186       SubStructure::ParamC<Degree> *lvl_prev = &levels_[i-1];
00187 
00188       int j=0, k=0;
00189       for(size_t y=0; y<lvl->h; y++) {
00190         for(size_t x=0; x<lvl->w; x++) {
00191           //j=getInd(x,y);
00192           lvl->data[j] = lvl_prev->data[k];    //getInd(i-1, x*2,y*2)
00193           lvl->data[j]+= lvl_prev->data[k+1]; //getInd(i-1, x*2,y*2+1)
00194           lvl->data[j]+= lvl_prev->data[k+levels_[i-1].w];    //getInd(i-1, x*2+1,y*2)
00195           lvl->data[j]+= lvl_prev->data[k+levels_[i-1].w+1];        //getInd(i-1, x*2+1,y*2+1)
00196           ++j;
00197           k+=2;
00198         }
00199         k+=levels_[i-1].w;
00200       }
00201     }
00202 
00203   }
00204 
00205 #ifdef STOP_TIME
00206   execution_time_quadtree_ = ssw.precisionStop();
00207 #endif
00208 }
00209 
00210 
00211 template <int Degree, typename Point, typename CameraModel>
00212 void QuadRegression_Downsampled<Degree, Point, CameraModel>::buildTree(const pcl::PointCloud<Point> &pc) {
00213 #ifdef STOP_TIME
00214   PrecisionStopWatch ssw;
00215   ssw.precisionStart();
00216 #endif
00217 
00218   //go through all levels
00219   for(size_t i=0; i<this->levels_.size(); i++) {
00220 
00221     SubStructure::ParamC<Degree> *lvl = &this->levels_[i];
00222     if(i==0) {  
00223       Eigen::Vector3f p,t;
00224       int j = 0;
00225       for(size_t y=0; y<lvl->h; y++) {
00226         for(size_t x=0; x<lvl->w; x++) {
00227           int num=0;
00228           p(0)=p(1)=p(2)=0.f;
00229 
00230           // sub-sample 4 points to one
00231           j=this->getIndPC(pc.width, 2*x,2*y);
00232           if(pcl_isfinite(pc[j].z))
00233           {
00234             p(0)+=pc[j].x;
00235             p(1)+=pc[j].y;
00236             p(2)+=pc[j].z;
00237             ++num;
00238           }
00239 
00240           j=this->getIndPC(pc.width, 2*x,2*y+1);
00241           if(pcl_isfinite(pc[j].z))
00242           {
00243             p(0)+=pc[j].x;
00244             p(1)+=pc[j].y;
00245             p(2)+=pc[j].z;
00246             ++num;
00247           }
00248 
00249           j=this->getIndPC(pc.width, 2*x+1,2*y);
00250           if(pcl_isfinite(pc[j].z))
00251           {
00252             p(0)+=pc[j].x;
00253             p(1)+=pc[j].y;
00254             p(2)+=pc[j].z;
00255             ++num;
00256           }
00257 
00258           j=this->getIndPC(pc.width, 2*x+1,2*y+1);
00259           if(pcl_isfinite(pc[j].z))
00260           {
00261             p(0)+=pc[j].x;
00262             p(1)+=pc[j].y;
00263             p(2)+=pc[j].z;
00264             ++num;
00265           }
00266 
00267           //revalidate
00268           j=this->getIndPC(pc.width, 2*x,2*y);
00269           if((pc[j].getVector3fMap()-p/num).squaredNorm()>0.005f)
00270           {
00271             p(0)-=pc[j].x;
00272             p(1)-=pc[j].y;
00273             p(2)-=pc[j].z;
00274             --num;
00275           }
00276 
00277           j=this->getIndPC(pc.width, 2*x,2*y+1);
00278           if((pc[j].getVector3fMap()-p/num).squaredNorm()>0.005f)
00279           {
00280             p(0)-=pc[j].x;
00281             p(1)-=pc[j].y;
00282             p(2)-=pc[j].z;
00283             --num;
00284           }
00285 
00286           j=this->getIndPC(pc.width, 2*x+1,2*y);
00287           if((pc[j].getVector3fMap()-p/num).squaredNorm()>0.005f)
00288           {
00289             p(0)-=pc[j].x;
00290             p(1)-=pc[j].y;
00291             p(2)-=pc[j].z;
00292             --num;
00293           }
00294 
00295           j=this->getIndPC(pc.width, 2*x+1,2*y+1);
00296           if((pc[j].getVector3fMap()-p/num).squaredNorm()>0.005f)
00297           {
00298             p(0)-=pc[j].x;
00299             p(1)-=pc[j].y;
00300             p(2)-=pc[j].z;
00301             --num;
00302           }
00303 
00304           j=this->getInd(i,x,y);
00305           lvl->data[j]=p/num;
00306 
00307           lvl->data[j].occopied=-1;
00308         }
00309       }
00310     }
00311     else { //other levels take lower level
00312       SubStructure::ParamC<Degree> *lvl_prev = &this->levels_[i-1];
00313 
00314       int j=0, k=0;
00315       for(size_t y=0; y<lvl->h; y++) {
00316         for(size_t x=0; x<lvl->w; x++) {
00317           //j=getInd(x,y);
00318           lvl->data[j] = lvl_prev->data[k];    //getInd(i-1, x*2,y*2)
00319           lvl->data[j]+= lvl_prev->data[k+1]; //getInd(i-1, x*2,y*2+1)
00320           lvl->data[j]+= lvl_prev->data[k+this->levels_[i-1].w];    //getInd(i-1, x*2+1,y*2)
00321           lvl->data[j]+= lvl_prev->data[k+this->levels_[i-1].w+1];        //getInd(i-1, x*2+1,y*2+1)
00322           ++j;
00323           k+=2;
00324         }
00325         k+=this->levels_[i-1].w;
00326       }
00327     }
00328 
00329   }
00330 
00331 #ifdef STOP_TIME
00332   this->execution_time_quadtree_ = ssw.precisionStop();
00333 #endif
00334 }
00335 
00336 
00337 template <int Degree, typename Point, typename CameraModel>
00338 void QuadRegression<Degree, Point, CameraModel>::calc() {
00339 
00340 #ifdef STOP_TIME
00341   execution_time_polyextraction_=0.;
00342   PrecisionStopWatch ssw;
00343   ssw.precisionStart();
00344 #endif
00345 
00346   for(int i=(int)levels_.size()-1; i>(int)(levels_.size()-GO_DOWN_TO_LVL); i--) {
00347 
00348     //from one corner to the other
00349     size_t sx=0, sy=0;
00350     while(sx<levels_[i].w-1 && sy<levels_[i].h-1) {
00351       for(int x=sx+1; x<(int)levels_[i].w-1; x++) {
00352         if(isOccupied(i,x,sy)==-1)
00353         {
00354           SubStructure::Model<Degree> m;
00355           grow(m, i, x,sy);
00356         }
00357       }
00358       sx+=2;
00359 
00360       for(size_t y=sy+1; y<levels_[i].h-1; y++) {
00361         if(isOccupied(i,sx,y)==-1)
00362         {
00363           SubStructure::Model<Degree> m;
00364           grow(m, i, sx,y);
00365         }
00366       }
00367       sy+=2;
00368     }
00369     /*
00370     //from one corner to the other
00371     size_t sx=0, sy=0;
00372     while(sx<levels_[i].w-1 && sy<levels_[i].h-1) {
00373       for(int x=sx+1; x<(int)levels_[i].w-1; x++) {
00374         //if(isOccupied2(i,x,sy)==-1&&!checkOccupiedDeep(i,x,sy))
00375         if(isOccupied(i,levels_[i].w-1-x,sy)==-1)
00376         {
00377           SubStructure::Model<Degree> m;
00378           grow(m, i, levels_[i].w-1-x,sy);
00379         }
00380       }
00381       sx+=2;
00382 
00383       for(size_t y=sy+1; y<levels_[i].h-1; y++) {
00384         //if(isOccupied2(i,sx,y)==-1&&!checkOccupiedDeep(i,sx,y))
00385         if(isOccupied(i,levels_[i].w-1-sx,y)==-1)
00386         {
00387           SubStructure::Model<Degree> m;
00388           grow(m, i, levels_[i].w-1-sx,y);
00389         }
00390       }
00391       sy+=2;
00392     }
00393 */
00394 
00395   }
00396 
00397 #ifdef STOP_TIME
00398   execution_time_growing_ = ssw.precisionStop();
00399 #endif
00400 
00401   //preparePolygons();
00402 }
00403 
00404 
00405 template <int Degree, typename Point, typename CameraModel>
00406 void QuadRegression<Degree, Point, CameraModel>::grow(SubStructure::Model<Degree> &model, const int i, const int x, const int y) {
00407   static SubStructure::VISITED_LIST<SubStructure::SVALUE> list;
00408   list.init();
00409   list.add( SubStructure::SVALUE(getInd(i,x,y),levels_[i].w*levels_[i].h) );
00410 
00411   grow(list, model, i, polygons_.size(), true);
00412 }
00413 
00414 template <int Degree, typename Point, typename CameraModel>
00415 void QuadRegression<Degree, Point, CameraModel>::grow(SubStructure::VISITED_LIST<SubStructure::SVALUE> &list, SubStructure::Model<Degree> &model, const int i, const int mark, bool first_lvl) {
00416   int x, y, hops, occ;
00417   unsigned int found=0;
00418   bool bNew,bNew2;
00419   int last_size=-1;
00420 #ifdef CHECK_CONNECTIVITY
00421   S_POLYGON_CONNECTIVITY connectivity;
00422 #endif
00423 
00424   do {
00425     bNew=false;
00426     bNew2=false;
00427     while(list.pos+1<list.size) {
00428       list.move();
00429 
00430       x= list.vals[list.pos].v%levels_[i].w;
00431       y= list.vals[list.pos].v/levels_[i].w;
00432       hops = list.vals[list.pos].hops;
00433 
00434       occ = isOccupied(i,x,y);
00435       if(occ==mark) {
00436         if(list.pos>last_size&&hops) list.remove();
00437         continue;
00438       }
00439       else if(occ!=-1) {
00440 #ifdef CHECK_CONNECTIVITY
00441         if(/*i==FINAL_LOD && */checkModelAt(model, i,x,y,
00442                                             0.02)) { //TODO: check threshold
00443           while(occ>=connectivity.connections_.size())
00444             connectivity.connections_.push_back(0);
00445           connectivity.connections_[occ]+=(1<<i);
00446         }
00447 #endif
00448         continue;
00449       }
00450 
00451       float d=std::min(
00452           std::abs(levels_[i].data[getInd(i,x,y)].z_(0)/levels_[i].data[getInd(i,x,y)].model_(0,0)),
00453           std::abs(model.param.z_(0)/model.param.model_(0,0))
00454       );
00455       /*
00456 #if defined(SIMULATION_)
00457       if(d>20.f) continue;
00458       const float thr=(d+2.f)*0.0015f;
00459 #elif defined(DO_NOT_DOWNSAMPLE_)
00460       const float thr=(d*d+1.2f)*0.004f;      //TODO: check
00461 #else
00462       const float thr=(d*d+1.2f)*0.004f;
00463 #endif
00464        */
00465       if( hops>0 && x>0&&y>0&&x+1<(int)levels_[i].w&&y+1<(int)levels_[i].h &&
00466           d!=0.f && ((found<1&&first_lvl
00467               //#ifdef USE_MIN_MAX_RECHECK_
00468               //                &&(levels_[i].data[getInd(x,y)].v_max_-levels_[i].data[getInd(x,y)].v_min_)<0.02f*(1<<i)*std::abs(levels_[i].data[getInd(x,y)].z_(0)/levels_[i].data[getInd(x,y)].model_(0,0))
00469               //#endif
00470           ) ||
00471           (
00472 #ifdef USE_MIN_MAX_RECHECK_
00473 #ifdef DO_NOT_DOWNSAMPLE_
00474 
00475               //expected maximum:   model.get_max_gradient(levels_[i].data[getInd(i, x,y)])*d*(1<<i)/camera_.f
00476               //+3sigma*(standard deviation at max./min.)
00477 
00478               (levels_[i].data[getInd(i, x,y)].v_max_-levels_[i].data[getInd(i, x,y)].v_min_) <
00479               (model.get_max_gradient(levels_[i].data[getInd(i, x,y)])*d*(1<<i)/camera_.f
00480                   +3*(camera_.std(levels_[i].data[getInd(i, x,y)].v_max_)
00481                       +camera_.std(levels_[i].data[getInd(i, x,y)].v_min_)) )
00482 
00483 
00484                       //(levels_[i].data[getInd(i, x,y)].v_max_-levels_[i].data[getInd(i, x,y)].v_min_)< (model.get_max_gradient(levels_[i].data[getInd(i, x,y)])*d*(1<<i)/camera_.f+2*thr) /*std::min(0.5f,std::max(0.02f,0.05f*d))*/ //TODO: in anbhaengigkeit der steigung
00485 #else
00486                       (levels_[i].data[getInd(i, x,y)].v_max_-levels_[i].data[getInd(i, x,y)].v_min_)< 2*(model.get_max_gradient(levels_[i].data[getInd(i, x,y)])*d*(1<<i)/camera_.f+4*thr) /*std::min(0.5f,std::max(0.02f,0.05f*d))*/ //TODO: in anbhaengigkeit der steigung
00487 #endif
00488                       //&& std::abs(model.model(levels_[i].data[getInd(x,y)].v_min_(0),levels_[i].data[getInd(x,y)].v_min_(1))-levels_[i].data[getInd(x,y)].v_min_(2))<thr
00489                       //&& std::abs(model.model(levels_[i].data[getInd(x,y)].v_max_(0),levels_[i].data[getInd(x,y)].v_max_(1))-levels_[i].data[getInd(x,y)].v_max_(2))<thr
00490                       &&
00491 #endif
00492                       (
00493                           //checkModelAt(model, i,x,y, thr)
00494                           checkModelAt(model, i,x,y)
00495                           /*||
00496                   checkModelAtZ(model, i,x,y,
00497                                 0.01f)*/)
00498                                 //d*(0.04-0.005*levels_[i].data[getInd(x,y)].model_(0,0)/model.param.model_(0,0))))
00499                                 //0.015)) {
00500                                 //d*(0.01-0.005*levels_[i].data[getInd(x,y)].model_(0,0)/model.param.model_(0,0)))
00501           )
00502 #ifdef USE_NORMAL_CHECK
00503           && ( (i!=1&&i!=2) || std::abs(SubStructure::Model(levels_[i].data[getInd(x,y)]).getLinearNormal().dot(
00504               model.getNormal(levels_[i].data[getInd(x,y)].model_(1,0)/levels_[i].data[getInd(x,y)].model_(0,0),
00505                               levels_[i].data[getInd(x,y)].model_(3,0)/levels_[i].data[getInd(x,y)].model_(0,0)) ))>0.8 ) //TODO: optimize normalize out
00506 #endif
00507           )
00508       ) {
00509         ++found;
00510         levels_[i].data[getInd(i,x,y)].occopied=mark;
00511         model+=levels_[i].data[getInd(i,x,y)];
00512         if(hops>10 || found%20==0)
00513           model.get();
00514         bNew=bNew2;
00515 
00516         list.add(SubStructure::SVALUE(getInd(i, x+1,y),hops-1));
00517         list.add(SubStructure::SVALUE(getInd(i, x-1,y),hops-1));
00518         list.add(SubStructure::SVALUE(getInd(i, x,y+1),hops-1));
00519         list.add(SubStructure::SVALUE(getInd(i, x,y-1),hops-1));
00520 
00521       }
00522       else
00523         bNew2=true;
00524     }
00525     last_size=list.pos;
00526     list.pos=-1;
00527     //break;
00528   } while(bNew);
00529 
00530   if(first_lvl && found<MIN_LOD) {
00531     for(int j=0; j<list.size; j++) {
00532       if(levels_[i].data[list.vals[j].v].occopied==mark)
00533         levels_[i].data[list.vals[j].v].occopied=-1;
00534     }
00535     return;
00536   }
00537 
00538   // if finished then create polygon
00539   if(i==(int)FINAL_LOD) {
00540     if(!list.size)
00541     {
00542       ROS_ASSERT(0);
00543       return;
00544     }
00545 
00546     if(only_planes_ && !model.isLinearAndTo())
00547       return;
00548 
00549     S_POLYGON<Degree> poly;
00550     poly=model;
00551     poly.mark_ = mark;
00552 
00553     //std::cout<<model.p<<"\n";
00554 
00555 #ifdef CHECK_CONNECTIVITY
00556     poly.connectivity_=connectivity;
00557 #endif
00558 
00559     static std::vector<SubStructure::SXY> outs;
00560     SubStructure::SXY pt;
00561 
00562     outs.clear();
00563 
00564     for(int j=0; j<list.size; j++) {
00565       x= list.vals[j].v%levels_[i].w;
00566       y= list.vals[j].v/levels_[i].w;
00567 
00568       if(x>0 && y>0 && x<(int)levels_[i].w && y<(int)levels_[i].h && isOccupied(i,x,y)==mark) continue;
00569 
00570       pt.x=x;pt.y=y;
00571 #ifdef USE_MIN_MAX_RECHECK_
00572       //        const float delta = (levels_[i+2].data[getInd2(x/4,y/4)].v_max_-
00573       //            model.model(levels_[i].data[getInd(x,y)].model_(1)/levels_[i].data[getInd(x,y)].model_(0,0),
00574       //                        levels_[i].data[getInd(x,y)].model_(3)/levels_[i].data[getInd(x,y)].model_(0,0)));
00575       //        pt.back = (delta > -0.01f && levels_[i+2].data[getInd(i+2, x/4,y/4)].v_min_<0.1f) || delta>2*(model.get_max_gradient(levels_[i].data[getInd(x,y)])*levels_[i].data[getInd(x,y)].z_(0)/levels_[i].data[getInd(x,y)].model_(0,0)*(1<<i)/kinect_params_.f+4*0.03f);
00576       pt.back = levels_[i+2].data[getInd(i+2, x/4,y/4)].v_max_-
00577           model.model(levels_[i+2].data[getInd(i+2, x/4,y/4)].model_(1)/levels_[i+2].data[getInd(i+2, x/4,y/4)].model_(0,0),
00578                       levels_[i+2].data[getInd(i+2, x/4,y/4)].model_(3)/levels_[i+2].data[getInd(i+2, x/4,y/4)].model_(0,0))
00579                       > (model.get_max_gradient(levels_[i+2].data[getInd(i+2, x/4,y/4)])*levels_[i+2].data[getInd(i+2, x/4,y/4)].z_(0)/levels_[i+2].data[getInd(i+2, x/4,y/4)].model_(0,0)*(1<<i)/camera_.f+4*0.03f);
00580       //TODO: improve this stupid thing (but it was easy :) )
00581 #endif
00582       outs.push_back(pt);
00583     }
00584 
00585     outline(ch_, levels_[i].w,levels_[i].h,outs,i, poly, model, mark);
00586 //    if(poly.segments_.size()<1)
00587 //    {
00588 //      //ROS_WARN("segment empty");
00589 //      return;
00590 //    }
00591 
00592     if(filter_>0.f) {
00593       float area = poly.area();
00594 
00595       if(poly.weight_*poly.model_.param.v_max_*poly.model_.param.v_max_/area>filter_)
00596         polygons_.push_back(poly);
00597     }
00598     else
00599       polygons_.push_back(poly);
00600 
00601     return;
00602   }
00603 
00604   //region growing
00605   SubStructure::VISITED_LIST<SubStructure::SVALUE> list_lower;
00606   for(int j=0; j<list.size; j++) {
00607     x= list.vals[j].v%levels_[i].w;
00608     y= list.vals[j].v/levels_[i].w;
00609 
00610     hops=9;     // max. allowed movement in inner nodes
00611 
00612     if(filterOccupied(i,x,y,mark))
00613       continue;
00614 
00615     bool above = y>0 &&                    filterOccupied(i,x,y-1,mark);
00616     bool below = y+1<(int)levels_[i].h &&  filterOccupied(i,x,y+1,mark);
00617     bool left  = x>0 &&                    filterOccupied(i,x-1,y,mark);
00618     bool right = x+1<(int)levels_[i].w &&  filterOccupied(i,x+1,y,mark);
00619 
00620     if(above&&below&&left&&right)
00621       continue;
00622 
00623     if(above) {
00624       list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x,2*y),hops/2));
00625       list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x+1,2*y),hops/2));
00626     }
00627     if(below) {
00628       list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x,2*y+1),hops/2));
00629       list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x+1,2*y+1),hops/2));
00630     }
00631     if(left && !above) list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x,2*y),hops/2));
00632     if(left && !below) list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x,2*y+1),hops/2));
00633     if(right && !above) list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x+1,2*y),hops/2));
00634     if(right && !below) list_lower.add(SubStructure::SVALUE(getInd(i-1, 2*x+1,2*y+1),hops/2));
00635   }
00636 
00637   grow(list_lower, model, i-1, mark, false);
00638 }
00639 
00640 template <int Degree, typename Point, typename CameraModel>
00641 int QuadRegression<Degree, Point, CameraModel>::getPos(int *ch, const int xx, const int yy, const int w, const int h) {
00642   int p=0;
00643   for(int x=-1; x<=1; x++) {
00644     for(int y=-1; y<=1; y++) {
00645       if( xx+x>=0 && yy+y>=0 && xx+x<w && yy+y<h &&
00646           (x||y) && ch[getInd(0, xx+x,yy+y)]>0)
00647       {
00648         p |= (1<<Contour2D::SplineMap[ (y+1)*3 + x+1]);
00649       }
00650     }
00651 
00652   }
00653   return p;
00654 }
00655 
00656 template <int Degree, typename Point, typename CameraModel>
00657 void QuadRegression<Degree, Point, CameraModel>::outline(int *ch, const int w, const int h, std::vector<SubStructure::SXY> &out, const int i, S_POLYGON<Degree> &poly, const SubStructure::Model<Degree> &model, const int mark)
00658 {
00659   //    std::cout<<"OFF:\n"<<poly.param_.col(0)<<"\n";
00660   //    std::cout<<"PLANE:\n"<<poly.proj2plane_<<"\n";
00661   //    std::cout<<"P1:\n"<<poly.param_.col(1)<<"\n";
00662   //    std::cout<<"P2:\n"<<poly.param_.col(2)<<"\n";
00663 
00664 #ifdef STOP_TIME
00665   PrecisionStopWatch ssw;
00666   ssw.precisionStart();
00667 #endif
00668 
00669   SubStructure::SXYcmp ttt;
00670   std::sort(out.begin(),out.end(), ttt);
00671 
00672   for(size_t j=0; j<out.size(); j++) {
00673     ch[ getInd(i, out[j].x,out[j].y) ]=(int)j+1;
00674   }
00675 
00676 #if DEBUG_LEVEL>200
00677   {  char buf[128];
00678   int *bs = new int[w*h];
00679   memset(bs,0,w*h*4);
00680   for(size_t j=0; j<out.size(); j++) {
00681     bs[ getInd(out[j].x,out[j].y) ]=-(out[j].back+1);
00682   }
00683   sprintf(buf,"/tmp/poly%d.ppm",polygons_.size());
00684   QQPF_Debug::ppm(buf,w,h,bs);
00685   delete [] bs;
00686   }
00687 #endif
00688 
00689   if(outline_check_size_<out.size()) {
00690     delete [] outline_check_;
00691     outline_check_ = new bool[out.size()];
00692     outline_check_size_=out.size();
00693   }
00694   memset(outline_check_,false,out.size());
00695 
00696   int n=-1;
00697   while(n+1<(int)out.size()) {
00698     ++n;
00699     if(outline_check_[n])
00700       continue;
00701 
00702     poly.segments_.push_back(std::vector<Eigen::Vector3f>());
00703 #ifdef USE_BOOST_POLYGONS_
00704     poly.segments2d_.push_back(std::vector<BoostPoint>());
00705 #else
00706     poly.segments2d_.push_back(std::vector<Eigen::Vector2i>());
00707 #endif
00708 
00709     int x=out[n].x;
00710     int y=out[n].y;
00711     int bf=8;
00712     int v=0;
00713     int back=0;
00714     int start_x=x, start_y=y;
00715 
00716     addPoint(i,x,y,mark, poly,model);
00717     int num=0,numb=0;
00718 
00719     while(1) {
00720 
00721       if(x<0 || y<0 || x>=w || y>=h || ch[ getInd(i,x,y) ]<1) {
00722         break;
00723       }
00724 
00725       back+=out[ch[ getInd(i,x,y) ]-1].back?1:0;
00726       ++numb;
00727       outline_check_[ch[ getInd(i,x,y) ]-1]=true;
00728       ch[ getInd(i,x,y) ]=-2;
00729       int p=getPos(ch,x,y,w,h);
00730 
00731       if(p==0|| (!Contour2D::g_Splines[bf][p].x&&!Contour2D::g_Splines[bf][p].y) )
00732       {
00733         break;
00734       }
00735 
00736       v+=v+Contour2D::g_Splines[bf][p].v;
00737       x+=Contour2D::g_Splines[bf][p].x;
00738       y+=Contour2D::g_Splines[bf][p].y;
00739       bf=Contour2D::g_Splines[bf][p].bf;
00740       ++num;
00741 
00742 #ifdef EVALUATE
00743       if(std::abs(v)>6) {
00744 #else
00745         if(std::abs(v)>3) {
00746 #endif
00747         v=0;
00748         Eigen::Vector2f tv;
00749         tv(0)=x;tv(1)=y;
00750         addPoint(i,x,y,mark, poly,model,back/(float)numb);
00751         numb=back=0;
00752       }
00753     }
00754     if(poly.segments_.back().size()>0) poly.segments_.back()[0](2)=back/(float)numb;
00755 
00756     if(poly.segments_.back().size()<3 || (std::abs(x-start_x)+std::abs(y-start_y))>10 ) {
00757       poly.segments_.erase(poly.segments_.end()-1);
00758 
00759 #if defined(USE_BOOST_POLYGONS_) || defined(BACK_CHECK_REPEAT)
00760       poly.segments2d_.erase(poly.segments2d_.end()-1);
00761 #endif
00762     }
00763 
00764 
00765   }
00766 
00767   //    for(size_t j=0; j<poly.segments_.size(); j++)
00768   //      for(size_t k=0; k<poly.segments_[j].size(); k++)
00769   //      {
00770   //        std::cout<<"s\n"<<poly.segments_[j][k].head<2>()<<"\n";
00771   //        std::cout<<"p\n"<<poly.project2world(poly.segments_[j][k].head<2>())<<"\n";
00772   //      }
00773 
00774   for(size_t j=0; j<out.size(); j++) {
00775     ch[ getInd(i, out[j].x,out[j].y) ]=0;
00776   }
00777 
00778 #ifdef STOP_TIME
00779   execution_time_polyextraction_ += ssw.precisionStop();
00780 #endif
00781 
00782 }


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