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
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
00099 std::sort(out.begin(), out.end());
00100
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
00110 for(size_t j=0; j<out.size(); j++) {
00111 ch_[ out[j].x + out[j].y * w ] = 1;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 for(int n = 0; n < (int)out.size(); n++)
00124
00125 {
00126
00127
00128
00129
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;
00135 int v = 0;
00136 int start_x = x, start_y = y;
00137
00138 poly.addPolygon();
00139 poly.addPoint(x,y);
00140
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
00146 if(x < 0 || y < 0 || x >= w || y >= h || ch_[ x + y * w ] < 1)
00147 {
00148 break;
00149 }
00150
00151 int ch_old = ch_[ x+y*w ];
00152
00153 ch_[ x+y*w ] = 0;
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
00160 if (forked_states.size() == 0 || (std::abs(x-start_x)+std::abs(y-start_y)) <= 4) { break; }
00161
00162
00163 v = forked_states.top().second.v;
00164 x = forked_states.top().second.x;
00165 y = forked_states.top().second.y;
00166
00167 bf = forked_states.top().second.bf;
00168 ch_ [ x+y*w ] = forked_states.top().first;
00169 forked_states.pop();
00170
00171
00172
00173
00174
00175 poly.removeLastPoints(forked_points.top());
00176
00177
00178
00179
00180 forked_points.pop();
00181 continue;
00182 }
00183
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
00196
00197 if(std::abs(v) > 5)
00198 {
00199 v = 0;
00200 ++(forked_points.top());
00201 poly.addPoint(x,y);
00202
00203
00204
00205
00206 }
00207 }
00208
00209
00210 if(poly.polys_.back().size() < 4 || (std::abs(x - start_x) + std::abs(y - start_y)) > 4 )
00211 {
00212 poly.removePolygon();
00213
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
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
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