00001 00063 #ifndef __IMPL_CLUSTER_GRAPH_STRUCTURE_HPP__ 00064 #define __IMPL_CLUSTER_GRAPH_STRUCTURE_HPP__ 00065 00066 // from cluster.h: #include "cob_3d_mapping_common/label_defines.h" 00067 #include "cob_3d_segmentation/cluster_graph_structure.h" 00068 00069 #include <set> 00070 00071 template <typename ClusterHandlerT, typename EdgeHandlerT> void 00072 cob_3d_segmentation::ClusterGraphStructure<ClusterHandlerT,EdgeHandlerT>::merge(const int cid_source, const int cid_target) 00073 { 00074 std::vector<EdgePtr> updated_edges; 00075 merge(vid_.find(cid_source)->second, vid_.find(cid_target)->second, updated_edges); 00076 } 00077 00078 template <typename ClusterHandlerT, typename EdgeHandlerT> void 00079 cob_3d_segmentation::ClusterGraphStructure<ClusterHandlerT,EdgeHandlerT>::merge( 00080 const int cid_source, 00081 const int cid_target, 00082 std::vector<EdgePtr>& updated_edges) 00083 { 00084 merge(vid_.find(cid_source)->second, vid_.find(cid_target)->second, updated_edges); 00085 } 00086 00087 template <typename ClusterHandlerT, typename EdgeHandlerT> void 00088 cob_3d_segmentation::ClusterGraphStructure<ClusterHandlerT,EdgeHandlerT>::merge( 00089 const VertexID src, 00090 const VertexID trg, 00091 std::vector<EdgePtr>& updated_edges) 00092 { 00093 e_hdl_->erase(g_[boost::edge(src, trg, g_).first].e_it); 00094 boost::remove_edge(src, trg, g_); 00095 typename boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00096 EdgeID eid; 00097 bool ok; 00098 // iterate edges of source and relocate them 00099 for (boost::tie(oe_it,oe_end) = boost::out_edges(src,g_); oe_it != oe_end; ++oe_it) 00100 { 00101 boost::tie(eid,ok) = boost::add_edge(trg, boost::target(*oe_it,g_), g_); // try add new edge 00102 if (ok) // if not already existing, move EdgePtr 00103 { 00104 g_[eid].e_it = g_[*oe_it].e_it; 00105 e_hdl_->move(g_[src].c_it->id(), g_[trg].c_it->id(), g_[eid].e_it); 00106 } 00107 else // else use EdgeHandler to merge to target and drop from Handler 00108 { 00109 e_hdl_->merge(g_[*oe_it].e_it, g_[eid].e_it); 00110 } 00111 updated_edges.push_back(g_[eid].e_it); 00112 } 00113 vid_.erase(g_[src].c_it->id()); // erase from map 00114 c_hdl_->merge(g_[src].c_it, g_[trg].c_it); // use ClusterHandler to merge properties and drop from handler 00115 boost::clear_vertex(src, g_); // removes all out edges, but vertex still exists 00116 boost::remove_vertex(src, g_); // removes vertex, assumes there are no edges left 00117 } 00118 00119 00120 template <typename ClusterHandlerT, typename EdgeHandlerT> void 00121 cob_3d_segmentation::ClusterGraphStructure<ClusterHandlerT,EdgeHandlerT>::getAdjacentClusters( 00122 int cid, std::vector<ClusterPtr>& adjacent_clusters) 00123 { 00124 adjacent_clusters.clear(); 00125 if (vid_.find(cid) == vid_.end()) return; 00126 typename boost::graph_traits<GraphT>::adjacency_iterator aj_it, aj_end; 00127 //std::cout << "EDGES: " << boost::out_degree(to_vID_[cID],g_) << std::endl; 00128 for (boost::tie(aj_it,aj_end) = boost::adjacent_vertices(vid_.find(cid)->second,g_); aj_it != aj_end; ++aj_it) 00129 adjacent_clusters.push_back(g_[*aj_it].c_it); 00130 } 00131 00132 template <typename ClusterHandlerT, typename EdgeHandlerT> void 00133 cob_3d_segmentation::ClusterGraphStructure<ClusterHandlerT,EdgeHandlerT>::getConnectedClusters( 00134 int cid_start, std::vector<ClusterPtr>& connected_clusters, boost::function<bool (EdgePtr)> f) 00135 { 00136 connected_clusters.clear(); 00137 if (vid_.find(cid_start) == vid_.end()) return; 00138 VertexID curr_c; 00139 std::set<int> id_set; 00140 id_set.insert(cid_start); 00141 std::list<VertexID> vertex_todo; 00142 vertex_todo.push_back(vid_.find(cid_start)->second); 00143 00144 while (vertex_todo.size() != 0) 00145 { 00146 typename boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00147 curr_c = vertex_todo.front(); 00148 vertex_todo.pop_front(); 00149 //std::cout << g_[curr_c].c_it->size() << std::endl; 00150 //std::cout << boost::out_degree(curr_c,g_) << std::endl; 00151 for (boost::tie(oe_it,oe_end) = boost::out_edges(curr_c,g_); oe_it != oe_end; ++oe_it) 00152 { 00153 VertexID new_id = boost::target(*oe_it,g_); 00154 if ( id_set.find(g_[new_id].c_it->id()) == id_set.end() && f(g_[*oe_it].e_it) ) 00155 { 00156 vertex_todo.push_back(new_id); 00157 id_set.insert(g_[new_id].c_it->id()); 00158 connected_clusters.push_back(g_[new_id].c_it); 00159 } 00160 } 00161 } 00162 //std::cout << "search done" << std::endl; 00163 } 00164 00165 /* 00166 void 00167 cob_3d_segmentation::ClusterList::computeEdgeAngles(int cID) 00168 { 00169 boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00170 Eigen::Vector3f c_n = g_[to_vID_[cID]].c_it->getOrientation(); 00171 for (boost::tie(oe_it, oe_end) = boost::out_edges(to_vID_[cID],g_); oe_it != oe_end; ++oe_it) 00172 { 00173 Eigen::Vector3f a_n = g_[boost::target(*oe_it,g_)].c_it->getOrientation(); 00174 g_[*oe_it].angle = atan2 ( (a_n.cross(c_n)).norm(), a_n.dot(c_n) ); 00175 g_[*oe_it].d_size = abs(g_[to_vID_[cID]].c_it->size() - g_[boost::target(*oe_it,g_)].c_it->size()); 00176 } 00177 } 00178 00179 void 00180 cob_3d_segmentation::ClusterList::computeEdgeSmoothness(const float max_angle) 00181 { 00182 boost::graph_traits<GraphT>::edge_iterator e_it, e_end; 00183 for (boost::tie(e_it,e_end) = boost::edges(g_); e_it != e_end; ++e_it) 00184 { 00185 std::map<int,int>::iterator bp_it = g_[*e_it].boundary_points.begin()->second.begin(); 00186 int smooth_points = 0; 00187 for ( ; bp_it != g_[*e_it].boundary_points.begin()->second.end(); ++bp_it) 00188 { 00189 if (max_angle < boundary_points_[bp_it->first].normal.dot(boundary_points_[bp_it->second].normal)) 00190 ++smooth_points; 00191 } 00192 g_[*e_it].smoothness = static_cast<float>(smooth_points) / static_cast<float>(g_[*e_it].boundary_points.begin()->second.size()); 00193 } 00194 } 00195 */ 00196 00197 /* not working 00198 void 00199 cob_3d_segmentation::ClusterGraphStructure::removeSmallClusters() 00200 { 00201 boost::graph_traits<GraphT>::vertex_iterator v_it, v_del, v_end; 00202 boost::tie(v_it,v_end)=boost::vertices(g_); 00203 boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00204 int size; 00205 while( v_it != v_end) 00206 { 00207 //std::cout << "ID: " << g_[*v_it].c_it->id << std::endl; 00208 int sum_borders = 0; 00209 std::pair<int,VertexID> big_brother(0,*v_it); 00210 for (boost::tie(oe_it,oe_end)=boost::out_edges(*v_it,g_); oe_it != oe_end; ++oe_it) 00211 { 00212 sum_borders += g_[*oe_it].width; 00213 if ( (size = g_[boost::target(*oe_it,g_)].c_it->size()) > big_brother.first ) 00214 big_brother = std::pair<int,VertexID>(size, boost::target(*oe_it,g_)); 00215 } 00216 //std::cout << "Borders="<< sum_borders << " Size="<<g_[*v_it].c_it->size()<<" "<<big_brother.first<<std::endl; 00217 00218 if ( ((size = g_[*v_it].c_it->size()) < 20 && size > 0 && big_brother.first > 0) || 2 * sum_borders > size) 00219 { 00220 v_del = v_it++; 00221 mergeClusterDataStructure(*v_del, big_brother.second); 00222 } 00223 else ++v_it; 00224 00225 //std::cout << "... done" << std::endl; 00226 } 00227 } 00228 */ 00229 00230 /* not working 00231 void 00232 cob_3d_segmentation::ClusterList::getMinAngleAdjacentClusters( 00233 int cID_start, 00234 const float max_angle, 00235 std::vector<ClusterPtr>& adjacent_clusters) 00236 { 00237 adjacent_clusters.clear(); 00238 VertexID curr_c = to_vID_[cID_start]; 00239 std::set<int> id_set; 00240 id_set.insert(cID_start); 00241 std::list<VertexID> vertex_todo; 00242 vertex_todo.push_back(to_vID_[cID_start]); 00243 /* //only follow minimal angle 00244 bool still_something_todo = true; 00245 while (still_something_todo) 00246 { 00247 still_something_todo = false; 00248 std::pair<float, int> min_c(std::numeric_limits<float>::max(), 0); 00249 boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00250 for (boost::tie(oe_it,oe_end) = boost::out_edges(curr_c,g_); oe_it != oe_end; ++oe_it) 00251 { 00252 float curr_angle = fabs(g_[*oe_it].angle); 00253 int curr_id = g_[boost::target(*oe_it,g_)].c_it->id; 00254 if (curr_angle < min_c.first && id_set.find(curr_id) == id_set.end() 00255 && curr_angle < max_angle && curr_angle != std::numeric_limits<float>::quiet_NaN() 00256 && g_[boost::target(*oe_it,g_)].c_it->indices.size() > g_[*oe_it].width * 10 ) 00257 { 00258 min_c = std::pair<float, int>(curr_angle, curr_id); 00259 still_something_todo = true; 00260 } 00261 } 00262 if (still_something_todo) 00263 { 00264 id_set.insert(min_c.second); 00265 curr_c = to_vID_[min_c.second]; 00266 adjacent_clusters.push_back(g_[curr_c].c_it); 00267 } 00268 } 00269 */ 00270 /* 00271 while (vertex_todo.size() != 0) 00272 { 00273 boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00274 curr_c = vertex_todo.front(); 00275 vertex_todo.pop_front(); 00276 for (boost::tie(oe_it,oe_end) = boost::out_edges(curr_c,g_); oe_it != oe_end; ++oe_it) 00277 { 00278 float new_angle = g_[*oe_it].angle; 00279 std::cout << new_angle << std::endl; 00280 VertexID new_id = boost::target(*oe_it,g_); 00281 //fabs(new_angle) < max_angle && 00282 if (id_set.find(g_[new_id].c_it->id) == id_set.end() 00283 && new_angle != std::numeric_limits<float>::quiet_NaN() 00284 && (fabs(new_angle) * g_[*oe_it].d_size) < 500) 00285 //&& abs(g_[curr_c].c_it->size() - g_[new_id].c_it->size()) < 0.8 * g_[curr_c].c_it->size() ) 00286 { 00287 vertex_todo.push_back(new_id); 00288 id_set.insert(g_[new_id].c_it->id); 00289 adjacent_clusters.push_back(g_[new_id].c_it); 00290 } 00291 } 00292 } 00293 } 00294 */ 00295 00296 /* not working 00297 void 00298 cob_3d_segmentation::ClusterList::getAdjacentClustersWithSmoothBoundaries( 00299 int cID_start, 00300 const float min_smoothness, 00301 std::vector<ClusterPtr>& adjacent_clusters) 00302 { 00303 adjacent_clusters.clear(); 00304 VertexID curr_c = to_vID_[cID_start]; 00305 std::set<int> id_set; 00306 id_set.insert(cID_start); 00307 std::list<VertexID> vertex_todo; 00308 vertex_todo.push_back(to_vID_[cID_start]); 00309 00310 while (vertex_todo.size() != 0) 00311 { 00312 boost::graph_traits<GraphT>::out_edge_iterator oe_it, oe_end; 00313 curr_c = vertex_todo.front(); 00314 vertex_todo.pop_front(); 00315 for (boost::tie(oe_it,oe_end) = boost::out_edges(curr_c,g_); oe_it != oe_end; ++oe_it) 00316 { 00317 float smooth = g_[*oe_it].smoothness; 00318 //std::cout << smooth << std::endl; 00319 VertexID new_id = boost::target(*oe_it,g_); 00320 //fabs(new_angle) < max_angle && 00321 if (id_set.find(g_[new_id].c_it->id) == id_set.end() 00322 && smooth > min_smoothness) 00323 { 00324 vertex_todo.push_back(new_id); 00325 id_set.insert(g_[new_id].c_it->id); 00326 adjacent_clusters.push_back(g_[new_id].c_it); 00327 } 00328 } 00329 } 00330 } 00331 */ 00332 00333 #endif