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