Point Cloud Library (PCL)  1.8.1
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< 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.
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.
void generateCodeForEvaluation(const MultiChannel2DComparisonFeature< PointXY32i > &feature, std::ostream &stream) const
Generates code for feature evaluation.
Example index for a set of 2D data blocks.
Feature for comparing two sample points in 2D multi-channel data.
float x
The x-coordinate of the point.
Definition: point_xy_32f.h:89
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.
Define standard C methods and C++ classes that are common to all methods.
MultiChannel2DComparisonFeatureHandler(const int feature_window_width, const int feature_window_height)
Constructor.
Holds a set of two-dimensional multi-channel data.
MultiChannel2DComparisonFeatureHandler< float, 3 > RGB2DComparisonFeatureHandler
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.
float y
The y-coordinate of the point.
Definition: point_xy_32f.h:91
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.
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.
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.
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.
void generateCodeForEvaluation(const MultiChannel2DComparisonFeature< PointXY32f > &feature, std::ostream &stream) const
Generates code for feature evaluation.
MultiChannel2DComparisonFeatureHandler< float, 2 > IntensityDepth2DComparisonFeatureHandler
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.
void generateEvalCode(const MultiChannel2DComparisonFeature< PointXY32f > &feature, std::ostream &stream) const
ScaledMultiChannel2DComparisonFeatureHandler< float, 4, 3, true > ScaledRGBD2DComparisonFeatureHandler
Utility class interface which is used for creating and evaluating features.