Go to the documentation of this file.00001
00061
00062
00063
00064 #include <map>
00065 #include <cob_3d_fov_segmentation/fov_segmentation.h>
00066
00067
00068 using namespace cob_3d_mapping;
00069
00070
00071
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
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
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
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
00142
00143
00144
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
00157
00158
00159
00160 if ( div == 0 ) continue;
00161 double lambda = (poly->normal_.cast<double>().dot(poly->pose_.translation().cast<double>() - p[0]))/div;
00162
00163 if ( lambda > 1 || lambda < 0) continue;
00164 Eigen::Vector3d intersection = p[0] + lambda*(p[i]-p[0]);
00165
00166 intersections.push_back(intersection.cast<float>());
00167 }
00168
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
00179
00180
00181
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
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
00194 cent = cent + (poly->pose_.inverse() * intersections[i]).head(2);
00195 }
00196
00197 cent = cent/5;
00198
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
00208 }
00209 else
00210 {
00211 angles2.insert(std::pair<double, unsigned int>((cs[i]-cent).normalized().dot(ref),i));
00212
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
00228
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