Point Cloud Library (PCL)  1.14.0-dev
linemod.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, 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 #pragma once
39 
40 #include <vector>
41 #include <cstddef>
42 #include <cstring>
43 #include <pcl/pcl_macros.h>
44 #include <pcl/recognition/quantizable_modality.h>
45 #include <pcl/recognition/region_xy.h>
46 #include <pcl/recognition/sparse_quantized_multi_mod_template.h>
47 
48 namespace pcl
49 {
50 
51  /** \brief Stores a set of energy maps.
52  * \author Stefan Holzer
53  */
55  {
56  public:
57  /** \brief Constructor. */
58  EnergyMaps () = default;
59  /** \brief Destructor. */
60  virtual ~EnergyMaps () = default;
61 
62  /** \brief Returns the width of the energy maps. */
63  inline std::size_t
64  getWidth () const
65  {
66  return (width_);
67  }
68 
69  /** \brief Returns the height of the energy maps. */
70  inline std::size_t
71  getHeight () const
72  {
73  return (height_);
74  }
75 
76  /** \brief Returns the number of bins used for quantization (which is equal to the number of energy maps). */
77  inline std::size_t
78  getNumOfBins () const
79  {
80  return (nr_bins_);
81  }
82 
83  /** \brief Initializes the set of energy maps.
84  * \param[in] width the width of the energy maps.
85  * \param[in] height the height of the energy maps.
86  * \param[in] nr_bins the number of bins used for quantization.
87  */
88  void
89  initialize (const std::size_t width, const std::size_t height, const std::size_t nr_bins)
90  {
91  maps_.resize(nr_bins, nullptr);
92  width_ = width;
93  height_ = height;
94  nr_bins_ = nr_bins;
95 
96  const std::size_t mapsSize = width*height;
97 
98  for (auto &map : maps_)
99  {
100  //maps_[map_index] = new unsigned char[mapsSize];
101  map = reinterpret_cast<unsigned char*> (aligned_malloc (mapsSize));
102  std::fill_n(map, mapsSize, 0);
103  }
104  }
105 
106  /** \brief Releases the internal data. */
107  void
109  {
110  for (auto &map : maps_)
111  //if (maps_[map_index] != NULL) delete[] maps_[map_index];
112  if (map != nullptr) aligned_free (map);
113 
114  maps_.clear ();
115  width_ = 0;
116  height_ = 0;
117  nr_bins_ = 0;
118  }
119 
120  /** \brief Operator for accessing a specific element in the set of energy maps.
121  * \param[in] bin_index the quantization bin (states which of the energy maps to access).
122  * \param[in] col_index the column index within the specified energy map.
123  * \param[in] row_index the row index within the specified energy map.
124  */
125  inline unsigned char &
126  operator() (const std::size_t bin_index, const std::size_t col_index, const std::size_t row_index)
127  {
128  return (maps_[bin_index][row_index*width_ + col_index]);
129  }
130 
131  /** \brief Operator for accessing a specific element in the set of energy maps.
132  * \param[in] bin_index the quantization bin (states which of the energy maps to access).
133  * \param[in] index the element index within the specified energy map.
134  */
135  inline unsigned char &
136  operator() (const std::size_t bin_index, const std::size_t index)
137  {
138  return (maps_[bin_index][index]);
139  }
140 
141  /** \brief Returns a pointer to the data of the specified energy map.
142  * \param[in] bin_index the index of the energy map to return (== the quantization bin).
143  */
144  inline unsigned char *
145  operator() (const std::size_t bin_index)
146  {
147  return (maps_[bin_index]);
148  }
149 
150  /** \brief Operator for accessing a specific element in the set of energy maps.
151  * \param[in] bin_index the quantization bin (states which of the energy maps to access).
152  * \param[in] col_index the column index within the specified energy map.
153  * \param[in] row_index the row index within the specified energy map.
154  */
155  inline const unsigned char &
156  operator() (const std::size_t bin_index, const std::size_t col_index, const std::size_t row_index) const
157  {
158  return (maps_[bin_index][row_index*width_ + col_index]);
159  }
160 
161  /** \brief Operator for accessing a specific element in the set of energy maps.
162  * \param[in] bin_index the quantization bin (states which of the energy maps to access).
163  * \param[in] index the element index within the specified energy map.
164  */
165  inline const unsigned char &
166  operator() (const std::size_t bin_index, const std::size_t index) const
167  {
168  return (maps_[bin_index][index]);
169  }
170 
171  /** \brief Returns a pointer to the data of the specified energy map.
172  * \param[in] bin_index the index of the energy map to return (== the quantization bin).
173  */
174  inline const unsigned char *
175  operator() (const std::size_t bin_index) const
176  {
177  return (maps_[bin_index]);
178  }
179 
180  private:
181  /** \brief The width of the energy maps. */
182  std::size_t width_{0};
183  /** \brief The height of the energy maps. */
184  std::size_t height_{0};
185  /** \brief The number of quantization bins (== the number of internally stored energy maps). */
186  std::size_t nr_bins_{0};
187  /** \brief Storage for the energy maps. */
188  std::vector<unsigned char*> maps_;
189  };
190 
191  /** \brief Stores a set of linearized maps.
192  * \author Stefan Holzer
193  */
195  {
196  public:
197  /** \brief Constructor. */
198  LinearizedMaps () = default;
199 
200  /** \brief Destructor. */
201  virtual ~LinearizedMaps () = default;
202 
203  /** \brief Returns the width of the linearized map. */
204  inline std::size_t
205  getWidth () const { return (width_); }
206 
207  /** \brief Returns the height of the linearized map. */
208  inline std::size_t
209  getHeight () const { return (height_); }
210 
211  /** \brief Returns the step-size used to construct the linearized map. */
212  inline std::size_t
213  getStepSize () const { return (step_size_); }
214 
215  /** \brief Returns the size of the memory map. */
216  inline std::size_t
217  getMapMemorySize () const { return (mem_width_ * mem_height_); }
218 
219  /** \brief Initializes the linearized map.
220  * \param[in] width the width of the source map.
221  * \param[in] height the height of the source map.
222  * \param[in] step_size the step-size used to sample the source map.
223  */
224  void
225  initialize (const std::size_t width, const std::size_t height, const std::size_t step_size)
226  {
227  maps_.resize(step_size*step_size, nullptr);
228  width_ = width;
229  height_ = height;
230  mem_width_ = width / step_size;
231  mem_height_ = height / step_size;
232  step_size_ = step_size;
233 
234  const std::size_t mapsSize = mem_width_ * mem_height_;
235 
236  for (auto &map : maps_)
237  {
238  //maps_[map_index] = new unsigned char[2*mapsSize];
239  map = reinterpret_cast<unsigned char*> (aligned_malloc (2*mapsSize));
240  std::fill_n(map, 2*mapsSize, 0);
241  }
242  }
243 
244  /** \brief Releases the internal memory. */
245  void
247  {
248  for (auto &map : maps_)
249  //if (maps_[map_index] != NULL) delete[] maps_[map_index];
250  if (map != nullptr) aligned_free (map);
251 
252  maps_.clear ();
253  width_ = 0;
254  height_ = 0;
255  mem_width_ = 0;
256  mem_height_ = 0;
257  step_size_ = 0;
258  }
259 
260  /** \brief Operator to access elements of the linearized map by column and row index.
261  * \param[in] col_index the column index.
262  * \param[in] row_index the row index.
263  */
264  inline unsigned char *
265  operator() (const std::size_t col_index, const std::size_t row_index)
266  {
267  return (maps_[row_index*step_size_ + col_index]);
268  }
269 
270  /** \brief Returns a linearized map starting at the specified position.
271  * \param[in] col_index the column index at which the returned map starts.
272  * \param[in] row_index the row index at which the returned map starts.
273  */
274  inline unsigned char *
275  getOffsetMap (const std::size_t col_index, const std::size_t row_index)
276  {
277  const std::size_t map_col = col_index % step_size_;
278  const std::size_t map_row = row_index % step_size_;
279 
280  const std::size_t map_mem_col_index = col_index / step_size_;
281  const std::size_t map_mem_row_index = row_index / step_size_;
282 
283  return (maps_[map_row*step_size_ + map_col] + map_mem_row_index*mem_width_ + map_mem_col_index);
284  }
285 
286  private:
287  /** \brief the original width of the data represented by the map. */
288  std::size_t width_{0};
289  /** \brief the original height of the data represented by the map. */
290  std::size_t height_{0};
291  /** \brief the actual width of the linearized map. */
292  std::size_t mem_width_{0};
293  /** \brief the actual height of the linearized map. */
294  std::size_t mem_height_{0};
295  /** \brief the step-size used for sampling the original data. */
296  std::size_t step_size_{0};
297  /** \brief a vector containing all the linearized maps. */
298  std::vector<unsigned char*> maps_;
299  };
300 
301  /** \brief Represents a detection of a template using the LINEMOD approach.
302  * \author Stefan Holzer
303  */
305  {
306  /** \brief Constructor. */
307  LINEMODDetection () = default;
308 
309  /** \brief x-position of the detection. */
310  int x{0};
311  /** \brief y-position of the detection. */
312  int y{0};
313  /** \brief ID of the detected template. */
314  int template_id{0};
315  /** \brief score of the detection. */
316  float score{0.0f};
317  /** \brief scale at which the template was detected. */
318  float scale{1.0f};
319  };
320 
321  /**
322  * \brief Template matching using the LINEMOD approach.
323  * \author Stefan Holzer, Stefan Hinterstoisser
324  * \ingroup recognition
325  */
327  {
328  public:
329  /** \brief Constructor */
331 
332  /** \brief Destructor */
333  virtual ~LINEMOD ();
334 
335  /** \brief Creates a template from the specified data and adds it to the matching queue.
336  * \param[in] modalities the modalities used to create the template.
337  * \param[in] masks the masks that determine which parts of the modalities are used for creating the template.
338  * \param[in] region the region which will be associated with the template (can be larger than the actual modality-maps).
339  */
340  int
341  createAndAddTemplate (const std::vector<QuantizableModality*> & modalities,
342  const std::vector<MaskMap*> & masks,
343  const RegionXY & region);
344 
345  /** \brief Adds the specified template to the matching queue.
346  * \param[in] linemod_template the template to add.
347  */
348  int
349  addTemplate (const SparseQuantizedMultiModTemplate & linemod_template);
350 
351  /** \brief Detects the stored templates in the supplied modality data.
352  * \param[in] modalities the modalities that will be used for detection.
353  * \param[out] detections the destination for the detections.
354  */
355  void
356  detectTemplates (const std::vector<QuantizableModality*> & modalities,
357  std::vector<LINEMODDetection> & detections) const;
358 
359  /** \brief Detects the stored templates in a semi scale invariant manner
360  * by applying the detection to multiple scaled versions of the input data.
361  * \param[in] modalities the modalities that will be used for detection.
362  * \param[out] detections the destination for the detections.
363  * \param[in] min_scale the minimum scale.
364  * \param[in] max_scale the maximum scale.
365  * \param[in] scale_multiplier the multiplier for getting from one scale to the next.
366  */
367  void
368  detectTemplatesSemiScaleInvariant (const std::vector<QuantizableModality*> & modalities,
369  std::vector<LINEMODDetection> & detections,
370  float min_scale = 0.6944444f,
371  float max_scale = 1.44f,
372  float scale_multiplier = 1.2f) const;
373 
374  /** \brief Matches the stored templates to the supplied modality data.
375  * \param[in] modalities the modalities that will be used for matching.
376  * \param[out] matches the found matches.
377  */
378  void
379  matchTemplates (const std::vector<QuantizableModality*> & modalities,
380  std::vector<LINEMODDetection> & matches) const;
381 
382  /** \brief Sets the detection threshold.
383  * \param[in] threshold the detection threshold.
384  */
385  inline void
386  setDetectionThreshold (float threshold)
387  {
388  template_threshold_ = threshold;
389  }
390 
391  /** \brief Enables/disables non-maximum suppression.
392  * \param[in] use_non_max_suppression determines whether to use non-maximum suppression or not.
393  */
394  inline void
395  setNonMaxSuppression (bool use_non_max_suppression)
396  {
397  use_non_max_suppression_ = use_non_max_suppression;
398  }
399 
400  /** \brief Enables/disables averaging of close detections.
401  * \param[in] average_detections determines whether to average close detections or not.
402  */
403  inline void
404  setDetectionAveraging (bool average_detections)
405  {
406  average_detections_ = average_detections;
407  }
408 
409  /** \brief Returns the template with the specified ID.
410  * \param[in] template_id the ID of the template to return.
411  */
412  inline const SparseQuantizedMultiModTemplate &
413  getTemplate (int template_id) const
414  {
415  return (templates_[template_id]);
416  }
417 
418  /** \brief Returns the number of stored/trained templates. */
419  inline std::size_t
421  {
422  return (templates_.size ());
423  }
424 
425  /** \brief Saves the stored templates to the specified file.
426  * \param[in] file_name the name of the file to save the templates to.
427  */
428  void
429  saveTemplates (const char * file_name) const;
430 
431  /** \brief Loads templates from the specified file.
432  * \param[in] file_name the name of the file to load the template from.
433  */
434  void
435  loadTemplates (const char * file_name);
436 
437  /** \brief Loads templates from the specified files.
438  * \param[in] file_names vector of files to load the templates from.
439  */
440 
441  void
442  loadTemplates (std::vector<std::string> & file_names);
443 
444  /** \brief Serializes the stored templates to the specified stream.
445  * \param[in] stream the stream the templates will be written to.
446  */
447  void
448  serialize (std::ostream & stream) const;
449 
450  /** \brief Deserializes templates from the specified stream.
451  * \param[in] stream the stream the templates will be read from.
452  */
453  void
454  deserialize (std::istream & stream);
455 
456 
457  private:
458  /** template response threshold */
459  float template_threshold_{0.75f};
460  /** states whether non-max-suppression on detections is enabled or not */
461  bool use_non_max_suppression_{false};
462  /** states whether to return an averaged detection */
463  bool average_detections_{false};
464  /** template storage */
465  std::vector<SparseQuantizedMultiModTemplate> templates_{};
466  };
467 
468 }
Stores a set of energy maps.
Definition: linemod.h:55
std::size_t getNumOfBins() const
Returns the number of bins used for quantization (which is equal to the number of energy maps).
Definition: linemod.h:78
virtual ~EnergyMaps()=default
Destructor.
EnergyMaps()=default
Constructor.
void releaseAll()
Releases the internal data.
Definition: linemod.h:108
void initialize(const std::size_t width, const std::size_t height, const std::size_t nr_bins)
Initializes the set of energy maps.
Definition: linemod.h:89
std::size_t getWidth() const
Returns the width of the energy maps.
Definition: linemod.h:64
std::size_t getHeight() const
Returns the height of the energy maps.
Definition: linemod.h:71
Template matching using the LINEMOD approach.
Definition: linemod.h:327
void deserialize(std::istream &stream)
Deserializes templates from the specified stream.
void saveTemplates(const char *file_name) const
Saves the stored templates to the specified file.
void detectTemplatesSemiScaleInvariant(const std::vector< QuantizableModality * > &modalities, std::vector< LINEMODDetection > &detections, float min_scale=0.6944444f, float max_scale=1.44f, float scale_multiplier=1.2f) const
Detects the stored templates in a semi scale invariant manner by applying the detection to multiple s...
const SparseQuantizedMultiModTemplate & getTemplate(int template_id) const
Returns the template with the specified ID.
Definition: linemod.h:413
void matchTemplates(const std::vector< QuantizableModality * > &modalities, std::vector< LINEMODDetection > &matches) const
Matches the stored templates to the supplied modality data.
std::size_t getNumOfTemplates() const
Returns the number of stored/trained templates.
Definition: linemod.h:420
void setDetectionThreshold(float threshold)
Sets the detection threshold.
Definition: linemod.h:386
void setDetectionAveraging(bool average_detections)
Enables/disables averaging of close detections.
Definition: linemod.h:404
virtual ~LINEMOD()
Destructor.
void serialize(std::ostream &stream) const
Serializes the stored templates to the specified stream.
void detectTemplates(const std::vector< QuantizableModality * > &modalities, std::vector< LINEMODDetection > &detections) const
Detects the stored templates in the supplied modality data.
LINEMOD()
Constructor.
void loadTemplates(std::vector< std::string > &file_names)
Loads templates from the specified files.
void setNonMaxSuppression(bool use_non_max_suppression)
Enables/disables non-maximum suppression.
Definition: linemod.h:395
int addTemplate(const SparseQuantizedMultiModTemplate &linemod_template)
Adds the specified template to the matching queue.
int createAndAddTemplate(const std::vector< QuantizableModality * > &modalities, const std::vector< MaskMap * > &masks, const RegionXY &region)
Creates a template from the specified data and adds it to the matching queue.
void loadTemplates(const char *file_name)
Loads templates from the specified file.
Stores a set of linearized maps.
Definition: linemod.h:195
std::size_t getHeight() const
Returns the height of the linearized map.
Definition: linemod.h:209
void initialize(const std::size_t width, const std::size_t height, const std::size_t step_size)
Initializes the linearized map.
Definition: linemod.h:225
LinearizedMaps()=default
Constructor.
virtual ~LinearizedMaps()=default
Destructor.
unsigned char * getOffsetMap(const std::size_t col_index, const std::size_t row_index)
Returns a linearized map starting at the specified position.
Definition: linemod.h:275
void releaseAll()
Releases the internal memory.
Definition: linemod.h:246
std::size_t getStepSize() const
Returns the step-size used to construct the linearized map.
Definition: linemod.h:213
std::size_t getWidth() const
Returns the width of the linearized map.
Definition: linemod.h:205
std::size_t getMapMemorySize() const
Returns the size of the memory map.
Definition: linemod.h:217
void aligned_free(void *ptr)
Definition: pcl_macros.h:404
void * aligned_malloc(std::size_t size)
Definition: pcl_macros.h:382
Defines all the PCL and non-PCL macros used.
#define PCL_EXPORTS
Definition: pcl_macros.h:323
Represents a detection of a template using the LINEMOD approach.
Definition: linemod.h:305
LINEMODDetection()=default
Constructor.
Defines a region in XY-space.
Definition: region_xy.h:82
A multi-modality template constructed from a set of quantized multi-modality features.