Point Cloud Library (PCL)  1.8.1
color_coding.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 #ifndef COLOR_COMPRESSION_H
39 #define COLOR_COMPRESSION_H
40 
41 #include <iterator>
42 #include <iostream>
43 #include <vector>
44 #include <string.h>
45 #include <iostream>
46 #include <stdio.h>
47 #include <string.h>
48 
49 namespace pcl
50 {
51  namespace octree
52  {
53  using namespace std;
54 
55  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
56  /** \brief @b ColorCoding class
57  * \note This class encodes 8-bit color information for octree-based point cloud compression.
58  * \note
59  * \note typename: PointT: type of point used in pointcloud
60  * \author Julius Kammerl (julius@kammerl.de)
61  */
62  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63  template<typename PointT>
65  {
66 
67  // public typedefs
69  typedef boost::shared_ptr<PointCloud> PointCloudPtr;
70  typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
71 
72  public:
73 
74  /** \brief Constructor.
75  *
76  * */
78  output_ (), pointAvgColorDataVector_ (), pointAvgColorDataVector_Iterator_ (),
79  pointDiffColorDataVector_ (), pointDiffColorDataVector_Iterator_ (), colorBitReduction_ (0)
80  {
81  }
82 
83  /** \brief Empty class constructor. */
84  virtual
86  {
87  }
88 
89  /** \brief Define color bit depth of encoded color information.
90  * \param bitDepth_arg: amounts of bits for representing one color component
91  */
92  inline
93  void
94  setBitDepth (unsigned char bitDepth_arg)
95  {
96  colorBitReduction_ = static_cast<unsigned char> (8 - bitDepth_arg);
97  }
98 
99  /** \brief Retrieve color bit depth of encoded color information.
100  * \return amounts of bits for representing one color component
101  */
102  inline unsigned char
104  {
105  return (static_cast<unsigned char> (8 - colorBitReduction_));
106  }
107 
108  /** \brief Set amount of voxels containing point color information and reserve memory
109  * \param voxelCount_arg: amounts of voxels
110  */
111  inline void
112  setVoxelCount (unsigned int voxelCount_arg)
113  {
114  pointAvgColorDataVector_.reserve (voxelCount_arg * 3);
115  }
116 
117  /** \brief Set amount of points within point cloud to be encoded and reserve memory
118  * \param pointCount_arg: amounts of points within point cloud
119  * */
120  inline
121  void
122  setPointCount (unsigned int pointCount_arg)
123  {
124  pointDiffColorDataVector_.reserve (pointCount_arg * 3);
125  }
126 
127  /** \brief Initialize encoding of color information
128  * */
129  void
131  {
132  pointAvgColorDataVector_.clear ();
133 
134  pointDiffColorDataVector_.clear ();
135  }
136 
137  /** \brief Initialize decoding of color information
138  * */
139  void
141  {
142  pointAvgColorDataVector_Iterator_ = pointAvgColorDataVector_.begin ();
143 
144  pointDiffColorDataVector_Iterator_ = pointDiffColorDataVector_.begin ();
145  }
146 
147  /** \brief Get reference to vector containing averaged color data
148  * */
149  std::vector<char>&
151  {
152  return pointAvgColorDataVector_;
153  }
154 
155  /** \brief Get reference to vector containing differential color data
156  * */
157  std::vector<char>&
159  {
160  return pointDiffColorDataVector_;
161  }
162 
163  /** \brief Encode averaged color information for a subset of points from point cloud
164  * \param indexVector_arg indices defining a subset of points from points cloud
165  * \param rgba_offset_arg offset to color information
166  * \param inputCloud_arg input point cloud
167  * */
168  void
169  encodeAverageOfPoints (const typename std::vector<int>& indexVector_arg, unsigned char rgba_offset_arg, PointCloudConstPtr inputCloud_arg)
170  {
171  std::size_t i, len;
172 
173  unsigned int avgRed;
174  unsigned int avgGreen;
175  unsigned int avgBlue;
176 
177  // initialize
178  avgRed = avgGreen = avgBlue = 0;
179 
180  // iterate over points
181  len = indexVector_arg.size ();
182  for (i = 0; i < len; i++)
183  {
184  // get color information from points
185  const int& idx = indexVector_arg[i];
186  const char* idxPointPtr = reinterpret_cast<const char*> (&inputCloud_arg->points[idx]);
187  const int& colorInt = *reinterpret_cast<const int*> (idxPointPtr+rgba_offset_arg);
188 
189  // add color information
190  avgRed += (colorInt >> 0) & 0xFF;
191  avgGreen += (colorInt >> 8) & 0xFF;
192  avgBlue += (colorInt >> 16) & 0xFF;
193 
194  }
195 
196  // calculated average color information
197  if (len > 1)
198  {
199  avgRed /= static_cast<unsigned int> (len);
200  avgGreen /= static_cast<unsigned int> (len);
201  avgBlue /= static_cast<unsigned int> (len);
202  }
203 
204  // remove least significant bits
205  avgRed >>= colorBitReduction_;
206  avgGreen >>= colorBitReduction_;
207  avgBlue >>= colorBitReduction_;
208 
209  // add to average color vector
210  pointAvgColorDataVector_.push_back (static_cast<char> (avgRed));
211  pointAvgColorDataVector_.push_back (static_cast<char> (avgGreen));
212  pointAvgColorDataVector_.push_back (static_cast<char> (avgBlue));
213  }
214 
215  /** \brief Encode color information of a subset of points from point cloud
216  * \param indexVector_arg indices defining a subset of points from points cloud
217  * \param rgba_offset_arg offset to color information
218  * \param inputCloud_arg input point cloud
219  * */
220  void
221  encodePoints (const typename std::vector<int>& indexVector_arg, unsigned char rgba_offset_arg, PointCloudConstPtr inputCloud_arg)
222  {
223  std::size_t i, len;
224 
225  unsigned int avgRed;
226  unsigned int avgGreen;
227  unsigned int avgBlue;
228 
229  // initialize
230  avgRed = avgGreen = avgBlue = 0;
231 
232  // iterate over points
233  len = indexVector_arg.size ();
234  for (i = 0; i < len; i++)
235  {
236  // get color information from point
237  const int& idx = indexVector_arg[i];
238  const char* idxPointPtr = reinterpret_cast<const char*> (&inputCloud_arg->points[idx]);
239  const int& colorInt = *reinterpret_cast<const int*> (idxPointPtr+rgba_offset_arg);
240 
241  // add color information
242  avgRed += (colorInt >> 0) & 0xFF;
243  avgGreen += (colorInt >> 8) & 0xFF;
244  avgBlue += (colorInt >> 16) & 0xFF;
245 
246  }
247 
248  if (len > 1)
249  {
250  unsigned char diffRed;
251  unsigned char diffGreen;
252  unsigned char diffBlue;
253 
254  // calculated average color information
255  avgRed /= static_cast<unsigned int> (len);
256  avgGreen /= static_cast<unsigned int> (len);
257  avgBlue /= static_cast<unsigned int> (len);
258 
259  // iterate over points for differential encoding
260  for (i = 0; i < len; i++)
261  {
262  const int& idx = indexVector_arg[i];
263  const char* idxPointPtr = reinterpret_cast<const char*> (&inputCloud_arg->points[idx]);
264  const int& colorInt = *reinterpret_cast<const int*> (idxPointPtr+rgba_offset_arg);
265 
266  // extract color components and do XOR encoding with predicted average color
267  diffRed = (static_cast<unsigned char> (avgRed)) ^ static_cast<unsigned char> (((colorInt >> 0) & 0xFF));
268  diffGreen = (static_cast<unsigned char> (avgGreen)) ^ static_cast<unsigned char> (((colorInt >> 8) & 0xFF));
269  diffBlue = (static_cast<unsigned char> (avgBlue)) ^ static_cast<unsigned char> (((colorInt >> 16) & 0xFF));
270 
271  // remove least significant bits
272  diffRed = static_cast<unsigned char> (diffRed >> colorBitReduction_);
273  diffGreen = static_cast<unsigned char> (diffGreen >> colorBitReduction_);
274  diffBlue = static_cast<unsigned char> (diffBlue >> colorBitReduction_);
275 
276  // add to differential color vector
277  pointDiffColorDataVector_.push_back (static_cast<char> (diffRed));
278  pointDiffColorDataVector_.push_back (static_cast<char> (diffGreen));
279  pointDiffColorDataVector_.push_back (static_cast<char> (diffBlue));
280  }
281  }
282 
283  // remove least significant bits from average color information
284  avgRed >>= colorBitReduction_;
285  avgGreen >>= colorBitReduction_;
286  avgBlue >>= colorBitReduction_;
287 
288  // add to differential color vector
289  pointAvgColorDataVector_.push_back (static_cast<char> (avgRed));
290  pointAvgColorDataVector_.push_back (static_cast<char> (avgGreen));
291  pointAvgColorDataVector_.push_back (static_cast<char> (avgBlue));
292 
293  }
294 
295  /** \brief Decode color information
296  * \param outputCloud_arg output point cloud
297  * \param beginIdx_arg index indicating first point to be assiged with color information
298  * \param endIdx_arg index indicating last point to be assiged with color information
299  * \param rgba_offset_arg offset to color information
300  */
301  void
302  decodePoints (PointCloudPtr outputCloud_arg, std::size_t beginIdx_arg, std::size_t endIdx_arg, unsigned char rgba_offset_arg)
303  {
304  std::size_t i;
305  unsigned int pointCount;
306  unsigned int colorInt;
307 
308  assert (beginIdx_arg <= endIdx_arg);
309 
310  // amount of points to be decoded
311  pointCount = static_cast<unsigned int> (endIdx_arg - beginIdx_arg);
312 
313  // get averaged color information for current voxel
314  unsigned char avgRed = *(pointAvgColorDataVector_Iterator_++);
315  unsigned char avgGreen = *(pointAvgColorDataVector_Iterator_++);
316  unsigned char avgBlue = *(pointAvgColorDataVector_Iterator_++);
317 
318  // invert bit shifts during encoding
319  avgRed = static_cast<unsigned char> (avgRed << colorBitReduction_);
320  avgGreen = static_cast<unsigned char> (avgGreen << colorBitReduction_);
321  avgBlue = static_cast<unsigned char> (avgBlue << colorBitReduction_);
322 
323  // iterate over points
324  for (i = 0; i < pointCount; i++)
325  {
326  if (pointCount > 1)
327  {
328  // get differential color information from input vector
329  unsigned char diffRed = static_cast<unsigned char> (*(pointDiffColorDataVector_Iterator_++));
330  unsigned char diffGreen = static_cast<unsigned char> (*(pointDiffColorDataVector_Iterator_++));
331  unsigned char diffBlue = static_cast<unsigned char> (*(pointDiffColorDataVector_Iterator_++));
332 
333  // invert bit shifts during encoding
334  diffRed = static_cast<unsigned char> (diffRed << colorBitReduction_);
335  diffGreen = static_cast<unsigned char> (diffGreen << colorBitReduction_);
336  diffBlue = static_cast<unsigned char> (diffBlue << colorBitReduction_);
337 
338  // decode color information
339  colorInt = ((avgRed ^ diffRed) << 0) |
340  ((avgGreen ^ diffGreen) << 8) |
341  ((avgBlue ^ diffBlue) << 16);
342  }
343  else
344  {
345  // decode color information
346  colorInt = (avgRed << 0) | (avgGreen << 8) | (avgBlue << 16);
347  }
348 
349  char* idxPointPtr = reinterpret_cast<char*> (&outputCloud_arg->points[beginIdx_arg + i]);
350  int& pointColor = *reinterpret_cast<int*> (idxPointPtr+rgba_offset_arg);
351  // assign color to point from point cloud
352  pointColor=colorInt;
353  }
354  }
355 
356  /** \brief Set default color to points
357  * \param outputCloud_arg output point cloud
358  * \param beginIdx_arg index indicating first point to be assiged with color information
359  * \param endIdx_arg index indicating last point to be assiged with color information
360  * \param rgba_offset_arg offset to color information
361  * */
362  void
363  setDefaultColor (PointCloudPtr outputCloud_arg, std::size_t beginIdx_arg, std::size_t endIdx_arg, unsigned char rgba_offset_arg)
364  {
365  std::size_t i;
366  unsigned int pointCount;
367 
368  assert (beginIdx_arg <= endIdx_arg);
369 
370  // amount of points to be decoded
371  pointCount = static_cast<unsigned int> (endIdx_arg - beginIdx_arg);
372 
373  // iterate over points
374  for (i = 0; i < pointCount; i++)
375  {
376  char* idxPointPtr = reinterpret_cast<char*> (&outputCloud_arg->points[beginIdx_arg + i]);
377  int& pointColor = *reinterpret_cast<int*> (idxPointPtr+rgba_offset_arg);
378  // assign color to point from point cloud
379  pointColor = defaultColor_;
380  }
381  }
382 
383 
384  protected:
385 
386  /** \brief Pointer to output point cloud dataset. */
387  PointCloudPtr output_;
388 
389  /** \brief Vector for storing average color information */
390  std::vector<char> pointAvgColorDataVector_;
391 
392  /** \brief Iterator on average color information vector */
393  std::vector<char>::const_iterator pointAvgColorDataVector_Iterator_;
394 
395  /** \brief Vector for storing differential color information */
396  std::vector<char> pointDiffColorDataVector_;
397 
398  /** \brief Iterator on differential color information vector */
399  std::vector<char>::const_iterator pointDiffColorDataVector_Iterator_;
400 
401  /** \brief Amount of bits to be removed from color components before encoding */
402  unsigned char colorBitReduction_;
403 
404  // frame header identifier
405  static const int defaultColor_;
406 
407  };
408 
409  // define default color
410  template<typename PointT>
411  const int ColorCoding<PointT>::defaultColor_ = ((255) << 0) |
412  ((255) << 8) |
413  ((255) << 16);
414 
415  }
416 }
417 
418 #define PCL_INSTANTIATE_ColorCoding(T) template class PCL_EXPORTS pcl::octree::ColorCoding<T>;
419 
420 #endif
std::vector< char >::const_iterator pointDiffColorDataVector_Iterator_
Iterator on differential color information vector.
Definition: color_coding.h:399
std::vector< char > pointAvgColorDataVector_
Vector for storing average color information.
Definition: color_coding.h:390
unsigned char colorBitReduction_
Amount of bits to be removed from color components before encoding.
Definition: color_coding.h:402
static const int defaultColor_
Definition: color_coding.h:405
void initializeDecoding()
Initialize decoding of color information.
Definition: color_coding.h:140
PointCloudPtr output_
Pointer to output point cloud dataset.
Definition: color_coding.h:387
void setVoxelCount(unsigned int voxelCount_arg)
Set amount of voxels containing point color information and reserve memory.
Definition: color_coding.h:112
void setDefaultColor(PointCloudPtr outputCloud_arg, std::size_t beginIdx_arg, std::size_t endIdx_arg, unsigned char rgba_offset_arg)
Set default color to points.
Definition: color_coding.h:363
std::vector< char > pointDiffColorDataVector_
Vector for storing differential color information.
Definition: color_coding.h:396
std::vector< char >::const_iterator pointAvgColorDataVector_Iterator_
Iterator on average color information vector.
Definition: color_coding.h:393
std::vector< char > & getAverageDataVector()
Get reference to vector containing averaged color data.
Definition: color_coding.h:150
ColorCoding()
Constructor.
Definition: color_coding.h:77
void encodeAverageOfPoints(const typename std::vector< int > &indexVector_arg, unsigned char rgba_offset_arg, PointCloudConstPtr inputCloud_arg)
Encode averaged color information for a subset of points from point cloud.
Definition: color_coding.h:169
unsigned char getBitDepth()
Retrieve color bit depth of encoded color information.
Definition: color_coding.h:103
ColorCoding class
Definition: color_coding.h:64
void setBitDepth(unsigned char bitDepth_arg)
Define color bit depth of encoded color information.
Definition: color_coding.h:94
virtual ~ColorCoding()
Empty class constructor.
Definition: color_coding.h:85
std::vector< char > & getDifferentialDataVector()
Get reference to vector containing differential color data.
Definition: color_coding.h:158
PointCloud represents the base class in PCL for storing collections of 3D points. ...
void decodePoints(PointCloudPtr outputCloud_arg, std::size_t beginIdx_arg, std::size_t endIdx_arg, unsigned char rgba_offset_arg)
Decode color information.
Definition: color_coding.h:302
void initializeEncoding()
Initialize encoding of color information.
Definition: color_coding.h:130
void encodePoints(const typename std::vector< int > &indexVector_arg, unsigned char rgba_offset_arg, PointCloudConstPtr inputCloud_arg)
Encode color information of a subset of points from point cloud.
Definition: color_coding.h:221
void setPointCount(unsigned int pointCount_arg)
Set amount of points within point cloud to be encoded and reserve memory.
Definition: color_coding.h:122