Point Cloud Library (PCL)  1.8.0
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 #ifndef PCL_ML_MULTI_CHANNEL_2D_COMPARISON_FEATURE_HANDLER_H_
39 #define PCL_ML_MULTI_CHANNEL_2D_COMPARISON_FEATURE_HANDLER_H_
40 
41 #include <pcl/common/common.h>
42 
43 #include <pcl/ml/feature_handler.h>
44 #include <pcl/ml/multi_channel_2d_data_set.h>
45 #include <pcl/ml/multi_channel_2d_comparison_feature.h>
46 #include <pcl/ml/multiple_data_2d_example_index.h>
47 #include <pcl/ml/point_xy_32i.h>
48 #include <pcl/ml/point_xy_32f.h>
49 
50 #include <istream>
51 #include <ostream>
52 
53 namespace pcl
54 {
55 
56  /** \brief Feature utility class that handles the creation and evaluation of RGBD comparison features. */
57  template <class DATA_TYPE, size_t NUM_OF_CHANNELS>
59  : public pcl::FeatureHandler<pcl::MultiChannel2DComparisonFeature<pcl::PointXY32i>, pcl::MultiChannel2DDataSet<DATA_TYPE, NUM_OF_CHANNELS>, pcl::MultipleData2DExampleIndex>
60  {
61 
62  public:
63 
64  /** \brief Constructor. */
66  const int feature_window_width,
67  const int feature_window_height)
68  : feature_window_width_ (feature_window_width), feature_window_height_ (feature_window_height)
69  {}
70  /** \brief Destructor. */
72 
73  /** \brief Sets the feature window size.
74  * \param[in] width The width of the feature window.
75  * \param[in] height The height of the feature window.
76  */
77  inline void
79  int width,
80  int height)
81  {
82  feature_window_width_ = width;
83  feature_window_height_ = height;
84  }
85 
86  /** \brief Creates random features.
87  * \param[in] num_of_features The number of random features to create.
88  * \param[out] features The destination for the created random features.
89  */
90  inline void
92  const size_t num_of_features,
93  std::vector<MultiChannel2DComparisonFeature<PointXY32i> > & features)
94  {
95  features.resize (num_of_features);
96  for (size_t feature_index = 0; feature_index < num_of_features; ++feature_index)
97  {
98  features[feature_index].p1 = PointXY32i::randomPoint(-feature_window_width_/2, feature_window_width_/2, -feature_window_height_/2, feature_window_height_/2);
99  features[feature_index].p2 = PointXY32i::randomPoint(-feature_window_width_/2, feature_window_width_/2, -feature_window_height_/2, feature_window_height_/2);
100  features[feature_index].channel = static_cast<unsigned char>(NUM_OF_CHANNELS*(static_cast<float>(rand()) / (RAND_MAX+1)));
101  }
102  }
103 
104  /** \brief Evaluates a feature for a set of examples on the specified data set.
105  * \param[in] feature The feature to evaluate.
106  * \param[in] data_set The data set the feature is evaluated on.
107  * \param[in] examples The examples the feature is evaluated for.
108  * \param[out] results The destination for the evaluation results.
109  * \param[out] flags The destination for the flags corresponding to the evaluation results.
110  */
111  inline void
115  std::vector<MultipleData2DExampleIndex> & examples,
116  std::vector<float> & results,
117  std::vector<unsigned char> & flags) const
118  {
119  results.resize (examples.size ());
120  flags.resize (examples.size ());
121  for (int example_index = 0; example_index < examples.size (); ++example_index)
122  {
123  const MultipleData2DExampleIndex & example = examples[example_index];
124 
125  evaluateFeature (feature, data_set, example, results[example_index], flags[example_index]);
126  }
127  }
128 
129  /** \brief Evaluates a feature for one examples on the specified data set.
130  * \param[in] feature The feature to evaluate.
131  * \param[in] data_set The data set the feature is evaluated on.
132  * \param[in] example The example the feature is evaluated for.
133  * \param[out] result The destination for the evaluation result.
134  * \param[out] flag The destination for the flag corresponding to the evaluation result.
135  */
136  inline void
140  const MultipleData2DExampleIndex & example,
141  float & result,
142  unsigned char & flag) const
143  {
144  const int center_col_index = example.x;
145  const int center_row_index = example.y;
146 
147  const size_t p1_col = static_cast<size_t> (feature.p1.x + center_col_index);
148  const size_t p1_row = static_cast<size_t> (feature.p1.y + center_row_index);
149 
150  const size_t p2_col = static_cast<size_t> (feature.p2.x + center_col_index);
151  const size_t p2_row = static_cast<size_t> (feature.p2.y + center_row_index);
152 
153  const unsigned char channel = feature.channel;
154 
155  const float value1 = static_cast<float> (data_set (example.data_set_id, p1_col, p1_row)[channel]);
156  const float value2 = static_cast<float> (data_set (example.data_set_id, p2_col, p2_row)[channel]);
157 
158  result = value1 - value2;
159  flag = (pcl_isfinite (value1) && pcl_isfinite (value2)) ? 0 : 1;
160  }
161 
162  /** \brief Generates code for feature evaluation.
163  * \param[in] feature The feature for which code is generated.
164  * \param[out] stream The destination for the generated code.
165  */
166  void
169  std::ostream & stream) const
170  {
171  stream << "ERROR: RegressionVarianceStatsEstimator does not implement generateCodeForBranchIndex(...)";
172  //stream << "const float value = ( (*dataSet)(dataSetId, centerY+" << feature.p1.y << ", centerX+" << feature.p1.x << ")[" << static_cast<int>(feature.colorChannel) << "]"
173  // << " - " << "(*dataSet)(dataSetId, centerY+" << feature.p2.y << ", centerX+" << feature.p2.x << ")[" << static_cast<int>(feature.colorChannel) << "] );" << ::std::endl;
174  }
175 
176  private:
177  /** \brief The width of the feature window. */
178  int feature_window_width_;
179  /** \brief The height of the feature window. */
180  int feature_window_height_;
181 
182  };
183 
184 
185  /** \brief Feature utility class that handles the creation and evaluation of RGBD comparison features. */
186  template <class DATA_TYPE, size_t NUM_OF_CHANNELS, size_t SCALE_CHANNEL, bool INVERT_SCALE>
188  : public pcl::FeatureHandler<pcl::MultiChannel2DComparisonFeature<pcl::PointXY32f>, pcl::MultiChannel2DDataSet<DATA_TYPE, NUM_OF_CHANNELS>, pcl::MultipleData2DExampleIndex>
189  {
190 
191  public:
192 
193  /** \brief Constructor. */
195  const int feature_window_width,
196  const int feature_window_height)
197  : feature_window_width_ (feature_window_width), feature_window_height_ (feature_window_height)
198  {}
199  /** \brief Destructor. */
201 
202  /** \brief Sets the feature window size.
203  * \param[in] width The width of the feature window.
204  * \param[in] height The height of the feature window.
205  */
206  inline void
208  int width,
209  int height)
210  {
211  feature_window_width_ = width;
212  feature_window_height_ = height;
213  }
214 
215  /** \brief Creates random features.
216  * \param[in] num_of_features The number of random features to create.
217  * \param[out] features The destination for the created random features.
218  */
219  inline void
221  const size_t num_of_features,
222  std::vector<MultiChannel2DComparisonFeature<PointXY32f> > & features)
223  {
224  features.resize (num_of_features);
225  for (size_t feature_index = 0; feature_index < num_of_features; ++feature_index)
226  {
227  features[feature_index].p1 = PointXY32f::randomPoint(-feature_window_width_/2, feature_window_width_/2, -feature_window_height_/2, feature_window_height_/2);
228  features[feature_index].p2 = PointXY32f::randomPoint(-feature_window_width_/2, feature_window_width_/2, -feature_window_height_/2, feature_window_height_/2);
229  features[feature_index].channel = static_cast<unsigned char>(NUM_OF_CHANNELS*(static_cast<float>(rand()) / (RAND_MAX+1)));
230  }
231  }
232 
233  /** \brief Evaluates a feature for a set of examples on the specified data set.
234  * \param[in] feature The feature to evaluate.
235  * \param[in] data_set The data set the feature is evaluated on.
236  * \param[in] examples The examples the feature is evaluated for.
237  * \param[out] results The destination for the evaluation results.
238  * \param[out] flags The destination for the flags corresponding to the evaluation results.
239  */
240  inline void
244  std::vector<MultipleData2DExampleIndex> & examples,
245  std::vector<float> & results,
246  std::vector<unsigned char> & flags) const
247  {
248  results.resize (examples.size ());
249  flags.resize (examples.size ());
250  for (int example_index = 0; example_index < examples.size (); ++example_index)
251  {
252  const MultipleData2DExampleIndex & example = examples[example_index];
253 
254  evaluateFeature (feature, data_set, example, results[example_index], flags[example_index]);
255  }
256  }
257 
258  /** \brief Evaluates a feature for one examples on the specified data set.
259  * \param[in] feature The feature to evaluate.
260  * \param[in] data_set The data set the feature is evaluated on.
261  * \param[in] example The example the feature is evaluated for.
262  * \param[out] result The destination for the evaluation result.
263  * \param[out] flag The destination for the flag corresponding to the evaluation result.
264  */
265  inline void
269  const MultipleData2DExampleIndex & example,
270  float & result,
271  unsigned char & flag) const
272  {
273  const int center_col_index = example.x;
274  const int center_row_index = example.y;
275 
276  float scale;
277  if (INVERT_SCALE)
278  scale = 1.0f / static_cast<float> (data_set (example.data_set_id, center_col_index, center_row_index)[SCALE_CHANNEL]);
279  else
280  scale = static_cast<float> (data_set (example.data_set_id, center_col_index, center_row_index)[SCALE_CHANNEL]);
281 
282 
283 
284 
285  const size_t p1_col = static_cast<size_t> (scale * feature.p1.x + center_col_index);
286  const size_t p1_row = static_cast<size_t> (scale * feature.p1.y + center_row_index);
287 
288  const size_t p2_col = static_cast<size_t> (scale * feature.p2.x + center_col_index);
289  const size_t p2_row = static_cast<size_t> (scale * feature.p2.y + center_row_index);
290 
291  const unsigned char channel = feature.channel;
292 
293  const float value1 = static_cast<float> (data_set (example.data_set_id, p1_col, p1_row)[channel]);
294  const float value2 = static_cast<float> (data_set (example.data_set_id, p2_col, p2_row)[channel]);
295 
296  result = value1 - value2;
297  flag = (pcl_isfinite (value1) && pcl_isfinite (value2)) ? 0 : 1;
298  }
299 
300  /** \brief Generates code for feature evaluation.
301  * \param[in] feature The feature for which code is generated.
302  * \param[out] stream The destination for the generated code.
303  */
304  void
307  std::ostream & stream) const
308  {
309  stream << "ERROR: ScaledMultiChannel2DComparisonFeatureHandler does not implement generateCodeForBranchIndex(...)" << std::endl;
310 
311  //pcl::PointXY32f p1 = feature.p1;
312  //pcl::PointXY32f p2 = feature.p2;
313 
314  //stream << "const float eval_value = data_ptr + " << p1.x << " + " << p1.y << " * width;
315 
316  //stream << "const float value = ( (*dataSet)(dataSetId, centerY+" << feature.p1.y << ", centerX+" << feature.p1.x << ")[" << static_cast<int>(feature.colorChannel) << "]"
317  // << " - " << "(*dataSet)(dataSetId, centerY+" << feature.p2.y << ", centerX+" << feature.p2.x << ")[" << static_cast<int>(feature.colorChannel) << "] );" << ::std::endl;
318  }
319 
320  private:
321  /** \brief The width of the feature window. */
322  int feature_window_width_;
323  /** \brief The height of the feature window. */
324  int feature_window_height_;
325 
326  };
327 
328 
329  template <class DATA_TYPE, size_t NUM_OF_CHANNELS, size_t SCALE_CHANNEL, bool INVERT_SCALE>
331  : public pcl::FeatureHandlerCodeGenerator<pcl::MultiChannel2DComparisonFeature<pcl::PointXY32f>, pcl::MultiChannel2DDataSet<DATA_TYPE, NUM_OF_CHANNELS>, pcl::MultipleData2DExampleIndex>
332  {
333  public:
336 
337  void
338  generateEvalFunctionCode (
339  std::ostream & stream) const;
340 
341  void
342  generateEvalCode (
344  std::ostream & stream) const;
345  };
346 
347  template <class DATA_TYPE, size_t NUM_OF_CHANNELS, size_t SCALE_CHANNEL, bool INVERT_SCALE>
348  void
350  std::ostream & stream) const
351  {
352  if (NUM_OF_CHANNELS == 1 && SCALE_CHANNEL == 0 && INVERT_SCALE)
353  {
354  stream << "const float scale = 1.0f / static_cast<float> (*data_ptr);" << std::endl;
355  stream << "" << std::endl;
356  stream << "struct LocalFeatureHandler" << std::endl;
357  stream << "{" << std::endl;
358  stream << " static inline void eval (" << typeid (DATA_TYPE).name () << " * a_ptr, const float a_x1, const float a_y1, const float a_x2, const float a_y2, const float a_scale, const int a_width, float & a_result, unsigned char & a_flags)" << std::endl;
359  stream << " {" << std::endl;
360  stream << " a_result = *(a_ptr + static_cast<int> (a_scale*a_x1) + (static_cast<int> (a_scale*a_y1)*a_width)) - *(a_ptr + static_cast<int> (a_scale*a_x2) + (static_cast<int> (a_scale*a_y2)*a_width));" << std::endl;
361  stream << " }" << std::endl;
362  stream << "};" << std::endl;
363  }
364  else
365  {
366  stream << "ERROR: generateEvalFunctionCode not implemented" << std::endl;
367  }
368  }
369 
370  template <class DATA_TYPE, size_t NUM_OF_CHANNELS, size_t SCALE_CHANNEL, bool INVERT_SCALE>
371  void
374  std::ostream & stream) const
375  {
376  stream << "LocalFeatureHandler::eval (data_ptr, "
377  << feature.p1.x << ", "
378  << feature.p1.y << ", "
379  << feature.p2.x << ", "
380  << feature.p2.y << ", "
381  << "scale, width, result, flags);" << std::endl;
382  }
383 
384 
389 
393 
395 
396 }
397 
398 #endif
ScaledMultiChannel2DComparisonFeatureHandler< float, 2, 1, true > ScaledIntensityDepth2DComparisonFeatureHandler
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.
ScaledMultiChannel2DComparisonFeatureHandler(const int feature_window_width, const int feature_window_height)
Constructor.
ScaledMultiChannel2DComparisonFeatureHandlerCCodeGenerator< float, 1, 0, true > ScaledDepth2DComparisonFeatureHandlerCCodeGenerator
ScaledMultiChannel2DComparisonFeatureHandler< float, 1, 0, true > ScaledDepth2DComparisonFeatureHandler
Feature utility class that handles the creation and evaluation of RGBD comparison features...
Example index for a set of 2D data blocks.
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.
Feature for comparing two sample points in 2D multi-channel data.
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.
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.
Holds a set of two-dimensional multi-channel data.
MultiChannel2DComparisonFeatureHandler< float, 3 > RGB2DComparisonFeatureHandler
void generateEvalCode(const MultiChannel2DComparisonFeature< PointXY32f > &feature, std::ostream &stream) const
MultiChannel2DComparisonFeatureHandler< float, 1 > Depth2DComparisonFeatureHandler
unsigned char channel
Specifies which channel is used for comparison.
MultiChannel2DComparisonFeatureHandler< float, 4 > RGBD2DComparisonFeatureHandler
void createRandomFeatures(const size_t num_of_features, std::vector< MultiChannel2DComparisonFeature< PointXY32f > > &features)
Creates random features.
void createRandomFeatures(const size_t num_of_features, std::vector< MultiChannel2DComparisonFeature< PointXY32i > > &features)
Creates random features.
void setFeatureWindowSize(int width, int height)
Sets the feature window size.
Feature utility class that handles the creation and evaluation of RGBD comparison features...
void generateCodeForEvaluation(const MultiChannel2DComparisonFeature< PointXY32f > &feature, std::ostream &stream) const
Generates code for feature evaluation.
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.
void setFeatureWindowSize(int width, int height)
Sets the feature window size.
MultiChannel2DComparisonFeatureHandler< float, 2 > IntensityDepth2DComparisonFeatureHandler
ScaledMultiChannel2DComparisonFeatureHandler< float, 4, 3, true > ScaledRGBD2DComparisonFeatureHandler
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.
Utility class interface which is used for creating and evaluating features.