#pragma once #include "Common.h" #include #include #include #include namespace CP { typedef boost::graph_traits >::edge_descriptor EdgeDescriptor; template class VertexAttribute { public: typedef T calc_type; public: T weight; //weight of the observation std::vector observation; //observed value std::vector value; //current value uint32_t color; //field use for the graph cut bool isBorder; //is the node part of an activated edge uint32_t in_component; //index of the component in which the node belong public: VertexAttribute(uint32_t dim = 1, T weight=1.) :weight(weight), observation(dim,0.),value(dim,0.),color(-1) ,isBorder(false){} }; template class EdgeAttribute { public: typedef T calc_type; public: uint32_t index; //index of the edge (necessary for graph cuts) EdgeDescriptor edge_reverse; //pointer to the reverse edge, also necessary for graph cuts T weight; //weight of the edge T capacity; //capacity in the flow graph T residualCapacity; //necessary for graph cuts bool isActive; //is the edge in the support of the values bool realEdge; //is the edge between real nodes or link to source/sink public: EdgeAttribute(T weight=1., uint32_t eIndex = 0, bool real = true) :index(eIndex), weight(weight), capacity(weight), residualCapacity(0), isActive(!real), realEdge(real) {} }; template< typename T> using Graph = typename boost::adjacency_list, EdgeAttribute >; template< typename T> using VertexDescriptor = typename boost::graph_traits>::vertex_descriptor; template< typename T> using VertexIndex = typename boost::graph_traits>::vertices_size_type; template< typename T> using EdgeIndex = typename boost::graph_traits>::edges_size_type; template< typename T> using VertexIterator = typename boost::graph_traits>::vertex_iterator; template< typename T> using EdgeIterator = typename boost::graph_traits>::edge_iterator; template using VertexAttributeMap = boost::vec_adj_list_vertex_property_map, Graph* , VertexAttribute, VertexAttribute &, boost::vertex_bundle_t >; template using EdgeAttributeMap = boost::adj_list_edge_property_map< boost::directed_tag, EdgeAttribute, EdgeAttribute & , long unsigned int, CP::EdgeAttribute, boost::edge_bundle_t>; template using VertexIndexMap = typename boost::property_map, boost::vertex_index_t>::type; template using EdgeIndexMap = typename boost::property_map, uint32_t EdgeAttribute::*>::type; template bool addDoubledge(Graph & g, const VertexDescriptor & source, const VertexDescriptor & target ,const T weight, uint32_t eIndex, EdgeAttributeMap & edge_attribute_map, bool real = true) { // Add edges between two vertices. We have to create the edge and the reverse edge, // then add the edge_reverse as the corresponding reverse edge to 'edge', and then add 'edge' // as the corresponding reverse edge to 'edge_reverse' EdgeDescriptor edge, edge_reverse; std::pair edge_added = boost::add_edge(source, target, g); if (edge_added.second) { edge = edge_added.first; edge_reverse = boost::add_edge(target, source, g).first; EdgeAttribute attrib_edge(weight,eIndex,real); EdgeAttribute attrib_edge_reverse(weight,eIndex+1,real); attrib_edge.edge_reverse = edge_reverse; attrib_edge_reverse.edge_reverse = edge; edge_attribute_map(edge) = attrib_edge; edge_attribute_map(edge_reverse) = attrib_edge_reverse; return true; } else { return false; } } }