polygon_extraction.cpp
Go to the documentation of this file.
00001 
00060 #ifndef __IMPL_POLYGON_EXTRACTION__
00061 #define __IMPL_POLYGON_EXTRACTION__
00062 
00063 #include <cstring>
00064 #include <iostream>
00065 #include <cob_3d_segmentation/polygon_extraction/polygon_extraction.h>
00066 #include <cob_3d_segmentation/polygon_extraction/impl/poly2d.hpp>
00067 #include <cob_3d_segmentation/polygon_extraction/polygon_types.h>
00068 
00069 #include <cstdio>
00070 
00071 cob_3d_segmentation::PolygonExtraction::PolygonExtraction()
00072  : ch_(NULL),ch_size_(0)
00073  , outline_check_(NULL)
00074  , outline_check_size_(0)
00075 {
00076   Contour2D::generateSpline2D();
00077 }
00078 
00079 
00080 template <typename TPoint>
00081 int cob_3d_segmentation::PolygonExtraction::getPos(int *ch, const int xx, const int yy, const int w, const int h) {
00082   int p = 0;
00083   //const int i = 0;
00084   for(int x = -1; x <= 1; x++) {
00085     for(int y = -1; y <= 1; y++) {
00086       if( xx + x >= 0 && yy + y >= 0 && xx + x < w && yy + y < h && (x || y) && ch[xx + x + (yy + y ) * w] > 0)
00087       {
00088         p |= (1 << Contour2D::SplineMap[(y + 1) * 3 + x + 1]);
00089       }
00090     }
00091   }
00092   return p;
00093 }
00094 
00095 template<typename TPoint, typename TPolygon>
00096 void cob_3d_segmentation::PolygonExtraction::outline(const int w, const int h, std::vector<TPoint> out, TPolygon &poly)
00097 {
00098   //sort border points ascendingly by y and x
00099   std::sort(out.begin(), out.end());
00100   //image size has changed, re-initialize
00101   if(ch_size_ < w*h)
00102   {
00103     delete [] ch_;
00104     ch_ = new int[w*h];
00105     ch_size_=w*h;
00106     memset(ch_,0,sizeof(int)*ch_size_);
00107   }
00108 
00109   //fill ch_ with border points
00110   for(size_t j=0; j<out.size(); j++) {
00111     ch_[ out[j].x + out[j].y * w ] = 1;//(int)j+1;
00112   }
00113 
00114   /*if(outline_check_size_<out.size()) {
00115     delete [] outline_check_;
00116     outline_check_ = new bool[out.size()];
00117     outline_check_size_=out.size();
00118   }
00119   memset(outline_check_,false,out.size());*/
00120 
00121   //ppm("/tmp/outline.ppm",w,h,ch_);
00122   //int n=-1;
00123   for(int n = 0; n < (int)out.size(); n++)
00124   //while(n+1<(int)out.size())
00125   {
00126     //if(poly.polys_.size() > 0) break; //why?
00127     //++n;
00128     /*if(outline_check_[n])
00129       continue;*/
00130 
00131     int x = out[n].x;
00132     int y = out[n].y;
00133     if(ch_[ x + y * w ] < 1) continue;
00134     int bf = 8; //neighborhood before (8 bit)
00135     int v = 0;
00136     int start_x = x, start_y = y;
00137 
00138     poly.addPolygon();
00139     poly.addPoint(x,y);
00140     //int num=0;
00141     std::stack<std::pair<int,Contour2D::spline2D> > forked_states;
00142     std::stack<typename std::vector<TPoint>::size_type> forked_points;
00143     while(1)
00144     {
00145       //out of image range or point is no border point
00146       if(x < 0 || y < 0 || x >= w || y >= h || ch_[ x + y * w ] < 1)
00147       {
00148         /*std::cout << "no points left" << std::endl;*/break;
00149       }
00150 
00151       int ch_old = ch_[ x+y*w ];
00152       //outline_check_[ch_[ x+y*w ]-1]=true;
00153       ch_[ x+y*w ] = 0;//-2;
00154 
00155       int p = getPos<TPoint>(ch_, x, y, w, h);
00156 
00157       if(p == 0 || (!Contour2D::g_Splines[bf][p].x && !Contour2D::g_Splines[bf][p].y))
00158       {
00159         // There is no valid next point:
00160         if (forked_states.size() == 0 || (std::abs(x-start_x)+std::abs(y-start_y)) <= 4) { /*std::cout << "no forks left" << std::endl;*/break; }
00161         //std::cout << "--> Back to fork!" << std::endl;
00162         // Go back to last forked state
00163         v = forked_states.top().second.v;
00164         x = forked_states.top().second.x;
00165         y = forked_states.top().second.y;
00166         //std::cout << "fork: " << x << "," << y << std::endl;
00167         bf = forked_states.top().second.bf;
00168         ch_ [ x+y*w ] = forked_states.top().first;
00169         forked_states.pop();
00170         /*std::cout << "poly points before: ";
00171         for(unsigned int i=0; i<poly.polys_.back().size(); i++)
00172           std::cout << poly.polys_.back()[i].x << "," << poly.polys_.back()[i].y << "->";
00173         std::cout << std::endl;
00174         std::cout << "to remove: " << forked_points.top() << std::endl;*/
00175         poly.removeLastPoints(forked_points.top());
00176         /*std::cout << "remaining poly points: ";
00177         for(unsigned int i=0; i<poly.polys_.back().size(); i++)
00178           std::cout << poly.polys_.back()[i].x << "," << poly.polys_.back()[i].y << "->";
00179         std::cout << std::endl;*/
00180         forked_points.pop();
00181         continue;
00182       }
00183       //create new fork
00184       if (hasMultiplePositions((unsigned int)p))
00185       {
00186         Contour2D::spline2D s = {v, x, y, bf};
00187         forked_states.push(std::pair<int,Contour2D::spline2D>(ch_old, s));
00188         forked_points.push(0);
00189       }
00190 
00191       v += v + Contour2D::g_Splines[bf][p].v;
00192       x += Contour2D::g_Splines[bf][p].x;
00193       y += Contour2D::g_Splines[bf][p].y;
00194       bf = Contour2D::g_Splines[bf][p].bf;
00195       //++num;
00196 
00197       if(std::abs(v) > 5)
00198       {
00199         v = 0;
00200         ++(forked_points.top());
00201         poly.addPoint(x,y);
00202         /*std::cout << "adding poly point: ";
00203         for(unsigned int i=0; i<poly.polys_.back().size(); i++)
00204           std::cout << poly.polys_.back()[i].x << "," << poly.polys_.back()[i].y << "->";
00205         std::cout << std::endl;*/
00206       }
00207     }
00208 
00209     //std::cout << "abs: " << x << "," << start_x << ";" << y << "," << start_y << std::endl;
00210     if(poly.polys_.back().size() < 4 || (std::abs(x - start_x) + std::abs(y - start_y)) > 4 )
00211     {
00212       poly.removePolygon();
00213       //std::cout << "No contour found, aborting" << std::endl;
00214       break;
00215     }
00216 
00217   }
00218 
00219   for(size_t j = 0; j < out.size(); j++) {
00220     ch_[ out[j].x + out[j].y * w ] = 0;
00221   }
00222 
00223 }
00224 
00225 void cob_3d_segmentation::PolygonExtraction::ppm(const char *fn, const int w, const int h, const int *ch) {
00226   //ppm
00227   FILE *fp = fopen(fn,"w");
00228 
00229   char buffer[128];
00230   sprintf(buffer,"P3\n%d %d\n255\n",h,w);
00231   fputs(buffer,fp);
00232 
00233   for(int x=0; x<w; x++) {
00234     for(int y=0; y<h; y++) {
00235       int v=0;
00236       if(ch[(x+w*y)])
00237         v=255;
00238 
00239       if(ch[(x+w*y)]<-1) {
00240         sprintf(buffer,"%d %d %d  ",0,255,0);
00241       }
00242       else if(ch[(x+w*y)]<0) {
00243         sprintf(buffer,"%d %d %d  ",255,0,0);
00244       }
00245       else
00246         sprintf(buffer,"%d %d %d  ",v,v,v);
00247       fputs(buffer,fp);
00248     }
00249   }
00250   fclose(fp);
00251 }
00252 
00253 // explicit instantiation of template member functions:
00254 
00255 template void cob_3d_segmentation::PolygonExtraction::outline<cob_3d_segmentation::PolygonPoint, cob_3d_segmentation::PolygonContours<cob_3d_segmentation::PolygonPoint> >(const int w, const int h, std::vector<cob_3d_segmentation::PolygonPoint> out, cob_3d_segmentation::PolygonContours<cob_3d_segmentation::PolygonPoint> &poly);
00256 
00257 template int cob_3d_segmentation::PolygonExtraction::getPos<cob_3d_segmentation::PolygonPoint>(int *ch, const int xx, const int yy, const int w, const int h);
00258 
00259 #endif


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