voxel_grid_graph_builder.hpp
Go to the documentation of this file.
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2014-, Open Perception, Inc.
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of the copyright holder(s) nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38#ifndef PCL_GRAPH_IMPL_VOXEL_GRID_GRAPH_BUILDER_CPP
39#define PCL_GRAPH_IMPL_VOXEL_GRID_GRAPH_BUILDER_CPP
40
41
42#include <boost/unordered_map.hpp>
43
44#include <pcl/common/centroid.h>
45#include <pcl/common/common.h>
46#include <pcl/common/io.h>
47
48#pragma GCC diagnostic push
49#pragma GCC diagnostic ignored "-Wignored-qualifiers"
50#pragma GCC diagnostic push
51#pragma GCC diagnostic ignored "-Wpedantic"
52#include <pcl/octree/octree.h>
53#pragma GCC diagnostic pop
54#pragma GCC diagnostic pop
55
57
58/* The function below is required in order to use boost::unordered_map with
59 * pcl::octree::OctreeKey key type. It simply hashes the x, y, z array of
60 * indices, because it uniquely defines the key. */
61
62#pragma GCC diagnostic push
63#pragma GCC diagnostic ignored "-Wunused-function"
64
65namespace pcl
66{
67
68 namespace octree
69 {
70
71 static size_t
72 hash_value(const OctreeKey& b)
73 {
74 return boost::hash_value(b.key_);
75 }
76
77 } // namespace octree
78
79} // namespace pcl
80
81#pragma GCC diagnostic pop
82
83template <typename PointT, typename GraphT>
84void
86{
87 if (!initCompute())
88 {
89 graph = GraphT();
90 deinitCompute();
91 return;
92 }
93
94 typename pcl::PointCloud<PointT>::Ptr transformed(new pcl::PointCloud<PointT>);
95 pcl::copyPointCloud(*input_, *transformed);
96 for (size_t i = 0; i < transformed->size(); ++i)
97 {
98 PointT& p = transformed->points[i];
99 p.x /= p.z;
100 p.y /= p.z;
101 p.z = std::log(p.z);
102 }
103
104 Eigen::Vector4f min, max;
105 pcl::getMinMax3D(*transformed, *indices_, min, max);
106
107 // Create and initialize an Octree that stores point indices
108 typedef pcl::octree::OctreePointCloud<PointT> Octree;
109 Octree octree(voxel_resolution_);
110 octree.defineBoundingBox(min(0), min(1), min(2), max(0), max(1), max(2));
111 octree.setInputCloud(transformed, indices_);
112 octree.addPointsFromInputCloud();
113
114 graph = GraphT(octree.getLeafCount());
115
116 typedef boost::unordered_map<pcl::octree::OctreeKey, VertexId> KeyVertexMap;
117 KeyVertexMap key_to_vertex_map;
118
119 point_to_vertex_map_.clear();
120 point_to_vertex_map_.resize(transformed->size(), std::numeric_limits<VertexId>::max());
121
122 typename Octree::LeafNodeIterator leaf_itr = octree.leaf_depth_begin();
123 for (VertexId v = 0; leaf_itr != octree.leaf_depth_end(); ++leaf_itr, ++v)
124 {
125 // Step 1: compute leaf centroid and fill in corresponding elements of the
126 // point to vertex map.
127 pcl::CentroidPoint<PointInT> centroid;
128 std::vector<int>& indices = leaf_itr.getLeafContainer().getPointIndicesVector();
129 for (int& index : indices)
130 {
131 centroid.add(input_->operator[](index));
133 }
134 centroid.get(graph[v]);
135
136 // Step 2: fill in octree key to vertex map.
137 octree::OctreeKey key = leaf_itr.getCurrentOctreeKey();
138 key_to_vertex_map[key] = v;
139
140 // Step 3: find neighbors and insert edges.
141 octree::OctreeKey neighbor_key;
142 for (int dx = (key.x > 0) ? -1 : 0; dx <= 1; ++dx)
143 {
144 neighbor_key.x = static_cast<std::uint32_t>(key.x + dx);
145 for (int dy = (key.y > 0) ? -1 : 0; dy <= 1; ++dy)
146 {
147 neighbor_key.y = static_cast<std::uint32_t>(key.y + dy);
148 for (int dz = (key.z > 0) ? -1 : 0; dz <= 1; ++dz)
149 {
150 neighbor_key.z = static_cast<std::uint32_t>(key.z + dz);
151 typename KeyVertexMap::iterator f = key_to_vertex_map.find(neighbor_key);
152 if (f != key_to_vertex_map.end() && v != f->second)
153 {
154 boost::add_edge(v, f->second, graph);
155 }
156 }
157 }
158 }
159 }
160 graph.m_graph.m_point_cloud->header = input_->header;
161}
162
163#endif /* PCL_GRAPH_IMPL_VOXEL_GRID_GRAPH_BUILDER_CPP */
uint8_t index
boost::graph_traits< GraphT >::vertex_descriptor VertexId
std::vector< VertexId > point_to_vertex_map_
virtual void compute(GraphT &graph)
Build a graph based on the provided input data.
T min(T t1, T t2)
Definition gdiam.h:44
T max(T t1, T t2)
Definition gdiam.h:51
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...