00001
00002
00003
00004
00005
00006
00007
00008 #include "../sub_structures/poly2d.hpp"
00009
00010 #include <cob_3d_mapping_common/stop_watch.h>
00011
00012
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
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
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
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
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
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 {
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
00192 lvl->data[j] = lvl_prev->data[k];
00193 lvl->data[j]+= lvl_prev->data[k+1];
00194 lvl->data[j]+= lvl_prev->data[k+levels_[i-1].w];
00195 lvl->data[j]+= lvl_prev->data[k+levels_[i-1].w+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
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
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
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 {
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
00318 lvl->data[j] = lvl_prev->data[k];
00319 lvl->data[j]+= lvl_prev->data[k+1];
00320 lvl->data[j]+= lvl_prev->data[k+this->levels_[i-1].w];
00321 lvl->data[j]+= lvl_prev->data[k+this->levels_[i-1].w+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
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
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 }
00396
00397 #ifdef STOP_TIME
00398 execution_time_growing_ = ssw.precisionStop();
00399 #endif
00400
00401
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(checkModelAt(model, i,x,y,
00442 0.02)) {
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
00457
00458
00459
00460
00461
00462
00463
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
00468
00469
00470 ) ||
00471 (
00472 #ifdef USE_MIN_MAX_RECHECK_
00473 #ifdef DO_NOT_DOWNSAMPLE_
00474
00475
00476
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
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)
00487 #endif
00488
00489
00490 &&
00491 #endif
00492 (
00493
00494 checkModelAt(model, i,x,y)
00495
00496
00497 )
00498
00499
00500
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 )
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
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
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
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
00573
00574
00575
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
00581 #endif
00582 outs.push_back(pt);
00583 }
00584
00585 outline(ch_, levels_[i].w,levels_[i].h,outs,i, poly, model, mark);
00586
00587
00588
00589
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
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;
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
00660
00661
00662
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
00768
00769
00770
00771
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 }