fov_segmentation.cpp
Go to the documentation of this file.
00001 
00061 //##################
00062 //#### includes ####
00063 
00064 #include <map>
00065 #include <cob_3d_fov_segmentation/fov_segmentation.h>
00066 //#include <pcl/surface/convex_hull.h>
00067 
00068 using namespace cob_3d_mapping;
00069 
00070 
00071 // Constructor
00072 FOVSegmentation::FOVSegmentation()
00073 {
00074 }
00075 
00076 bool FOVSegmentation::ccw(Eigen::Vector2f& a, Eigen::Vector2f& b, Eigen::Vector2f& c)
00077 {
00078         return (c(1)-a(1))*(b(0)-a(0)) > (b(1)-a(1))*(c(0)-a(0));
00079 }
00080 
00081 void FOVSegmentation::compute(std::vector<Polygon::Ptr>& polygons)
00082 {
00083   for(polygon_iterator it = polygons_in_.begin(); it != polygons_in_.end(); it++)
00084   {
00085     std::vector<Eigen::Vector3f> intersections;
00086     clipFOVandPlane(*it, intersections);
00087     std::vector<std::vector<Eigen::Vector3f> > intersections2;
00088     intersections2.push_back(intersections);
00089     /*if( intersections.size() < 3)
00090     {
00091       //check if centroid is inside tetraeder
00092       //find clipping point of fov plane and vector between 0 and p
00093       std::vector<Eigen::Vector3d> p(5);
00094       fov_.getFOV(p[0], p[1], p[2], p[3], p[4]);
00095       Eigen::Vector3d normal = (p[2]-p[1]).cross(p[3]-p[2]).normalized();
00096       Eigen::Vector4f centroid;
00097       centroid << p[2].cast<float>(),1;
00098       //std::cout << normal << std::endl;
00099       //std::cout << p[2].cast<float>().head(3) << std::endl;
00100       Polygon::Ptr poly(new Polygon);
00101       poly->computeAttributes(normal.cast<float>(), centroid);
00102       double div = normal.dot(poly->centroid.topLeftCorner(3, 1).cast<double>()-p[0]);
00103       double lambda = (normal.dot(p[2] - p[0]))/div;
00104       Eigen::Vector3d intersection = p[0] + lambda*(poly->centroid.topLeftCorner(3, 1).cast<double>()-p[0]);
00105       Eigen::Vector2f inters_plane = (poly->transform_from_world_to_plane * intersection.cast<float>()).head(2);
00106       Eigen::Vector2f p1_plane = (poly->transform_from_world_to_plane * p[1].cast<float>()).head(2);
00107       Eigen::Vector2f p2_plane = (poly->transform_from_world_to_plane * p[2].cast<float>()).head(2);
00108       Eigen::Vector2f p3_plane = (poly->transform_from_world_to_plane * p[3].cast<float>()).head(2);
00109       Eigen::Vector2f p4_plane = (poly->transform_from_world_to_plane * p[4].cast<float>()).head(2);
00110       std::cout << "inters: " << inters_plane(0) << "," << inters_plane(1) << std::endl;
00111       std::cout << "p1: " << p1_plane(0) << "," << p1_plane(1) << std::endl;
00112       std::cout << "p2: " << p2_plane(0) << "," << p2_plane(1) << std::endl;
00113       std::cout << "p3: " << p3_plane(0) << "," << p3_plane(1) << std::endl;
00114       std::cout << "p4: " << p4_plane(0) << "," << p4_plane(1) << std::endl;
00115       //check if clipping point is inside fov rectangle
00116       if(ccw(p2_plane,p1_plane,inters_plane) &&
00117           ccw(p3_plane,p2_plane,inters_plane) &&
00118           ccw(p4_plane,p3_plane,inters_plane) &&
00119           ccw(p1_plane,p4_plane,inters_plane))
00120           {
00121             //if all ccw are true => inside, else outside
00122         std::cout << "polygon is inside" << std::endl;
00123             continue;
00124           }
00125     }*/
00126     if(intersections.size() != 0)
00127     {
00128       Polygon::Ptr fov_poly(new Polygon(**it));
00129       fov_poly->contours_.clear();
00130       fov_poly->holes_.clear();
00131       //fov_poly->contours_.push_back(intersections);
00132       fov_poly->setContours3D(intersections2);
00133       fov_poly->holes_.push_back(false);
00134       (*it)->mergeDifference(fov_poly);
00135       std::cout << "clipped poly:" << fov_poly->contours_.size() << std::endl;
00136       if (fov_poly->contours_.size() > 0)
00137         polygons.push_back(fov_poly);
00138     }
00139     else
00140       polygons.push_back(*it);
00141     /*std::cout << fov_poly->contours[0][0](0) << "," <<  fov_poly->contours[0][0](1) << "," << fov_poly->contours[0][0](2) << std::endl;
00142     std::cout << fov_poly->contours[0][1](0) << "," <<  fov_poly->contours[0][1](1) << "," << fov_poly->contours[0][1](2) << std::endl;
00143     std::cout << fov_poly->contours[0][2](0) << "," <<  fov_poly->contours[0][2](1) << "," << fov_poly->contours[0][2](2) << std::endl;
00144     std::cout << fov_poly->contours[0][3](0) << "," <<  fov_poly->contours[0][3](1) << "," << fov_poly->contours[0][3](2) << std::endl;*/
00145   }
00146 }
00147 
00148 void FOVSegmentation::clipFOVandPlane(Polygon::Ptr& poly, std::vector<Eigen::Vector3f>& intersections)
00149 {
00150   std::vector<Eigen::Vector3d> p(5);
00151   fov_.getFOV(p[0], p[1], p[2], p[3], p[4]);
00152 
00153   for( unsigned int i=1; i<p.size(); i++)
00154   {
00155     double div = poly->normal_.cast<double>().dot(p[i]-p[0]);
00156     /*std::cout << poly->normal << std::endl;
00157     std::cout << p[i] << std::endl;
00158     std::cout << p[0] << std::endl;*/
00159     //std::cout << "div: " << div << std::endl;
00160     if ( div == 0 ) continue;
00161     double lambda = (poly->normal_.cast<double>().dot(poly->pose_.translation().cast<double>() - p[0]))/div;
00162     //std::cout << "lambda: " << lambda << std::endl;
00163     if ( lambda > 1 || lambda < 0) continue;
00164     Eigen::Vector3d intersection = p[0] + lambda*(p[i]-p[0]);
00165     //std::cout << i << ": " << intersection(0) << "," << intersection(1) << "," << intersection(2) << std::endl;
00166     intersections.push_back(intersection.cast<float>());
00167   }
00168   //std::cout << std::endl;
00169   for( unsigned int i=1; i<p.size(); i++)
00170   {
00171     unsigned int j = i+1;
00172     if ( j == p.size() ) j = 1;
00173     double div = poly->normal_.cast<double>().dot(p[j]-p[i]);
00174     if ( div == 0 ) continue;
00175     double lambda = (poly->normal_.cast<double>().dot(poly->pose_.translation().cast<double>() - p[i]))/div;
00176     if ( lambda > 1  || lambda < 0) continue;
00177     Eigen::Vector3d intersection = p[i] + lambda*(p[j]-p[i]);
00178     //std::cout << i <<"," << j << ": " << intersection(0) << "," << intersection(1) << "," << intersection(2) << std::endl;
00179     /*std::cout << "div, l: "<< div << "," << lambda << std::endl;
00180     std::cout << "p" << i << ": " << p[i](0) << "," << p[i](1) << "," << p[i](2) << std::endl;
00181     std::cout << "p" << j << ": " << p[j](0) << "," << p[j](1) << "," << p[j](2) << std::endl;*/
00182     intersections.push_back(intersection.cast<float>());
00183   }
00184   std::cout << "found " << intersections.size() << "intersecting points for ID " << poly->id_ << std::endl;
00185   if(intersections.size() == 5)
00186   {
00187     //calc angle rel. to centroid
00188     std::vector<Eigen::Vector2f> cs;
00189     Eigen::Vector2f cent(0,0);
00190     for(unsigned int i=0; i<intersections.size(); i++)
00191       {
00192         cs.push_back((poly->pose_.inverse() * intersections[i]).head(2));
00193         //std::cout << "cs" << i << ": " << (poly->transform_from_world_to_plane * intersections[i]).head(2)(0) << "," << (poly->transform_from_world_to_plane * intersections[i]).head(2)(1) << std::endl;
00194         cent = cent + (poly->pose_.inverse() * intersections[i]).head(2);
00195       }
00196 
00197     cent = cent/5;
00198     //std::cout << "centroid " << cent(0) << "," << cent(1) << std::endl;
00199     Eigen::Vector2f ref = (cs[0] - cent).normalized();
00200     std::map<double, unsigned int> angles1;
00201     std::map<double, unsigned int> angles2;
00202     for(unsigned int i=1; i<cs.size(); i++)
00203     {
00204       if(ccw(cent, cs[0], cs[i]))
00205       {
00206         angles1.insert(std::pair<double, unsigned int>((cs[i]-cent).normalized().dot(ref),i));
00207         //std::cout << "angle1 " << i << ": " << acos((cs[i]-cent).normalized().dot(ref))*180/3.14159 << std::endl;
00208       }
00209       else
00210       {
00211         angles2.insert(std::pair<double, unsigned int>((cs[i]-cent).normalized().dot(ref),i));
00212         //std::cout << "angle2 " << i << ": " << acos((cs[i]-cent).normalized().dot(ref))*180/3.14159 << std::endl;
00213       }
00214     }
00215     std::vector<unsigned int> sorted;
00216     sorted.push_back(0);
00217     for(std::map<double, unsigned int>::reverse_iterator it = angles1.rbegin(); it != angles1.rend(); it++)
00218       sorted.push_back(it->second);
00219     for(std::map<double, unsigned int>::const_iterator it = angles2.begin(); it != angles2.end(); it++)
00220       sorted.push_back(it->second);
00221     std::vector<Eigen::Vector3f> inters_temp(sorted.size());
00222     for(unsigned int i=0; i<sorted.size(); i++)
00223     {
00224       inters_temp[i] = intersections[sorted[i]];
00225     }
00226     intersections.swap(inters_temp);
00227     //for(unsigned int i=0; i<intersections.size(); i++)
00228     //  std::cout << "inter: " << intersections[i](0) << "," << intersections[i](1) << "," << intersections[i](2) << std::endl;
00229   }
00230   if(intersections.size() == 4)
00231   {
00232     Eigen::Vector2f c1 = (poly->pose_.inverse() * intersections[0]).head(2);
00233     Eigen::Vector2f c2 = (poly->pose_.inverse() * intersections[1]).head(2);
00234     Eigen::Vector2f c3 = (poly->pose_.inverse() * intersections[2]).head(2);
00235     Eigen::Vector2f c4 = (poly->pose_.inverse() * intersections[3]).head(2);
00236     if(ccw(c1,c2,c3))
00237     {
00238       if(ccw(c1,c3,c4)) ;
00239       else
00240       {
00241         if(ccw(c1,c2,c4)) std::swap(intersections[3],intersections[2]);
00242         else std::swap(intersections[0],intersections[3]);
00243       }
00244     }
00245     else
00246     {
00247       if(ccw(c1,c3,c4))
00248       {
00249         if(ccw(c1,c2,c4)) std::swap(intersections[1],intersections[2]);
00250         else std::swap(intersections[0],intersections[1]);
00251       }
00252       else std::swap(intersections[0],intersections[2]);
00253     }
00254   }
00255 }
00256 
00257 
00258 


cob_3d_fov_segmentation
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:04:19