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