Point Cloud Library (PCL)  1.12.1-dev
multi_channel_2d_comparison_feature_handler.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 <pcl/common/common.h>
41 #include <pcl/ml/feature_handler.h>
42 #include <pcl/ml/multi_channel_2d_comparison_feature.h>
43 #include <pcl/ml/multi_channel_2d_data_set.h>
44 #include <pcl/ml/multiple_data_2d_example_index.h>
45 #include <pcl/ml/point_xy_32f.h>
46 #include <pcl/ml/point_xy_32i.h>
47 
48 #include <istream>
49 #include <ostream>
50 
51 namespace pcl {
52 
53 /** Feature utility class that handles the creation and evaluation of RGBD
54  * comparison features. */
55 template <class DATA_TYPE, std::size_t NUM_OF_CHANNELS>
57 : public pcl::FeatureHandler<pcl::MultiChannel2DComparisonFeature<pcl::PointXY32i>,
58  pcl::MultiChannel2DDataSet<DATA_TYPE, NUM_OF_CHANNELS>,
59  pcl::MultipleData2DExampleIndex> {
60 
61 public:
62  /** Constructor. */
63  MultiChannel2DComparisonFeatureHandler(const int feature_window_width,
64  const int feature_window_height)
65  : feature_window_width_(feature_window_width)
66  , feature_window_height_(feature_window_height)
67  {}
68 
69  /** Sets the feature window size.
70  *
71  * \param[in] width the width of the feature window
72  * \param[in] height the height of the feature window
73  */
74  inline void
75  setFeatureWindowSize(int width, int height)
76  {
77  feature_window_width_ = width;
78  feature_window_height_ = height;
79  }
80 
81  /** Creates random features.
82  *
83  * \param[in] num_of_features the number of random features to create
84  * \param[out] features the destination for the created random features
85  */
86  inline void
88  const std::size_t num_of_features,
89  std::vector<MultiChannel2DComparisonFeature<PointXY32i>>& features)
90  {
91  features.resize(num_of_features);
92  for (std::size_t feature_index = 0; feature_index < num_of_features;
93  ++feature_index) {
94  features[feature_index].p1 = PointXY32i::randomPoint(-feature_window_width_ / 2,
95  feature_window_width_ / 2,
96  -feature_window_height_ / 2,
97  feature_window_height_ / 2);
98  features[feature_index].p2 = PointXY32i::randomPoint(-feature_window_width_ / 2,
99  feature_window_width_ / 2,
100  -feature_window_height_ / 2,
101  feature_window_height_ / 2);
102  features[feature_index].channel = static_cast<unsigned char>(
103  NUM_OF_CHANNELS * (static_cast<float>(rand()) / (RAND_MAX + 1)));
104  }
105  }
106 
107  /** Evaluates a feature for a set of examples on the specified data set.
108  *
109  * \param[in] feature the feature to evaluate
110  * \param[in] data_set the data set the feature is evaluated on
111  * \param[in] examples the examples the feature is evaluated for
112  * \param[out] results the destination for the evaluation results
113  * \param[out] flags the destination for the flags corresponding to the evaluation
114  * results
115  */
116  inline void
119  std::vector<MultipleData2DExampleIndex>& examples,
120  std::vector<float>& results,
121  std::vector<unsigned char>& flags) const
122  {
123  results.resize(examples.size());
124  flags.resize(examples.size());
125  for (int example_index = 0; example_index < examples.size(); ++example_index) {
126  const MultipleData2DExampleIndex& example = examples[example_index];
127 
128  evaluateFeature(
129  feature, data_set, example, results[example_index], flags[example_index]);
130  }
131  }
132 
133  /** Evaluates a feature for one examples on the specified data set.
134  *
135  * \param[in] feature the feature to evaluate
136  * \param[in] data_set the data set the feature is evaluated on
137  * \param[in] example the example the feature is evaluated for
138  * \param[out] result the destination for the evaluation result
139  * \param[out] flag the destination for the flag corresponding to the evaluation
140  * result
141  */
142  inline void
145  const MultipleData2DExampleIndex& example,
146  float& result,
147  unsigned char& flag) const
148  {
149  const int center_col_index = example.x;
150  const int center_row_index = example.y;
151 
152  const std::size_t p1_col =
153  static_cast<std::size_t>(feature.p1.x + center_col_index);
154  const std::size_t p1_row =
155  static_cast<std::size_t>(feature.p1.y + center_row_index);
156 
157  const std::size_t p2_col =
158  static_cast<std::size_t>(feature.p2.x + center_col_index);
159  const std::size_t p2_row =
160  static_cast<std::size_t>(feature.p2.y + center_row_index);
161 
162  const unsigned char channel = feature.channel;
163 
164  const float value1 =
165  static_cast<float>(data_set(example.data_set_id, p1_col, p1_row)[channel]);
166  const float value2 =
167  static_cast<float>(data_set(example.data_set_id, p2_col, p2_row)[channel]);
168 
169  result = value1 - value2;
170  flag = (std::isfinite(value1) && std::isfinite(value2)) ? 0 : 1;
171  }
172 
173  /** Generates code for feature evaluation.
174  *
175  * \param[in] feature the feature for which code is generated
176  * \param[out] stream the destination for the generated code
177  */
178  void
180  std::ostream& stream) const
181  {
182  stream << "ERROR: RegressionVarianceStatsEstimator does not implement "
183  "generateCodeForBranchIndex(...)";
184  // stream << "const float value = ( (*dataSet)(dataSetId, centerY+" << feature.p1.y
185  // << ", centerX+" << feature.p1.x << ")[" << static_cast<int>(feature.colorChannel)
186  // << "]"
187  // << " - " << "(*dataSet)(dataSetId, centerY+" << feature.p2.y << ", centerX+" <<
188  // feature.p2.x << ")[" << static_cast<int>(feature.colorChannel) << "] );" <<
189  // ::std::endl;
190  }
191 
192 private:
193  /** The width of the feature window. */
194  int feature_window_width_;
195  /** The height of the feature window. */
196  int feature_window_height_;
197 };
198 
199 /** Feature utility class that handles the creation and evaluation of RGBD
200  * comparison features. */
201 template <class DATA_TYPE,
202  std::size_t NUM_OF_CHANNELS,
203  std::size_t SCALE_CHANNEL,
204  bool INVERT_SCALE>
206 : public pcl::FeatureHandler<pcl::MultiChannel2DComparisonFeature<pcl::PointXY32f>,
207  pcl::MultiChannel2DDataSet<DATA_TYPE, NUM_OF_CHANNELS>,
208  pcl::MultipleData2DExampleIndex> {
209 
210 public:
211  /** Constructor. */
212  ScaledMultiChannel2DComparisonFeatureHandler(const int feature_window_width,
213  const int feature_window_height)
214  : feature_window_width_(feature_window_width)
215  , feature_window_height_(feature_window_height)
216  {}
217 
218  /** Sets the feature window size.
219  *
220  * \param[in] width the width of the feature window
221  * \param[in] height the height of the feature window
222  */
223  inline void
224  setFeatureWindowSize(int width, int height)
225  {
226  feature_window_width_ = width;
227  feature_window_height_ = height;
228  }
229 
230  /** Creates random features.
231  *
232  * \param[in] num_of_features the number of random features to create
233  * \param[out] features the destination for the created random features
234  */
235  inline void
237  const std::size_t num_of_features,
238  std::vector<MultiChannel2DComparisonFeature<PointXY32f>>& features)
239  {
240  features.resize(num_of_features);
241  for (std::size_t feature_index = 0; feature_index < num_of_features;
242  ++feature_index) {
243  features[feature_index].p1 = PointXY32f::randomPoint(-feature_window_width_ / 2,
244  feature_window_width_ / 2,
245  -feature_window_height_ / 2,
246  feature_window_height_ / 2);
247  features[feature_index].p2 = PointXY32f::randomPoint(-feature_window_width_ / 2,
248  feature_window_width_ / 2,
249  -feature_window_height_ / 2,
250  feature_window_height_ / 2);
251  features[feature_index].channel = static_cast<unsigned char>(
252  NUM_OF_CHANNELS * (static_cast<float>(rand()) / (RAND_MAX + 1)));
253  }
254  }
255 
256  /** Evaluates a feature for a set of examples on the specified data set.
257  *
258  * \param[in] feature the feature to evaluate
259  * \param[in] data_set the data set the feature is evaluated on
260  * \param[in] examples the examples the feature is evaluated for
261  * \param[out] results the destination for the evaluation results
262  * \param[out] flags the destination for the flags corresponding to the evaluation
263  * results
264  */
265  inline void
268  std::vector<MultipleData2DExampleIndex>& examples,
269  std::vector<float>& results,
270  std::vector<unsigned char>& flags) const
271  {
272  results.resize(examples.size());
273  flags.resize(examples.size());
274  for (int example_index = 0; example_index < examples.size(); ++example_index) {
275  const MultipleData2DExampleIndex& example = examples[example_index];
276 
277  evaluateFeature(
278  feature, data_set, example, results[example_index], flags[example_index]);
279  }
280  }
281 
282  /** Evaluates a feature for one examples on the specified data set.
283  *
284  * \param[in] feature the feature to evaluate
285  * \param[in] data_set the data set the feature is evaluated on
286  * \param[in] example the example the feature is evaluated for
287  * \param[out] result the destination for the evaluation result
288  * \param[out] flag the destination for the flag corresponding to the evaluation
289  * result
290  */
291  inline void
294  const MultipleData2DExampleIndex& example,
295  float& result,
296  unsigned char& flag) const
297  {
298  const int center_col_index = example.x;
299  const int center_row_index = example.y;
300 
301  float scale;
302  if (INVERT_SCALE)
303  scale = 1.0f / static_cast<float>(data_set(example.data_set_id,
304  center_col_index,
305  center_row_index)[SCALE_CHANNEL]);
306  else
307  scale = static_cast<float>(data_set(
308  example.data_set_id, center_col_index, center_row_index)[SCALE_CHANNEL]);
309 
310  const std::size_t p1_col =
311  static_cast<std::size_t>(scale * feature.p1.x + center_col_index);
312  const std::size_t p1_row =
313  static_cast<std::size_t>(scale * feature.p1.y + center_row_index);
314 
315  const std::size_t p2_col =
316  static_cast<std::size_t>(scale * feature.p2.x + center_col_index);
317  const std::size_t p2_row =
318  static_cast<std::size_t>(scale * feature.p2.y + center_row_index);
319 
320  const unsigned char channel = feature.channel;
321 
322  const float value1 =
323  static_cast<float>(data_set(example.data_set_id, p1_col, p1_row)[channel]);
324  const float value2 =
325  static_cast<float>(data_set(example.data_set_id, p2_col, p2_row)[channel]);
326 
327  result = value1 - value2;
328  flag = (std::isfinite(value1) && std::isfinite(value2)) ? 0 : 1;
329  }
330 
331  /** Generates code for feature evaluation.
332  *
333  * \param[in] feature the feature for which code is generated
334  * \param[out] stream the destination for the generated code
335  */
336  void
338  std::ostream& stream) const
339  {
340  stream << "ERROR: ScaledMultiChannel2DComparisonFeatureHandler does not implement "
341  "generateCodeForBranchIndex(...)"
342  << std::endl;
343 
344  // pcl::PointXY32f p1 = feature.p1;
345  // pcl::PointXY32f p2 = feature.p2;
346 
347  // stream << "const float eval_value = data_ptr + " << p1.x << " + " << p1.y << " *
348  // width;
349 
350  // stream << "const float value = ( (*dataSet)(dataSetId, centerY+" << feature.p1.y
351  // << ", centerX+" << feature.p1.x << ")[" << static_cast<int>(feature.colorChannel)
352  // << "]"
353  // << " - " << "(*dataSet)(dataSetId, centerY+" << feature.p2.y << ", centerX+" <<
354  // feature.p2.x << ")[" << static_cast<int>(feature.colorChannel) << "] );" <<
355  // ::std::endl;
356  }
357 
358 private:
359  /** The width of the feature window. */
360  int feature_window_width_;
361  /** The height of the feature window. */
362  int feature_window_height_;
363 };
364 
365 template <class DATA_TYPE,
366  std::size_t NUM_OF_CHANNELS,
367  std::size_t SCALE_CHANNEL,
368  bool INVERT_SCALE>
370 : public pcl::FeatureHandlerCodeGenerator<
371  pcl::MultiChannel2DComparisonFeature<pcl::PointXY32f>,
372  pcl::MultiChannel2DDataSet<DATA_TYPE, NUM_OF_CHANNELS>,
373  pcl::MultipleData2DExampleIndex> {
374 public:
376 
377  void
378  generateEvalFunctionCode(std::ostream& stream) const;
379 
380  void
381  generateEvalCode(const MultiChannel2DComparisonFeature<PointXY32f>& feature,
382  std::ostream& stream) const;
383 };
384 
385 template <class DATA_TYPE,
386  std::size_t NUM_OF_CHANNELS,
387  std::size_t SCALE_CHANNEL,
388  bool INVERT_SCALE>
389 void
390 ScaledMultiChannel2DComparisonFeatureHandlerCCodeGenerator<
391  DATA_TYPE,
392  NUM_OF_CHANNELS,
393  SCALE_CHANNEL,
394  INVERT_SCALE>::generateEvalFunctionCode(std::ostream& stream) const
395 {
396  if (NUM_OF_CHANNELS == 1 && SCALE_CHANNEL == 0 && INVERT_SCALE) {
397  stream << "const float scale = 1.0f / static_cast<float> (*data_ptr);"
398  << std::endl;
399  stream << "" << std::endl;
400  stream << "struct LocalFeatureHandler" << std::endl;
401  stream << "{" << std::endl;
402  stream << " static inline void eval (" << typeid(DATA_TYPE).name()
403  << " * a_ptr, const float a_x1, const float a_y1, const float a_x2, const "
404  "float a_y2, const float a_scale, const int a_width, float & a_result, "
405  "unsigned char & a_flags)"
406  << std::endl;
407  stream << " {" << std::endl;
408  stream << " a_result = *(a_ptr + static_cast<int> (a_scale*a_x1) + "
409  "(static_cast<int> (a_scale*a_y1)*a_width)) - *(a_ptr + static_cast<int> "
410  "(a_scale*a_x2) + (static_cast<int> (a_scale*a_y2)*a_width));"
411  << std::endl;
412  stream << " }" << std::endl;
413  stream << "};" << std::endl;
414  }
415  else {
416  stream << "ERROR: generateEvalFunctionCode not implemented" << std::endl;
417  }
418 }
419 
420 template <class DATA_TYPE,
421  std::size_t NUM_OF_CHANNELS,
422  std::size_t SCALE_CHANNEL,
423  bool INVERT_SCALE>
424 void
426  NUM_OF_CHANNELS,
427  SCALE_CHANNEL,
428  INVERT_SCALE>::
429  generateEvalCode(const MultiChannel2DComparisonFeature<PointXY32f>& feature,
430  std::ostream& stream) const
431 {
432  stream << "LocalFeatureHandler::eval (data_ptr, " << feature.p1.x << ", "
433  << feature.p1.y << ", " << feature.p2.x << ", " << feature.p2.y << ", "
434  << "scale, width, result, flags);" << std::endl;
435 }
436 
443 
450 
453 
454 } // namespace pcl
Utility class interface which is used for creating and evaluating features.
Feature utility class that handles the creation and evaluation of RGBD comparison features.
void evaluateFeature(const MultiChannel2DComparisonFeature< PointXY32i > &feature, MultiChannel2DDataSet< DATA_TYPE, NUM_OF_CHANNELS > &data_set, std::vector< MultipleData2DExampleIndex > &examples, std::vector< float > &results, std::vector< unsigned char > &flags) const
Evaluates a feature for a set of examples on the specified data set.
void setFeatureWindowSize(int width, int height)
Sets the feature window size.
void createRandomFeatures(const std::size_t num_of_features, std::vector< MultiChannel2DComparisonFeature< PointXY32i >> &features)
Creates random features.
void evaluateFeature(const MultiChannel2DComparisonFeature< PointXY32i > &feature, MultiChannel2DDataSet< DATA_TYPE, NUM_OF_CHANNELS > &data_set, const MultipleData2DExampleIndex &example, float &result, unsigned char &flag) const
Evaluates a feature for one examples on the specified data set.
MultiChannel2DComparisonFeatureHandler(const int feature_window_width, const int feature_window_height)
Constructor.
void generateCodeForEvaluation(const MultiChannel2DComparisonFeature< PointXY32i > &feature, std::ostream &stream) const
Generates code for feature evaluation.
Feature for comparing two sample points in 2D multi-channel data.
unsigned char channel
Specifies which channel is used for comparison.
Holds a set of two-dimensional multi-channel data.
static PointXY32f randomPoint(const int min_x, const int max_x, const int min_y, const int max_y)
Creates a random point within the specified window.
static PointXY32i randomPoint(const int min_x, const int max_x, const int min_y, const int max_y)
Creates a random point within the specified window.
Feature utility class that handles the creation and evaluation of RGBD comparison features.
void evaluateFeature(const MultiChannel2DComparisonFeature< PointXY32f > &feature, MultiChannel2DDataSet< DATA_TYPE, NUM_OF_CHANNELS > &data_set, std::vector< MultipleData2DExampleIndex > &examples, std::vector< float > &results, std::vector< unsigned char > &flags) const
Evaluates a feature for a set of examples on the specified data set.
void evaluateFeature(const MultiChannel2DComparisonFeature< PointXY32f > &feature, MultiChannel2DDataSet< DATA_TYPE, NUM_OF_CHANNELS > &data_set, const MultipleData2DExampleIndex &example, float &result, unsigned char &flag) const
Evaluates a feature for one examples on the specified data set.
void generateCodeForEvaluation(const MultiChannel2DComparisonFeature< PointXY32f > &feature, std::ostream &stream) const
Generates code for feature evaluation.
void createRandomFeatures(const std::size_t num_of_features, std::vector< MultiChannel2DComparisonFeature< PointXY32f >> &features)
Creates random features.
void setFeatureWindowSize(int width, int height)
Sets the feature window size.
ScaledMultiChannel2DComparisonFeatureHandler(const int feature_window_width, const int feature_window_height)
Constructor.
Define standard C methods and C++ classes that are common to all methods.
#define PCL_EXPORTS
Definition: pcl_macros.h:323
Example index for a set of 2D data blocks.