38 #ifndef PCL_GRAPH_IMPL_COMMON_CPP
39 #define PCL_GRAPH_IMPL_COMMON_CPP
43 #include <boost/concept_check.hpp>
44 #include <boost/graph/connected_components.hpp>
47 #include <pcl/point_cloud.h>
48 #include <pcl/features/normal_3d.h>
54 template <
typename Graph>
void
61 typedef typename Graph::vertex_descriptor
VertexId;
65 for (
VertexId vertex = 0; vertex < boost::num_vertices(graph); ++vertex)
67 std::vector<int> neighbors(1, vertex);
68 neighbors.reserve(256);
71 for (boost::tie(vi1, ve1) = boost::adjacent_vertices(vertex, graph); vi1 != ve1; ++vi1)
73 neighbors.push_back(*vi1);
74 if (!neighborhood_1ring)
75 for (boost::tie(vi2, ve2) = boost::adjacent_vertices(*vi1, graph); vi2 != ve2; ++vi2)
77 neighbors.push_back(*vi2);
81 Eigen::Vector4f normal;
83 pcl::computePointNormal(*cloud, neighbors, normal, curvature);
94 graph[vertex].getNormalVector4fMap().any())
96 if (graph[vertex].getNormalVector4fMap().
dot(normal) < 0)
103 pcl::flipNormalTowardsViewpoint(graph[vertex], 0.0f, 0.0f, 0.0f, normal);
105 graph[vertex].getNormalVector4fMap() = normal;
106 graph[vertex].curvature = std::isnan(curvature) ? 0.0f : curvature;
110 template <
typename Graph>
void
117 typedef typename Graph::vertex_descriptor
VertexId;
120 std::vector<float> convexities(boost::num_vertices(graph), 0.0f);
121 for (boost::tie(ei, ee) = boost::edges(graph); ei != ee; ++ei)
125 const PointT& p1 = graph[v1];
126 const PointT& p2 = graph[v2];
127 const Eigen::Vector3f& d = p2.getVector3fMap() - p1.getVector3fMap();
128 const Eigen::Vector3f& n1 = p1.getNormalVector3fMap();
129 const Eigen::Vector3f& n2 = p2.getNormalVector3fMap();
130 float c = (((d - d.dot(n1) * n1).
dot(n2) > 0 ? 1.0 : -1.0) * (n1 - n2).squaredNorm());
131 convexities[v1] +=
c;
132 convexities[v2] +=
c;
135 for (
VertexId vertex = 0; vertex < boost::num_vertices(graph); ++vertex)
137 graph[vertex].curvature = copysign(graph[vertex].curvature, convexities[vertex]);
141 template <
typename Graph>
size_t
143 std::vector<boost::reference_wrapper<Graph> >& subgraphs)
145 typedef typename Graph::vertex_descriptor
VertexId;
146 typedef typename boost::reference_wrapper<Graph>
GraphRef;
149 std::vector<int> component(boost::num_vertices(graph));
150 size_t num_components = boost::connected_components(graph, &component[0]);
151 for (
size_t i = 0; i < num_components; ++i)
153 subgraphs.push_back(
GraphRef(graph.create_subgraph()));
155 for (
VertexId v = 0;
v < boost::num_vertices(graph); ++
v)
157 boost::add_vertex(graph.local_to_global(
v), subgraphs.at(component[
v]).get());
159 return num_components;
162 template <
typename Graph,
typename ColorMap>
size_t
165 std::vector<boost::reference_wrapper<Graph> >& subgraphs)
167 typedef typename Graph::vertex_descriptor
VertexId;
168 typedef typename boost::reference_wrapper<Graph>
GraphRef;
169 typedef typename boost::property_traits<ColorMap>::value_type
Color;
170 typedef std::map<Color, GraphRef> SubgraphMap;
171 typedef typename SubgraphMap::iterator SubgraphMapIterator;
173 SubgraphMap subgraph_map;
174 for (
VertexId v = 0;
v < boost::num_vertices(graph); ++
v)
176 SubgraphMapIterator itr = subgraph_map.find(color_map[
v]);
177 if (itr == subgraph_map.end())
179 GraphRef subgraph(graph.create_subgraph());
180 boost::add_vertex(graph.local_to_global(
v), subgraph.get());
181 subgraph_map.insert(std::make_pair(color_map[
v], subgraph));
185 boost::add_vertex(graph.local_to_global(
v), itr->second.get());
190 for (SubgraphMapIterator itr = subgraph_map.begin(); itr != subgraph_map.end(); ++itr)
192 subgraphs.push_back(itr->second);
195 return subgraphs.size();
198 template <
typename Graph>
void
200 const pcl::PointIndices&
indices,
201 std::vector<boost::reference_wrapper<Graph> >& subgraphs)
203 typedef typename Graph::vertex_descriptor
VertexId;
204 typedef typename boost::reference_wrapper<Graph>
GraphRef;
206 std::set<int> index_set;
209 subgraphs.push_back(
GraphRef(graph.create_subgraph()));
210 subgraphs.push_back(
GraphRef(graph.create_subgraph()));
211 Graph& first = subgraphs.at(0).get();
212 Graph& second = subgraphs.at(1).get();
214 for (
size_t i = 0; i <
indices.indices.size(); ++i)
216 index_set.insert(
indices.indices[i]);
217 boost::add_vertex(
indices.indices[i], first);
220 for (
VertexId v = 0;
v < boost::num_vertices(graph); ++
v)
221 if (!index_set.count(
v))
223 boost::add_vertex(
v, second);
227 template <
typename Graph>
void
229 const std::vector<pcl::PointIndices>&
indices,
230 std::vector<boost::reference_wrapper<Graph> >& subgraphs)
232 typedef typename Graph::vertex_descriptor
VertexId;
233 typedef typename boost::reference_wrapper<Graph>
GraphRef;
235 std::set<int> index_set;
238 for (
size_t i = 0; i <
indices.size(); ++i)
240 subgraphs.push_back(
GraphRef(graph.create_subgraph()));
241 Graph&
s = subgraphs.back().get();
242 for (
size_t j = 0; j <
indices[i].indices.size(); ++j)
249 subgraphs.push_back(
GraphRef(graph.create_subgraph()));
250 Graph&
s = subgraphs.back().get();
251 for (
VertexId v = 0;
v < boost::num_vertices(graph); ++
v)
252 if (!index_set.count(
v))
254 boost::add_vertex(
v,
s);
258 template <
typename Graph>
void
264 typedef typename Graph::vertex_descriptor
VertexId;
266 std::vector<float> K(boost::num_vertices(graph), 0);
267 Eigen::MatrixXf P(boost::num_vertices(graph), 3);
271 for (boost::tie(ei, ee) = boost::edges(graph); ei != ee; ++ei)
275 const Eigen::Vector3f& p = graph[src].getVector3fMap();
276 const Eigen::Vector3f&
q = graph[tgt].getVector3fMap();
277 const Eigen::Vector3f& np = graph[src].getNormalVector3fMap();
278 const Eigen::Vector3f& nq = graph[tgt].getNormalVector3fMap();
279 Eigen::Vector3f x = p -
q;
280 float d1 = nq.dot(x);
281 float d2 = np.dot(-x);
282 float ws = std::exp(- std::pow(x.norm(), 2) / (2 * std::pow(spatial_sigma, 2)));
283 float wi1 = std::exp(- std::pow(d1, 2) / (2 * std::pow(influence_sigma, 2)));
284 float wi2 = std::exp(- std::pow(d2, 2) / (2 * std::pow(influence_sigma, 2)));
289 P.row(src) += nq * d1 * w1;
290 P.row(tgt) += np * d2 * w2;
293 for (
VertexId v = 0;
v < boost::num_vertices(graph); ++
v)
296 graph[
v].getVector3fMap() -= P.row(
v) / K[
v];