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