Point Cloud Library (PCL) 1.15.1-dev
Loading...
Searching...
No Matches
rigid_transform_space.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2010-2012, Willow Garage, 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 Willow Garage, Inc. 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
39/*
40 * rigid_transform_space.h
41 *
42 * Created on: Feb 15, 2013
43 * Author: papazov
44 */
45
46#pragma once
47
48#include "simple_octree.h"
49#include "model_library.h"
50#include <pcl/pcl_exports.h>
51#include <list>
52#include <map>
53
54namespace pcl
55{
56 namespace recognition
57 {
59 {
60 public:
61 class Entry
62 {
63 public:
65 {
66 aux::set3 (axis_angle_, 0.0f);
67 aux::set3 (translation_, 0.0f);
68 }
69
70 Entry (const Entry& src)
72 {
73 aux::copy3 (src.axis_angle_, this->axis_angle_);
74 aux::copy3 (src.translation_, this->translation_);
75 }
76
77 const Entry& operator = (const Entry& src)
78 {
79 if (this == &src)
80 return *this;
82 aux::copy3 (src.axis_angle_, this->axis_angle_);
83 aux::copy3 (src.translation_, this->translation_);
84
85 return *this;
86 }
87
88 inline const Entry&
89 addRigidTransform (const float axis_angle[3], const float translation[3])
90 {
91 aux::add3 (this->axis_angle_, axis_angle);
92 aux::add3 (this->translation_, translation);
94
95 return *this;
96 }
97
98 inline void
99 computeAverageRigidTransform (float *rigid_transform = nullptr)
100 {
101 if ( num_transforms_ >= 2 )
102 {
103 float factor = 1.0f/static_cast<float> (num_transforms_);
104 aux::mult3 (axis_angle_, factor);
105 aux::mult3 (translation_, factor);
106 num_transforms_ = 1;
107 }
108
109 if ( rigid_transform )
110 {
111 // Save the rotation (in matrix form)
113 // Save the translation
114 aux::copy3 (translation_, rigid_transform + 9);
115 }
116 }
117
118 inline const float*
120 {
121 return (axis_angle_);
122 }
123
124 inline const float*
126 {
127 return (translation_);
128 }
129
130 inline int
132 {
133 return (num_transforms_);
134 }
135
136 protected:
139 };// class Entry
140
141 public:
142 RotationSpaceCell () = default;
144 {
145 model_to_entry_.clear ();
146 }
147
148 inline std::map<const ModelLibrary::Model*,Entry>&
150 {
151 return (model_to_entry_);
152 }
153
154 inline const RotationSpaceCell::Entry*
155 getEntry (const ModelLibrary::Model* model) const
156 {
157 auto res = model_to_entry_.find (model);
158
159 if ( res != model_to_entry_.end () )
160 return (&res->second);
161
162 return (nullptr);
163 }
164
165 inline const RotationSpaceCell::Entry&
166 addRigidTransform (const ModelLibrary::Model* model, const float axis_angle[3], const float translation[3])
167 {
168 return model_to_entry_[model].addRigidTransform (axis_angle, translation);
169 }
170
171 protected:
172 std::map<const ModelLibrary::Model*,Entry> model_to_entry_;
173 }; // class RotationSpaceCell
174
186
188
189 /** \brief This is a class for a discrete representation of the rotation space based on the axis-angle representation.
190 * This class is not supposed to be very general. That's why it is dependent on the class ModelLibrary.
191 *
192 * \author Chavdar Papazov
193 * \ingroup recognition
194 */
195 class PCL_EXPORTS RotationSpace
196 {
197 public:
198 /** \brief We use the axis-angle representation for rotations. The axis is encoded in the vector
199 * and the angle is its magnitude. This is represented in an octree with bounds [-pi, pi]^3. */
200 RotationSpace (float discretization)
201 {
202 float min = -(AUX_PI_FLOAT + 0.000000001f), max = AUX_PI_FLOAT + 0.000000001f;
203 float bounds[6] = {min, max, min, max, min, max};
204
205 // Build the voxel structure
206 octree_.build (bounds, discretization, &cell_creator_);
207 }
208
209 virtual ~RotationSpace ()
210 {
211 octree_.clear ();
212 }
213
214 inline void
215 setCenter (const float* c)
216 {
217 center_[0] = c[0];
218 center_[1] = c[1];
219 center_[2] = c[2];
220 }
221
222 inline const float*
223 getCenter () const { return center_;}
224
225 inline bool
226 getTransformWithMostVotes (const ModelLibrary::Model* model, float rigid_transform[12]) const
227 {
228 RotationSpaceCell::Entry with_most_votes;
229 const std::vector<CellOctree::Node*>& full_leaves = octree_.getFullLeaves ();
230 int max_num_transforms = 0;
231
232 // For each full leaf
233 for (const auto &full_leaf : full_leaves)
234 {
235 // Is there an entry for 'model' in the current cell
236 const RotationSpaceCell::Entry *entry = full_leaf->getData ().getEntry (model);
237 if ( !entry )
238 continue;
239
240 int num_transforms = entry->getNumberOfTransforms ();
241 const std::set<CellOctree::Node*>& neighs = full_leaf->getNeighbors ();
242
243 // For each neighbor
244 for (const auto &neigh : neighs)
245 {
246 const RotationSpaceCell::Entry *neigh_entry = neigh->getData ().getEntry (model);
247 if ( !neigh_entry )
248 continue;
249
250 num_transforms += neigh_entry->getNumberOfTransforms ();
251 }
252
253 if ( num_transforms > max_num_transforms )
254 {
255 with_most_votes = *entry;
256 max_num_transforms = num_transforms;
257 }
258 }
259
260 if ( !max_num_transforms )
261 return false;
262
263 with_most_votes.computeAverageRigidTransform (rigid_transform);
264
265 return true;
266 }
267
268 inline bool
269 addRigidTransform (const ModelLibrary::Model* model, const float axis_angle[3], const float translation[3])
270 {
271 CellOctree::Node* cell = octree_.createLeaf (axis_angle[0], axis_angle[1], axis_angle[2]);
272
273 if ( !cell )
274 {
275 const float *b = octree_.getBounds ();
276 printf ("WARNING in 'RotationSpace::%s()': the provided axis-angle input (%f, %f, %f) is "
277 "out of the rotation space bounds ([%f, %f], [%f, %f], [%f, %f]).\n",
278 __func__, axis_angle[0], axis_angle[1], axis_angle[2], b[0], b[1], b[2], b[3], b[4], b[5]);
279 return (false);
280 }
281
282 // Add the rigid transform to the cell
283 cell->getData ().addRigidTransform (model, axis_angle, translation);
284
285 return (true);
286 }
287
288 protected:
291 float center_[3];
292 };// class RotationSpace
293
295 {
296 public:
298
299 virtual ~RotationSpaceCreator() = default;
300
302 {
303 auto *rot_space = new RotationSpace (discretization_);
304 rot_space->setCenter (leaf->getCenter ());
305 rotation_spaces_.push_back (rot_space);
306
307 ++counter_;
308
309 return (rot_space);
310 }
311
312 void
313 setDiscretization (float value){ discretization_ = value;}
314
315 int
317
318 const std::list<RotationSpace*>&
320
321 std::list<RotationSpace*>&
323
324 void
326 {
327 counter_ = 0;
328 rotation_spaces_.clear ();
329 }
330
331 protected:
333 int counter_{0};
334 std::list<RotationSpace*> rotation_spaces_;
335 };
336
338
339 class PCL_EXPORTS RigidTransformSpace
340 {
341 public:
343 virtual ~RigidTransformSpace (){ this->clear ();}
344
345 inline void
346 build (const float* pos_bounds, float translation_cell_size, float rotation_cell_size)
347 {
348 this->clear ();
349
350 rotation_space_creator_.setDiscretization (rotation_cell_size);
351
352 pos_octree_.build (pos_bounds, translation_cell_size, &rotation_space_creator_);
353 }
354
355 inline void
357 {
358 pos_octree_.clear ();
359 rotation_space_creator_.reset ();
360 }
361
362 inline std::list<RotationSpace*>&
364 {
365 return (rotation_space_creator_.getRotationSpaces ());
366 }
367
368 inline const std::list<RotationSpace*>&
370 {
371 return (rotation_space_creator_.getRotationSpaces ());
372 }
373
374 inline int
376 {
377 return (rotation_space_creator_.getNumberOfRotationSpaces ());
378 }
379
380 inline bool
381 addRigidTransform (const ModelLibrary::Model* model, const float position[3], const float rigid_transform[12])
382 {
383 // Get the leaf 'position' ends up in
384 RotationSpaceOctree::Node* leaf = pos_octree_.createLeaf (position[0], position[1], position[2]);
385
386 if ( !leaf )
387 {
388 printf ("WARNING in 'RigidTransformSpace::%s()': the input position (%f, %f, %f) is out of bounds.\n",
389 __func__, position[0], position[1], position[2]);
390 return (false);
391 }
392
393 float rot_angle, axis_angle[3];
394 // Extract the axis-angle representation from the rotation matrix
395 aux::rotationMatrixToAxisAngle (rigid_transform, axis_angle, rot_angle);
396 // Multiply the axis by the angle to get the final representation
397 aux::mult3 (axis_angle, rot_angle);
398
399 // Now, add the rigid transform to the rotation space
400 leaf->getData ().addRigidTransform (model, axis_angle, rigid_transform + 9);
401
402 return (true);
403 }
404
405 protected:
408 }; // class RigidTransformSpace
409 } // namespace recognition
410} // namespace pcl
Stores some information about the model.
bool addRigidTransform(const ModelLibrary::Model *model, const float position[3], const float rigid_transform[12])
void build(const float *pos_bounds, float translation_cell_size, float rotation_cell_size)
std::list< RotationSpace * > & getRotationSpaces()
const std::list< RotationSpace * > & getRotationSpaces() const
const float * getAxisAngle() const
float translation_[3]
const Entry & operator=(const Entry &src)
int getNumberOfTransforms() const
const float * getTranslation() const
const Entry & addRigidTransform(const float axis_angle[3], const float translation[3])
int num_transforms_
Entry()
void computeAverageRigidTransform(float *rigid_transform=nullptr)
float axis_angle_[3]
Entry(const Entry &src)
RotationSpaceCell * create(const SimpleOctree< RotationSpaceCell, RotationSpaceCellCreator, float >::Node *)
const RotationSpaceCell::Entry & addRigidTransform(const ModelLibrary::Model *model, const float axis_angle[3], const float translation[3])
const RotationSpaceCell::Entry * getEntry(const ModelLibrary::Model *model) const
std::map< const ModelLibrary::Model *, Entry > model_to_entry_
std::map< const ModelLibrary::Model *, Entry > & getEntries()
RotationSpace * create(const SimpleOctree< RotationSpace, RotationSpaceCreator, float >::Node *leaf)
std::list< RotationSpace * > rotation_spaces_
const std::list< RotationSpace * > & getRotationSpaces() const
std::list< RotationSpace * > & getRotationSpaces()
This is a class for a discrete representation of the rotation space based on the axis-angle represent...
bool addRigidTransform(const ModelLibrary::Model *model, const float axis_angle[3], const float translation[3])
bool getTransformWithMostVotes(const ModelLibrary::Model *model, float rigid_transform[12]) const
RotationSpace(float discretization)
We use the axis-angle representation for rotations.
RotationSpaceCellCreator cell_creator_
void axisAngleToRotationMatrix(const T axis_angle[3], T rotation_matrix[9])
brief Computes a rotation matrix from the provided input vector 'axis_angle'.
Definition auxiliary.h:411
void mult3(T *v, T scalar)
v = scalar*v.
Definition auxiliary.h:221
void add3(T a[3], const T b[3])
a += b
Definition auxiliary.h:150
void set3(T v[3], T value)
v[0] = v[1] = v[2] = value
Definition auxiliary.h:109
void copy3(const T src[3], T dst[3])
dst = src
Definition auxiliary.h:116