polygon.cpp
Go to the documentation of this file.
00001 
00059 //ros includes
00060 #include <ros/console.h>
00061 //cob includes
00062 #include <cob_3d_mapping_common/polygon.h>
00063 //pcl includes
00064 #include <pcl/common/common.h>
00065 
00066 #ifdef PCL_VERSION_COMPARE
00067 #include <pcl/common/transforms.h>
00068 #else
00069 #include <pcl/common/transform.h>
00070 #include <pcl/registration/transforms.h>
00071 #endif
00072 #include <pcl/common/centroid.h>
00073 #include <pcl/common/eigen.h>
00074 
00075 //boost includes
00076 #include <boost/shared_ptr.hpp>
00077 
00078 //custom definitons
00079 #define MOD(a,b) ( ((a%b)+b)%b )
00080 
00081 namespace cob_3d_mapping
00082 {
00083 
00084   // NON MEMBER FUNCTIONS
00085 
00093   /*void
00094   getPointOnPolygon(const Eigen::Vector3f &normal,double d,Eigen::Vector3f &point)
00095   {
00096     float value=fabs(normal(0));
00097     int direction=0;
00098 
00099     if(fabs(normal(1))>value)
00100     {
00101 
00102       direction=1;
00103       value=fabs(normal(1));
00104     }
00105 
00106     if(fabs(normal(2))>value)
00107 
00108     {
00109       direction=2;
00110       value=fabs(normal(2));
00111     }
00112     point << 0,0,0;
00113     point(direction)=-d/normal(direction);
00114   }*/
00115 
00124   /*void
00125 getCoordinateSystemOnPlane(const Eigen::Vector3f &normal,
00126     Eigen::Vector3f &u, Eigen::Vector3f &v)
00127 {
00128   v = normal.unitOrthogonal ();
00129   u = normal.cross (v);
00130 }*/
00131 
00132 
00136   /*void
00137   copyGpcStructure(const gpc_polygon* source, gpc_polygon* dest)
00138   {
00139     dest->num_contours = source->num_contours;
00140     dest->hole = (int*)malloc(source->num_contours*sizeof(int));
00141     dest->contour = (gpc_vertex_list*)malloc(source->num_contours*sizeof(gpc_vertex_list));
00142     for(int j=0; j<source->num_contours; ++j)
00143     {
00144       dest->hole[j] = source->hole[j];
00145       dest->contour[j].num_vertices = source->contour[j].num_vertices;
00146       dest->contour[j].vertex = (gpc_vertex*)malloc(source->contour[j].num_vertices*sizeof(gpc_vertex));
00147 
00148       for(int k=0; k<source->contour[j].num_vertices; ++k)
00149       {
00150         dest->contour[j].vertex[k].x = source->contour[j].vertex[k].x;
00151         dest->contour[j].vertex[k].y = source->contour[j].vertex[k].y;
00152       }
00153     }
00154   }*/
00155 
00163   /*void
00164   smoothGpcStructure(const gpc_polygon* gpc_in, gpc_polygon* gpc_out)
00165   {
00166   }*/
00167 
00168 
00169   //##########methods for instantiation##############
00170   /*Polygon::Polygon(Polygon::Ptr polygon)
00171   {
00172     this->normal = polygon->normal;
00173     this->d = polygon->d;
00174     this->transform_from_world_to_plane = polygon->transform_from_world_to_plane;
00175     this->merge_weight_ = polygon->merge_weight_;
00176   }*/
00177 
00178   Polygon::Polygon(unsigned int id,
00179                    Eigen::Vector3f normal,
00180                    Eigen::Vector3f centroid,
00181                    std::vector<std::vector<Eigen::Vector3f> >& contours_3d,
00182                    std::vector<bool> holes,
00183                    std::vector<float> color)
00184   : normal_(Eigen::Vector3f::Zero()),
00185     d_(0.0),
00186     merge_weight_(1.0)
00187   {
00188     id_ = id;
00189     d_ = centroid.dot(normal);
00190     if (d_ > 0) {
00191       normal_ = -normal;
00192       d_ = -d_;
00193     }
00194     else { normal_ = normal; }
00195     holes_ = holes;
00196     color_ = color;
00197     computePose(contours_3d);
00198     setContours3D(contours_3d);
00199   }
00200 
00201   Polygon::Polygon(unsigned int id,
00202                    Eigen::Vector3f normal,
00203                    Eigen::Vector3f centroid,
00204                    std::vector<pcl::PointCloud<pcl::PointXYZ> >& contours_3d,
00205                    std::vector<bool> holes,
00206                    std::vector<float> color)
00207   : normal_(Eigen::Vector3f::Zero()),
00208     d_(0.0),
00209     merge_weight_(1.0)
00210   {
00211     id_ = id;
00212     d_ = centroid.dot(normal);
00213     if (d_ > 0) {
00214       normal_ = -normal;
00215       d_ = -d_;
00216     }
00217     else { normal_ = normal; }
00218     //normal_ = normal;
00219     holes_ = holes;
00220     color_ = color;
00221     std::vector<std::vector<Eigen::Vector3f> > contours_eigen;
00222     for(unsigned int i = 0; i < contours_3d.size(); i++)
00223     {
00224       std::vector<Eigen::Vector3f> c_eigen;
00225       for(unsigned int j = 0; j < contours_3d[i].size(); j++)
00226       {
00227         Eigen::Vector3f pt = contours_3d[i].points[j].getVector3fMap();
00228         c_eigen.push_back(pt);
00229       }
00230       contours_eigen.push_back(c_eigen);
00231     }
00232     computePose(contours_eigen);
00233     setContours3D(contours_eigen);
00234   }
00235 
00236   void
00237   Polygon::setContours3D(std::vector<std::vector<Eigen::Vector3f> >& contours_3d)
00238   {
00239     contours_.clear();
00240     for(unsigned int i = 0; i < contours_3d.size(); i++)
00241     {
00242       std::vector<Eigen::Vector2f> c;
00243       for(unsigned int j = 0; j < contours_3d[i].size(); j++)
00244       {
00245         Eigen::Vector2f pt_2d = (pose_.inverse()*contours_3d[i][j]).head(2);
00246         c.push_back(pt_2d);
00247       }
00248       contours_.push_back(c);
00249     }
00250     /*for(unsigned int i = 0; i < contours_.size(); i++)
00251   {
00252     for(unsigned int j = 0; j < contours_[i].size(); j++)
00253     {
00254       std::cout << contours_[i][j](0) << "," << contours_[i][j](1) << std::endl;
00255     }
00256   }*/
00257   }
00258 
00259   std::vector<std::vector<Eigen::Vector3f> >
00260   Polygon::getContours3D()
00261   {
00262     std::vector<std::vector<Eigen::Vector3f> > contours_3d;
00263     for(unsigned int i = 0; i < contours_.size(); i++)
00264     {
00265       std::vector<Eigen::Vector3f> c;
00266       for(unsigned int j = 0; j < contours_[i].size(); j++)
00267       {
00268         Eigen::Vector3f pt_2d(contours_[i][j](0), contours_[i][j](1), 0);
00269         Eigen::Vector3f pt_3d = pose_*pt_2d;
00270         c.push_back(pt_3d);
00271       }
00272       contours_3d.push_back(c);
00273     }
00274     return contours_3d;
00275   }
00276 
00277   void
00278   Polygon::updateAttributes(const Eigen::Vector3f &new_normal, const Eigen::Vector3f& new_origin)
00279   {
00280     //TODO: optionally provide x- or y-axis
00281     d_ = new_origin.dot(new_normal);
00282     if (d_ > 0) {
00283       normal_ = -new_normal;
00284       d_ = -d_;
00285     }
00286     else { normal_ = new_normal; }
00287     //pose_.translation() = new_centroid;
00288     //centroid = new_centroid;
00289 
00290     Eigen::Affine3f t;
00291     pcl::getTransformationFromTwoUnitVectorsAndOrigin(normal_.unitOrthogonal(), normal_, new_origin, t);
00292     pose_ = t.inverse();
00293     //pcl::getTransformationFromTwoUnitVectorsAndOrigin(
00294     //    this->normal_.unitOrthogonal(), this->normal_, new_centroid, this->pose_);
00295   }
00296 
00297   void Polygon::transform(const Eigen::Affine3f& trafo)
00298   {
00299     //transform contours
00300     //this->TransformContours(trafo);
00301     pose_ = trafo*pose_;
00302     normal_ = trafo.rotation()*normal_;
00303     d_ = pose_.translation().dot(normal_);
00304     if (d_ > 0)
00305     {
00306       normal_ *= -1;
00307       d_ = -d_;
00308     }
00309 
00310     //  transform parameters
00311     /*Eigen::Vector3f tf_normal = trafo.rotation() *this->normal;
00312   this->normal =tf_normal;
00313   Eigen::Vector3f tf_centroid3f = this->centroid.head(3);
00314   tf_centroid3f = trafo * tf_centroid3f;
00315   this->centroid.head(3) = tf_centroid3f;
00316   this->computeAttributes(this->normal,this->centroid);*/
00317   }
00318 
00319 
00320   void
00321   Polygon::smoothContours()
00322   {
00323     /*gpc_polygon *before = new gpc_polygon();
00324     gpc_polygon *after = new gpc_polygon();
00325     this->getGpcStructure(before, contours_);
00326     copyGpcStructure(gpc_in, gpc_out);*/
00327     std::vector<std::vector<Eigen::Vector2f> > contours_sm = contours_;
00328     float weight_data = 0.5, weight_smooth = 0.01, tolerance = 1.0f;
00329     float change = tolerance;
00330 
00331     for(unsigned int j = 0; j < contours_.size(); ++j)
00332     {
00333       int num_iteration = 0;
00334       int l = contours_[j].size(); // length
00335       //gpc_vertex* contours_sm[j] = gpc_out->contour[j].vertex; // new polygon
00336       //gpc_vertex* po = gpc_in->contour[j].vertex; // old polygon
00337 
00338       while(change >= tolerance && num_iteration <= 5)
00339       {
00340         change = 0.0f;
00341         for(int k=0; k<l; ++k)
00342         {
00343           //if( !k%10 ) continue;
00344           // do x value:
00345           float before = contours_sm[j][k](0);
00346           contours_sm[j][k](0) += weight_data * (contours_[j][k](0) - contours_sm[j][k](0));
00347           contours_sm[j][k](0) += weight_smooth * (contours_sm[j][ MOD(k-1,l) ](0) + contours_sm[j][ (k+1)%l ](0) - (2.0f * contours_sm[j][k](0)));
00348           contours_sm[j][k](0) += 0.5f * weight_smooth * (2.0f * contours_sm[j][ MOD(k-1,l) ](0) - contours_sm[j][ MOD(k-2,l) ](0) - contours_sm[j][k](0));
00349           contours_sm[j][k](0) += 0.5f * weight_smooth * (2.0f * contours_sm[j][    (k+1)%l ](0) - contours_sm[j][    (k+2)%l ](0) - contours_sm[j][k](0));
00350           change += fabs(before - contours_sm[j][k](0));
00351 
00352           // do y value:
00353           before = contours_sm[j][k](1);
00354           contours_sm[j][k](1) += weight_data * (contours_[j][k](1) - contours_sm[j][k](1));
00355           contours_sm[j][k](1) += weight_smooth * (contours_sm[j][ MOD(k-1,l) ](1) + contours_sm[j][ (k+1)%l ](1) - (2.0f * contours_sm[j][k](1)));
00356           contours_sm[j][k](1) += 0.5f * weight_smooth * (2.0f * contours_sm[j][ MOD(k-1,l) ](1) - contours_sm[j][ MOD(k-2,l) ](1) - contours_sm[j][k](1));
00357           contours_sm[j][k](1) += 0.5f * weight_smooth * (2.0f * contours_sm[j][    (k+1)%l ](1) - contours_sm[j][    (k+2)%l ](1) - contours_sm[j][k](1));
00358           change += fabs(before - contours_sm[j][k](1));
00359         }
00360         ++num_iteration;
00361       }
00362       ROS_DEBUG_STREAM( "Needed " << num_iteration << " iterations for polygon of size " << l );
00363     }
00364     contours_ = contours_sm;
00365   }
00366 
00367 
00368   //###########methods for merging##################
00369 
00370 
00371   void
00372   Polygon::getMergeCandidates(const std::vector<Polygon::Ptr>& poly_vec, std::vector<int>& intersections) const
00373   {
00374     for(size_t i=0; i< poly_vec.size(); ++i)
00375     {
00376       //std::cout << this->hasSimilarParametersWith(poly_vec[i]) << "," << this->isIntersectedWith(poly_vec[i]) << std::endl;
00377       if(this->hasSimilarParametersWith(poly_vec[i]) && this->isIntersectedWith(poly_vec[i])) intersections.push_back(i);
00378     }
00379   }
00380 
00381   bool
00382   Polygon::isIntersectedWith(const Polygon::Ptr& poly) const
00383   {
00384     gpc_polygon *gpc_res = new gpc_polygon();
00385     this->getIntersection(poly, gpc_res);
00386     bool res = (gpc_res->num_contours != 0);
00387     gpc_free_polygon(gpc_res);
00388     return (res);
00389   }
00390 
00391 
00392   void
00393   Polygon::getIntersection(const Polygon::Ptr& poly, gpc_polygon* gpc_intersection) const
00394   {
00395     /*std::cout << "####### Proj of P0 ###########" << std::endl;
00396   for(unsigned int i = 0; i < contours_[0].size(); i++)
00397   {
00398     std::cout << contours_[0][i](0) << "," << contours_[0][i](1) << "," << std::endl;
00399   }*/
00400     std::vector<std::vector<Eigen::Vector2f> > contours_p;
00401     projectContour(*poly, contours_p);
00402     /*std::cout << "####### Proj of P1 ###########" << std::endl;
00403   for(unsigned int i = 0; i < contours_p[0].size(); i++)
00404   {
00405     std::cout << contours_p[0][i](0) << "," << contours_p[0][i](1) << "," << std::endl;
00406   }*/
00407     gpc_polygon *gpc_poly = new gpc_polygon(), *gpc_here = new gpc_polygon();
00408     this->getGpcStructure(gpc_here, contours_);
00409     poly->getGpcStructure(gpc_poly, contours_p);
00410     gpc_polygon_clip(GPC_INT, gpc_here, gpc_poly, gpc_intersection);
00411     gpc_free_polygon(gpc_poly);
00412     gpc_free_polygon(gpc_here);
00413   }
00414 
00415   bool
00416   Polygon::getContourOverlap(const Polygon::Ptr& poly, float& rel_overlap, int& abs_overlap) const
00417   {
00418     std::vector<std::vector<Eigen::Vector2f> > contours_p;
00419     projectContour(*poly, contours_p);
00420     gpc_polygon *gpc_a = new gpc_polygon(), *gpc_b = new gpc_polygon();
00421     gpc_polygon *gpc_res_int = new gpc_polygon(), *gpc_res_union = new gpc_polygon();
00422     this->getGpcStructure(gpc_a, contours_);
00423     poly->getGpcStructure(gpc_b, contours_p);
00424     gpc_polygon_clip(GPC_INT, gpc_a, gpc_b, gpc_res_int);
00425     gpc_polygon_clip(GPC_UNION, gpc_a, gpc_b, gpc_res_union);
00426 
00427     int i_int = -1, i_union = -1;
00428     for(int i=0;i<gpc_res_int->num_contours;++i) { if(!gpc_res_int->hole[i]) { i_int = i; break; } }
00429     for(int i=0;i<gpc_res_union->num_contours;++i) { if(!gpc_res_union->hole[i]) { i_union = i; break; } }
00430     if(i_int == -1 || i_union == -1) return false;
00431     int overlap = 0;
00432     float d_th = pow( 0.01, 2 );
00433     for(int i=0;i<gpc_res_int->contour[i_int].num_vertices; ++i)
00434     {
00435       gpc_vertex* pv_int = &gpc_res_int->contour[i_int].vertex[i];
00436       for(int j=0;j<gpc_res_union->contour[i_union].num_vertices; ++j)
00437       {
00438         if( pow(gpc_res_union->contour[i_union].vertex[j].x - pv_int->x, 2) +
00439             pow(gpc_res_union->contour[i_union].vertex[j].y - pv_int->y, 2) < d_th )
00440         {
00441           ++overlap;
00442           break;
00443         }
00444       }
00445     }
00446     rel_overlap = (float)overlap/(float)gpc_res_int->contour[i_int].num_vertices;
00447     abs_overlap = overlap;
00448     ROS_DEBUG_STREAM("Overlap: " << overlap << "/"<<gpc_res_int->contour[i_int].num_vertices << " -> "
00449                      << (float)overlap/(float)gpc_res_int->contour[i_int].num_vertices );
00450     gpc_free_polygon(gpc_a);
00451     gpc_free_polygon(gpc_b);
00452     gpc_free_polygon(gpc_res_int);
00453     gpc_free_polygon(gpc_res_union);
00454     return true;
00455   }
00456 
00457 
00458   float
00459   Polygon::computeSimilarity(const Polygon::Ptr& poly) const
00460   {
00461     float normal = (fabs(poly->normal_.dot(this->normal_)) - this->merge_settings_.angle_thresh) /
00462         (1-this->merge_settings_.angle_thresh);
00463     float d = fabs(fabs((this->pose_.translation()-poly->pose_.translation()).head(3).dot(this->normal_))-this->merge_settings_.d_thresh) /
00464         this->merge_settings_.d_thresh;
00465     float overlap = 0.0;
00466     int abs_overlap;
00467     this->getContourOverlap(poly, overlap, abs_overlap);
00468     return ( 3.0f / (1.0f / normal + 1.0f / d + 1.0f / overlap) );
00469   }
00470 
00471   void
00472   Polygon::merge(std::vector<Polygon::Ptr>& poly_vec)
00473   {
00474     assignID(poly_vec);
00475     //if(this->id==0) std::cout << "merge_weight before: " << this->merge_weight_ << "," << merged << std::endl;
00476     Polygon::Ptr p_average = Polygon::Ptr(new Polygon);
00477     computeAverage(poly_vec, p_average);
00478     mergeUnion(poly_vec, p_average);
00479     assignWeight();
00480     //if(this->id==0) std::cout << "merge_weight after: " << this->merge_weight_ << "," << merged  << std::endl;
00481   }
00482 
00483   void
00484   Polygon::mergeDifference(Polygon::Ptr& p_merge)
00485   {
00486     std::vector<std::vector<Eigen::Vector2f> > contours_p;
00487     p_merge->projectContour(*this, contours_p);
00488     gpc_polygon *gpc_C = new gpc_polygon;
00489     this->getGpcStructure(gpc_C, contours_p);
00490     //std::cout << this->transform_from_world_to_plane.matrix() << std::endl;
00491 
00492     gpc_polygon *gpc_B = new gpc_polygon;
00493     p_merge->getGpcStructure(gpc_B, p_merge->contours_);
00494 
00495     gpc_polygon_clip(GPC_DIFF, gpc_C, gpc_B, gpc_B);
00496     //std::cout << "contours: " << gpc_B->num_contours << std::endl;
00497     gpc_free_polygon(gpc_C);
00498     //copyGpcStructure(gpc_C, smoothed);
00499     //smoothGpcStructure(gpc_C, smoothed);
00500     p_merge->applyGpcStructure(gpc_B);
00501     gpc_free_polygon(gpc_B);
00502     //gpc_free_polygon(smoothed);
00503   }
00504 
00505   void
00506   Polygon::mergeUnion(std::vector<Polygon::Ptr>& poly_vec,  Polygon::Ptr& p_average)
00507   {
00508     //std::cout << "p_avg pose " << p_average->pose_.matrix() << std::endl;
00509     //if(this->id==0) std::cout << "\tthis rgb: " << this->color[0]*255 << "," << this->color[1]*255 << "," << this->color[2]*255 << std::endl;
00510     d_color_.reset();
00511     //d_color_.setID(this->id_);
00512     std::vector<std::vector<Eigen::Vector2f> > contours;
00513     p_average->projectContour(*this, contours);
00514     /*std::cout << "####### Proj of P0 ###########" << std::endl;
00515   //std::cout << "normal: " << normal_(0) << "," << normal_(1) << "," << normal_(2) << std::endl;
00516   std::cout << pose_.matrix() << std::endl;
00517   for(unsigned int i = 0; i < contours[0].size(); i++)
00518   {
00519     std::cout << contours[0][i](0) << "," << contours[0][i](1) << "," << std::endl;
00520   }*/
00521     gpc_polygon *gpc_C = new gpc_polygon, *smoothed = new gpc_polygon;
00522     this->getGpcStructure(gpc_C, contours);
00523 
00524     double min_weight = this->merge_weight_;
00525     for(size_t i=0;i<poly_vec.size();++i)
00526     {
00527       if(poly_vec[i]->merge_weight_ < min_weight)
00528         min_weight = poly_vec[i]->merge_weight_;
00529     }
00530     double normalizer = 1/min_weight;
00531 
00532     for(size_t i=0;i<poly_vec.size();++i)
00533     {
00534       std::vector<std::vector<Eigen::Vector2f> > contours_p;
00535       p_average->projectContour(*poly_vec[i], contours_p);
00536       /*std::cout << "####### Proj of P1 ###########" << std::endl;
00537     //std::cout << "normal: " << poly_vec[i]->normal_(0) << "," << poly_vec[i]->normal_(1) << "," << poly_vec[i]->normal_(2) << std::endl;
00538     std::cout << poly_vec[i]->pose_.matrix() << std::endl;
00539     for(unsigned int j = 0; j < contours_p[0].size(); j++)
00540     {
00541       std::cout << contours_p[0][j](0) << "," << contours_p[0][j](1) << "," << std::endl;
00542     }*/
00543       gpc_polygon *gpc_B = new gpc_polygon;
00544       poly_vec[i]->getGpcStructure(gpc_B, contours_p);
00545       gpc_polygon_clip(GPC_UNION, gpc_B, gpc_C, gpc_C);
00546       gpc_free_polygon(gpc_B);
00547       d_color_.addColor(poly_vec[i]->color_[0]*255,poly_vec[i]->color_[1]*255,poly_vec[i]->color_[2]*255, round(normalizer*poly_vec[i]->merge_weight_));
00548       //if(id==0) std::cout << "\tm_weight " << poly_vec[i]->id << ": " << poly_vec[i]->merge_weight_ << "," << poly_vec[i]->computeArea3d() << std::endl;
00549     }
00550     d_color_.addColor(this->color_[0]*255,this->color_[1]*255,this->color_[2]*255,round(normalizer*this->merge_weight_));
00551     //if(id==0) std::cout << "\tm_weight " << this->merge_weight_ <<  "," << this->computeArea3d() << std::endl;
00552 
00553     /*std::cout << "####### Proj of Paverage ###########" << std::endl;
00554   std::cout << "normal: " << p_average->normal_(0) << "," << p_average->normal_(1) << "," << p_average->normal_(2) << std::endl;
00555   std::cout << p_average->pose_.matrix() << std::endl;*/
00556     // fill in parameters for "this" polygon
00557     setParamsFrom(p_average);
00558     //this->merge_weight_ = p_average->merge_weight_;
00559     /*copyGpcStructure(gpc_C, smoothed);
00560   smoothGpcStructure(gpc_C, smoothed);
00561   this->applyGpcStructure(smoothed);*/
00562     this->applyGpcStructure(gpc_C);
00563     gpc_free_polygon(gpc_C);
00564     /*std::cout << "####### Proj of Pmerged ###########" << std::endl;
00565   std::cout << "normal: " << normal_(0) << "," << normal_(1) << "," << normal_(2) << std::endl;
00566   std::cout << pose_.matrix() << std::endl;
00567   for(unsigned int i = 0; i < contours_[0].size(); i++)
00568   {
00569     std::cout << contours_[0][i](0) << "," << contours_[0][i](1) << "," << std::endl;
00570   }*/
00571     //gpc_free_polygon(smoothed);
00572     uint8_t r,g,b;
00573     d_color_.getColor(r,g,b);
00574     //std::cout << "\t" << (int)r << "," << (int)g << "," << (int)b << std::endl;
00575     float temp_inv = 1.0f/255.0f;
00576     //std::cout << r* temp_inv << "," << g* temp_inv << "," << b* temp_inv << std::endl;
00577     this->color_[0] = r * temp_inv;
00578     this->color_[1] = g * temp_inv;
00579     this->color_[2] = b * temp_inv;
00580     //if(this->id==0) std::cout << "\tthis rgb: " << this->color[0]*255 << "," << this->color[1]*255 << "," << this->color[2]*255 << std::endl;
00581   }
00582 
00583   void
00584   Polygon::projectContour(const Polygon& p, std::vector<std::vector<Eigen::Vector2f> >& contours) const
00585   {
00586     //std::cout << pose_.matrix() << std::endl << std::endl;
00587     //std::cout << p.pose_.inverse().matrix() << std::endl << std::endl;
00588     for(unsigned int i = 0; i < p.contours_.size(); i++)
00589     {
00590       std::vector<Eigen::Vector2f> c;
00591       for(unsigned int j = 0; j < p.contours_[i].size(); j++)
00592       {
00593         //std::cout << p.contours_[i][j](0) << "," << p.contours_[i][j](1) << std::endl;
00594         Eigen::Vector2f pt_p = (pose_.inverse() * p.pose_ * Eigen::Vector3f(p.contours_[i][j](0), p.contours_[i][j](1), 0)).head(2);
00595         c.push_back(pt_p);
00596         //std::cout << pt_p(0) << "," << pt_p(1) << std::endl;
00597       }
00598       contours.push_back(c);
00599     }
00600   }
00601 
00602   void
00603   Polygon::assignWeight()
00604   {
00605     if (std::strcmp(merge_settings_.weighting_method.c_str(), "COUNTER") == 0)
00606     {
00607       merge_weight_ = merged_;
00608     }
00609     else if (std::strcmp(merge_settings_.weighting_method.c_str(), "AREA") == 0)
00610     {
00611       double area = computeArea3d();
00612       merge_weight_ = (merged_ * area);
00613     }
00614   }
00615 
00616   void
00617   Polygon::assignID(const std::vector<Polygon::Ptr>& poly_vec)
00618   {
00619     unsigned int tmp_id = poly_vec[0]->id_;
00620     for(size_t i = 0; i < poly_vec.size(); ++i)
00621     {
00622       if(poly_vec[i]->id_ < tmp_id) tmp_id = poly_vec[i]->id_;
00623     }
00624     this->id_ = tmp_id;
00625   }
00626 
00627   void
00628   Polygon::computeAverage(const std::vector<Polygon::Ptr>& poly_vec, Polygon::Ptr & p_average)
00629   {
00630     //std::cout << "w: " << merge_weight_ << std::endl;
00631     //std::cout << "merged: " << merged_ << std::endl;
00632     Eigen::Vector3f average_normal = normal_*merge_weight_;
00633     Eigen::Vector3f average_centroid = pose_.translation()*merge_weight_;
00634     double average_d = d_*merge_weight_;
00635     double sum_w = merge_weight_;
00636     unsigned int sum_merged = merged_;
00637     //std::cout << "poly centroid" << pose_.translation()(0) << "," << pose_.translation()(1) << "," << pose_.translation()(2) << "," << std::endl;
00638     //std::cout << "poly normal" << normal_(0) << "," << normal_(1) << "," << normal_(2) << "," << std::endl;
00639     //std::cout << pose_.translation()*merge_weight_ << std::endl;
00640 
00641     for(int i=0 ; i< (int) poly_vec.size();i++)
00642     {
00643       Polygon& p_map1 =*(poly_vec[i]);
00644 
00645       if(normal_.dot(p_map1.normal_) < 0)
00646       {
00647         average_normal += p_map1.merge_weight_* -p_map1.normal_;
00648       }
00649       else
00650       {
00651         average_normal += p_map1.merge_weight_* p_map1.normal_;
00652       }
00653       average_centroid += p_map1.merge_weight_* p_map1.pose_.translation();
00654       //std::cout << "poly centroid" << p_map1.pose_.translation()(0) << "," << p_map1.pose_.translation()(1) << "," << p_map1.pose_.translation()(2) << "," << std::endl;
00655       //std::cout << "poly normal" << p_map1.normal_(0) << "," << p_map1.normal_(1) << "," << p_map1.normal_(2) << "," << std::endl;
00656       average_d += p_map1.merge_weight_ * p_map1.d_;
00657       sum_w += p_map1.merge_weight_;
00658       sum_merged += p_map1.merged_;
00659     }
00660 
00661     average_normal = average_normal/sum_w;
00662     average_centroid = average_centroid/sum_w;
00663     average_d = average_d/sum_w;
00664     average_normal.normalize();
00665 
00666     if (sum_merged < merged_limit_)
00667     {
00668       p_average->merged_ = sum_merged;
00669     }
00670     else
00671     {
00672       p_average->merged_ = merged_limit_;
00673     }
00674     //std::cout << "average centroid" << average_centroid(0) << "," << average_centroid(1) << "," << average_centroid(2) << "," << std::endl;
00675     //std::cout << "average_normal" << average_normal(0) << "," << average_normal(1) << "," << average_normal(2) << "," << std::endl;
00676     p_average->updateAttributes(average_normal, average_centroid);
00677     //std::cout << "average p: " << p_average->pose_.matrix() << std::endl;
00678   }
00679 
00680   void
00681   Polygon::setParamsFrom(Polygon::Ptr& p)
00682   {
00683     this->pose_ = p->pose_;
00684     this->d_ = p->d_;
00685     this->normal_ = p->normal_;
00686     if(this->merged_ < 9) { this->merged_ = p->merged_; }
00687     else { this->merged_ = 9; }
00688   }
00689 
00690   void
00691   Polygon::getGpcStructure(gpc_polygon* gpc_p, const std::vector<std::vector<Eigen::Vector2f> >& contours) const
00692   {
00693     // get transformed contours
00694     //std::vector< std::vector <Eigen::Vector3f> > transformed_contours;
00695     //this->getTransformedContours(external_trafo, transformed_contours);
00696 
00697     gpc_p->num_contours = contours.size();
00698     gpc_p->hole = (int*)malloc(contours.size()*sizeof(int));
00699     gpc_p->contour = (gpc_vertex_list*)malloc(contours.size()*sizeof(gpc_vertex_list));
00700     for(size_t j = 0; j<contours.size(); ++j)
00701     {
00702       gpc_p->hole[j] = holes_[j];
00703       gpc_p->contour[j].num_vertices = contours[j].size();
00704       gpc_p->contour[j].vertex = (gpc_vertex*)malloc(gpc_p->contour[j].num_vertices*sizeof(gpc_vertex));
00705 
00706       for(size_t k = 0; k < contours[j].size(); ++k)
00707       {
00708         //Eigen::Vector3f point_trans = transformed_contours[j][k];
00709         gpc_p->contour[j].vertex[k].x = contours[j][k](0);//point_trans(0);
00710         gpc_p->contour[j].vertex[k].y = contours[j][k](1);//point_trans(1);
00711       }
00712     }
00713   }
00714 
00715 
00716   void
00717   Polygon::applyGpcStructure(const gpc_polygon* gpc_p)
00718   {
00719     // clear contours, at the end gpc_C contains everything we need!
00720     this->contours_.clear();
00721     this->holes_.clear();
00722     for(int j = 0; j < gpc_p->num_contours; ++j)
00723     {
00724       this->contours_.push_back(std::vector<Eigen::Vector2f>());
00725       this->holes_.push_back(gpc_p->hole[j]);
00726       float last_x = 0.0, last_y = 0.0;
00727       for (int k = 0; k < gpc_p->contour[j].num_vertices; ++k)
00728       {
00729         // check if points are too close to each other (so remove similar points)
00730         if (fabs(gpc_p->contour[j].vertex[k].x - last_x) < 0.01 && fabs(gpc_p->contour[j].vertex[k].y - last_y) < 0.01)
00731           continue;
00732         last_x = gpc_p->contour[j].vertex[k].x;
00733         last_y = gpc_p->contour[j].vertex[k].y;
00734         this->contours_.back().push_back(Eigen::Vector2f(last_x,last_y));
00735       }
00736 
00737       if (this->contours_.back().size() <= 2)  // drop empty contour lists
00738       {
00739         this->contours_.pop_back();
00740         this->holes_.pop_back();
00741       }
00742     }
00743   }
00744 
00745 
00746   //#######methods for calculation#####################
00747 
00748   /*void
00749 Polygon::computePose()
00750 {
00751   Eigen::Vector3f centroid = computeCentroid();
00752   //Eigen::Vector3f u, v;
00753   //getCoordinateSystemOnPlane(normal_, u, v);
00754   Eigen::Affine3f t;
00755   pcl::getTransformationFromTwoUnitVectorsAndOrigin(normal_.unitOrthogonal(), normal_, centroid, t);
00756   pose_ = t.inverse();
00757 }*/
00758 
00759   void
00760   Polygon::computePose(std::vector<std::vector<Eigen::Vector3f> >& contours_3d)
00761   {
00762     Eigen::Vector3f origin = d_*normal_;//contours_3d[0][0];//computeCentroid(contours_3d);
00763     //std::cout << "c: " << centroid << std::endl;
00764     //Eigen::Vector3f u, v;
00765     //getCoordinateSystemOnPlane(normal_, u, v);
00766     Eigen::Affine3f t;
00767     pcl::getTransformationFromTwoUnitVectorsAndOrigin(normal_.unitOrthogonal(), normal_, origin, t);
00768     pose_ = t.inverse();
00769   }
00770 
00771   Eigen::Vector3f
00772   Polygon::computeCentroid()
00773   {
00774     std::vector<std::vector<Eigen::Vector3f> > contours_3d = getContours3D();
00775     return computeCentroid(contours_3d);
00776     //find largest non-hole contour
00777     /*unsigned int idx = 0;
00778     for (unsigned int i = 0; i < contours_.size (); i++)
00779     {
00780       int max_pts = 0;
00781       if(!holes_[i])
00782       {
00783         if((int)contours_[i].size()>(int)max_pts)
00784         {
00785           max_pts = contours_[i].size();
00786           idx = i;
00787         }
00788       }
00789     }
00790     pcl::PointCloud<pcl::PointXYZ> poly_cloud;
00791     for (unsigned int j = 0; j < contours_[idx].size () ; j++)
00792     {
00793       Eigen::Vector4f pt_c_4f(Eigen::Vector4f::Zero());
00794       pt_c_4f.head(2) = contours_[idx][j];
00795       pcl::PointXYZ p;
00796       p.getVector4fMap() = pose_*pt_c_4f;
00797       poly_cloud.push_back(p);
00798     }
00799     Eigen::Vector4f centroid;
00800     pcl::compute3DCentroid(poly_cloud, centroid);
00801     return centroid.head(3);*/
00802   }
00803 
00804   Eigen::Vector3f
00805   Polygon::computeCentroid(std::vector<std::vector<Eigen::Vector3f> >& contours_3d)
00806   {
00807     //find largest non-hole contour
00808     unsigned int idx = 0;
00809     for (unsigned int i = 0; i < contours_3d.size (); i++)
00810     {
00811       int max_pts = 0;
00812       if(!holes_[i])
00813       {
00814         if((int)contours_3d[i].size()>(int)max_pts)
00815         {
00816           max_pts = contours_3d[i].size();
00817           idx = i;
00818         }
00819       }
00820     }
00821     pcl::PointCloud<pcl::PointXYZ> poly_cloud;
00822     for (unsigned int j = 0; j < contours_3d[idx].size () ; j++)
00823     {
00824       pcl::PointXYZ p;
00825       p.getVector3fMap() = contours_3d[idx][j];
00826       poly_cloud.push_back(p);
00827     }
00828     Eigen::Vector4f centroid;
00829     pcl::compute3DCentroid(poly_cloud, centroid);
00830     return centroid.head(3);
00831   }
00832 
00833 
00834   double
00835   Polygon::computeArea3d() const
00836   {
00837     double area = 0;
00838 
00839     list<TPPLPoly> tri_list;
00840     triangulate(tri_list);
00841     for (std::list<TPPLPoly>::iterator it = tri_list.begin (); it != tri_list.end (); it++)
00842     {
00843       TPPLPoint pt1 = it->GetPoint(0);
00844       TPPLPoint pt2 = it->GetPoint(1);
00845       TPPLPoint pt3 = it->GetPoint(2);
00846       area += 0.5*fabs((pt2.x - pt1.x)*(pt3.y - pt1.y) - (pt3.x -pt1.x)*(pt2.y - pt1.y));
00847     }
00848     return area;
00849   }
00850 
00851   void
00852   Polygon::triangulate(list<TPPLPoly>& tri_list) const
00853   {
00854     TPPLPartition pp;
00855     list<TPPLPoly> polys;
00856     TPPLPoly poly;
00857     TPPLPoint pt;
00858 
00859     for(size_t j=0;j<contours_.size();j++)
00860     {
00861       poly.Init(contours_[j].size());
00862       poly.SetHole(holes_[j]);
00863       for(size_t i=0; i<contours_[j].size(); ++i)
00864       {
00865         pt.x = contours_[j][i](0);
00866         pt.y = contours_[j][i](1);
00867         poly[i] = pt;
00868       }
00869       if (holes_[j])
00870         poly.SetOrientation(TPPL_CW);
00871       else
00872         poly.SetOrientation(TPPL_CCW);
00873       polys.push_back(poly);
00874     }
00875     // triangulation into monotone triangles
00876     pp.Triangulate_EC (&polys, &tri_list);
00877   }
00878 
00879   //#############debugging methods#######################
00880 
00881   void Polygon::debugOutput(std::string name)
00882   {
00883     std::string path = "/home/goa-tz/debug/dbg/";
00884     path.append(name.c_str());
00885     std::ofstream os(path.c_str());
00886 
00887     for (int i = 0; i < (int) this->contours_.size(); ++i)
00888     {
00889       for (int j = 0; j < (int) this->contours_[i].size(); ++j)
00890       {
00891         os << contours_[i][j] << std::endl;
00892       }
00893     }
00894 
00895     os.close();
00896   }
00897 
00898 }//namespace
00899 
00900 
00901 
00902 /*double
00903 Polygon::computeArea() const
00904 {
00905   // IMPORTANT: computes area only for the projection of the polygon onto XY plane
00906   // therefore  the resulting area is not the true area of the polygon
00907   double xi, xi_1, yi, yi_1, area=0;
00908   double sum;
00909   for (unsigned int i = 0; i < contours_.size (); i++)
00910   {
00911     if(holes_[i]) continue;
00912     sum = 0;
00913     //area_[i] = 0;
00914     for (unsigned int j = 0; j < contours_[i].size (); j++)
00915     {
00916       xi = contours_[i][j][0];
00917       yi = contours_[i][j][1];
00918       if (j == (contours_[i].size ()) - 1)
00919       {
00920         xi_1 = contours_[i][0][0];
00921         yi_1 = contours_[i][0][1];
00922       }
00923       else
00924       {
00925         xi_1 = contours_[i][j + 1][0];
00926         yi_1 = contours_[i][j + 1][1];
00927       }
00928       sum = sum + (xi * yi_1 - xi_1 * yi);
00929 
00930     }
00931     area += fabs (sum / 2);
00932   }
00933   return area;
00934 }*/
00935 
00936 /*void
00937 Polygon::computePoseAndBoundingBox(Eigen::Affine3f& pose, Eigen::Vector4f& min_pt, Eigen::Vector4f& max_pt)
00938 {
00939   pcl::PointCloud<pcl::PointXYZ> poly_cloud;
00940   unsigned int idx = 0;
00941   for (unsigned int j = 0; j < contours_[idx].size () ; j++)
00942   {
00943     Eigen::Vector4f pt_c_4f(Eigen::Vector4f::Zero());
00944     pt_c_4f.head(2) = contours_[idx][j];
00945     pcl::PointXYZ p;
00946     p.getVector4fMap() = pose_*pt_c_4f;
00947     poly_cloud.push_back(p);
00948   }
00949   Eigen::Matrix3f cov;
00950   Eigen::Vector4f centroid(Eigen::Vector4f::Zero());
00951   centroid.head(3) = pose_.translation();
00952   pcl::computeCovarianceMatrix (poly_cloud, centroid, cov);
00953   EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
00954   EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
00955   pcl::eigen33 (cov, eigen_vectors, eigen_values);
00956   pcl::getTransformationFromTwoUnitVectorsAndOrigin(eigen_vectors.col(1),eigen_vectors.col(0),pose_.translation(),pose);
00957 
00958   pcl::PointCloud<pcl::PointXYZ> cloud_trans;
00959   pcl::transformPointCloud(poly_cloud, cloud_trans, pose);
00960   pcl::getMinMax3D(cloud_trans, min_pt, max_pt);
00961 }*/
00962 
00963 /*void
00964 Polygon::getTransformationFromPlaneToWorld(
00965 const Eigen::Vector3f &normal,
00966 const Eigen::Vector3f &origin,
00967 Eigen::Affine3f &transformation) const
00968 {
00969 Eigen::Vector3f u, v;
00970 getCoordinateSystemOnPlane(normal, u, v);
00971 pcl::getTransformationFromTwoUnitVectorsAndOrigin(v, normal, origin, transformation);
00972 transformation = transformation.inverse();
00973 }
00974 
00975 void
00976 Polygon::getTransformationFromPlaneToWorld(
00977 const Eigen::Vector3f z_axis,
00978 const Eigen::Vector3f &normal,
00979 const Eigen::Vector3f &origin,
00980 Eigen::Affine3f &transformation)
00981 {
00982 this->normal_ = normal;
00983 pcl::getTransformationFromTwoUnitVectorsAndOrigin(z_axis, normal, origin, transformation);
00984 transformation = transformation.inverse();
00985 }*/
00986 
00987 /*void
00988 Polygon::TransformContours(const Eigen::Affine3f& trafo)
00989 {
00990 
00991 for(size_t j=0; j<contours.size(); j++)
00992 {
00993   for(size_t k=0; k<contours[j].size(); k++)
00994   {
00995     contours[j][k] = trafo * contours[j][k];
00996   }
00997 }
00998 }
00999 
01000 void
01001 Polygon::getTransformedContours(const Eigen::Affine3f& trafo, std::vector< std::vector<Eigen::Vector3f> >& new_contours) const
01002 {
01003 new_contours.resize(contours.size());
01004 for(size_t j=0; j<contours.size(); j++)
01005 {
01006   new_contours[j].resize(contours[j].size());
01007   for(size_t k=0; k<contours[j].size(); k++)
01008   {
01009     new_contours[j][k] = trafo*contours[j][k];
01010   }
01011 }
01012 }*/


cob_3d_mapping_common
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:02:19