template<typename PointT, typename OutEdgeListS = boost::vecS, typename DirectedS = boost::undirectedS, typename VertexProperty = boost::no_property, typename EdgeProperty = boost::no_property, typename EdgeListS = boost::listS>
class pcl::graph::point_cloud_graph< PointT, OutEdgeListS, DirectedS, VertexProperty, EdgeProperty, EdgeListS >
A sibling of boost::adjacency_list with PCL points bundled in vertices and copy-free access to them as a PCL point cloud.
Motivation
Boost Graph Library has a concept of bundled properties, i.e. custom data types that may be stored in graph vertices and conveniently accessed with operator[]. In the context of PCL it makes a lot of sense to have PCL points bundled in graph vertices. The following specialization of boost::adjacency_list achieves that:
typedef
boost::adjacency_list<
boost::vecS
, boost::vecS
, boost::undirectedS
, pcl::PointXYZ>
Graph
A graph-based algorithm can easily access points associated with graph vertices:
Graph::vertex_descriptor v1 = boost::add_vertex (
graph);
Graph::vertex_descriptor v2 = boost::add_vertex (
graph);
graph[v1] = pcl::PointXYZ (1, 2, 3);
The problem though is that there is no efficient way to put the point cloud data inside the graph and retrieve it back. Suppose that in some application there is a point cloud that should first be filtered using some PCL tools (e.g. pcl::PassThrough filter), then a graph-based algorithm should be applied to it, and finally some more processing using PCL tools is required. The user will need to copy all the points of the original point cloud one-by-one to the graph, run the algorithm, and then copy it back one-by-one again.
Solution
point_cloud_graph resolves this issue by storing bundled points internally as a PCL point cloud. In fact, it stores a shared pointer to a point cloud, so input and output of points is really copy-free. One can create a new graph based on an existing point cloud:
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> (10, 1);
assert (10 == boost::num_vertices (
graph));
assert (14 == cloud->points[1].x);
A sibling of boost::adjacency_list with PCL points bundled in vertices and copy-free access to them a...
Definition point_cloud_graph.h:330
The internal point cloud as a whole may be accessed using pcl::graph::point_cloud (Graph& g):
pcl::io::savePCDFile (
"output.pcd", *
data);
uint8_t data[1]
Definition EtherCATFrame.h:10
pcl::PointCloud< P >::Ptr point_cloud(PCG &g)
Retrieve the point cloud stored in a point cloud graph.
Definition point_cloud_graph.h:690
Despite the fact that the point data are stored in a PCL point cloud, all the standard BGL features associated with bundled properties are supported, including operator[] and get/put access.
point_cloud_graph uses the same back-bone implementation as boost::adjacency_list and therefore models the same concepts and may be used everywhere boost::adjacency_list could. In particular, the very same functions could be used to add and remove vertices, access properties, iterate over edges, etc.
As boost::adjacency_list, point_cloud_graph allows to configure itself with a number of template parameters. They are almost the same as in boost::adjacency_list, though there are several differences:
There is a required template parameter PointT which allows the user to select the type of PCL points to be bundled in graph vertices;
Note that the VertexProperty parameter is still available for the user, so it is possible to additionally attach as many internal properties (such as vertex_color_t) as needed.
- The default value for
Directed parameter is changed to undirectedS since it is more relevant in the context of point cloud processing;
The vertex-list of the graph is constrained to be std::vector. The user has no control over it as there is no VertexList template parameter;
The choice of the container for the vertex-list determines the space complexity of the graph structure, as well as the time complexity of the various graph operations, see using boost::adjacency_list for a more detailed discussion. In the case of point_cloud_graph the vertex bundled properties (PCL points) are stored in a PCL point cloud (which has std::vector behind the scenes), so it is only logical to have std::vector as the container type for the vertex-list itself.
There is no GraphProperty template parameter.
boost::adjacency_list provides a facility to store an arbitrary piece of data associated with the graph as a whole (graph property). While being useful in certain cases, we do not consider this as a vital feature and have sacrificed it to support boost::subgraph. For more details please refer to the section about boost::subgraph below.
boost::subgraph provides a convenient mechanism to keep track of a graph and its induced subgraphs. Two issues have been accounted for in order to allow smooth inter-operation between point_cloud_graph and boost::subgraph.
Fixed interface
boost::subgraph is a template class that is wrapped around a graph class rather than a class that inherits from a graph class. Therefore if we want it to be possible to use point_cloud_graph either way (plain or wrapped by boost::subgraph), we have to limit ourselves to the interface exposed by boost::subgraph. In particular, we can not have a PCL point cloud-based constructor for point_cloud_graph because (for apparent reasons) boost::subgraph does not have it. However, the ability to construct a point_cloud_graph from an existing PCL point cloud is an essential feature. We noted that boost::subgraph has a GraphProperty-based constructor that could be re-used as a desired PCL point cloud-based constructor if we alias GraphProperty to PCL point cloud. Thus GraphProperty is used to support internal mechanics of point_cloud_graph and is no longer available to the user.
Lack of internal storage for points
Recall that point_cloud_graph stores the points bundled in its vertices inside a PCL point cloud. It could be conveniently retrieved using pcl::graph::point_cloud (Graph& g) and then used in PCL algorithms. boost::subgraph, however, is designed in such a way that it stores the indices of the vertices and edges of the parent (root) graph that belong to it, but not the data associated with these vertices and edges. In other words, a hierarchy of subgraphs (each of which represents a particular subset of vertices and edges of the root graph) shares common vertex/edge data, and all these data are contained inside the root graph. Consequently, there does not exist a PCL point cloud for each subgraph, but rather a single PCL point cloud for the root graph. This raises a question as of how the pcl::graph::point_cloud (Subgraph& g) function should be implemented.
One option is to construct a new PCL point cloud and fill it with subgraph's points. This, however, would be inconsistent with the behavior of pcl::graph::point_cloud (Graph& g), which simply returns a pointer (meaning it is O(1) operation) that could be used to read and modify the points of the graph. Luckily, working with subsets of point clouds is such a common task in the PCL world that pcl::PCLBase class (which lies at the top of the hierarchy of PCL algorithms) has a means for the user to supply an input point cloud and a vector of indices to which the processing should be limited to. Therefore, we decided that pcl::graph::point_cloud (Subgraph& g) should return the PCL point cloud of its root graph (that is, the whole set of points), and there should be an auxiliary function pcl::graph::indices (Subgraph& g) that returns indices of the points that belong to the subgraph.
Specification
As was noted, point_cloud_graph is virtually the same as boost::adjacency_list. Please refer to its documentation. The specifications below only highlight the differences.
Template parameters
| Parameter | Description | Default |
| PointT | Type of PCL points bundled in graph vertices | – |
| OutEdgeList | Selector for the container used to represent the edge-list for each of the vertices | vecS |
| Directed | Selector to choose whether the graph is directed/undirected/bidirectional | undirectedS |
| VertexProperty | For specifying internal vertex property storage (apart from bundled points) | no_property |
| EdgeProperty | For specifying internal edge property storage | no_property |
| EdgeList | Selector for the container used to represent the edge-list for the graph | listS |
Model of
PointCloudGraph, VertexAndEdgeListGraph, VertexMutablePropertyGraph, EdgeMutablePropertyGraph, CopyConstructible, Assignable
Probably it could also support Serializable, however this option has not been explored.
Associated types
point_cloud_graph_traits structure provides a means to access the type of points bundled in the point_cloud_graph and, for convenience, the types of PCL point cloud and shared pointer to PCL point cloud of those points.
Non-member functions
typename pcl::PointCloud<PointT>::Ptr
point_cloud_graph(const point_cloud_ptr &p=point_cloud_ptr(new point_cloud_type))
Construct a graph based on existing point cloud.
Definition point_cloud_graph.h:379
Return a shared pointer to the PCL point cloud stored internally. There are both const and non-const versions.
typename pcl::PointCloud<PointT>::Ptr
Return a shared pointer to the PCL point cloud stored in the root graph. There are both const and non-const versions.
pcl::PointIndices::Ptr
pcl::PointIndices::Ptr indices(const PCG &g)
Retrieve the indices of the points of the point cloud stored in a point cloud graph that actually bel...
Definition point_cloud_graph.h:717
Return a shared pointer to a vector of indices of the points that belong to this graph. Since point_cloud_graph is a complete graph (i.e. it is not a subgraph of some other graph), the returned indices are guaranteed to be [0..N-1], where N is the number of vertices. There are both const- and non-const- versions.
Return a shared pointer to a vector of indices of the points of the root graph that belong to this subgraph. There are both const- and non-const- versions.
- Author
- Sergey Alexandrov