Point Cloud Library (PCL) 1.15.0
Loading...
Searching...
No Matches
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
43namespace pcl
44{
45
46namespace 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 */
55template<typename PointT>
57{
58 // public typedefs
59 using PointCloud = pcl::PointCloud<PointT>;
60 using PointCloudPtr = typename PointCloud::Ptr;
61 using PointCloudConstPtr = typename PointCloud::ConstPtr;
62
63public:
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 {
117
119 }
120
121 /** \brief Initialize decoding of color information
122 * */
123 void
130
131 /** \brief Get reference to vector containing averaged color data
132 * */
133 std::vector<char>&
138
139 /** \brief Get reference to vector containing differential color data
140 * */
141 std::vector<char>&
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
351protected:
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
375template<typename PointT>
376const 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.
shared_ptr< PointCloud< PointT > > Ptr
shared_ptr< const PointCloud< PointT > > ConstPtr
ColorCoding class
void decodePoints(PointCloudPtr outputCloud_arg, uindex_t beginIdx_arg, uindex_t endIdx_arg, unsigned char rgba_offset_arg)
Decode color information.
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.
void initializeDecoding()
Initialize decoding of color information.
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.
std::vector< char > pointDiffColorDataVector_
Vector for storing differential color information
std::vector< char > pointAvgColorDataVector_
Vector for storing average color information
std::vector< char >::const_iterator pointAvgColorDataVector_Iterator_
Iterator on average color information vector.
void initializeEncoding()
Initialize encoding of color information.
virtual ~ColorCoding()=default
Empty class constructor.
unsigned char colorBitReduction_
Amount of bits to be removed from color components before encoding.
unsigned char getBitDepth()
Retrieve color bit depth of encoded color information.
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.
std::vector< char >::const_iterator pointDiffColorDataVector_Iterator_
Iterator on differential color information vector.
void setVoxelCount(unsigned int voxelCount_arg)
Set amount of voxels containing point color information and reserve memory.
ColorCoding()=default
Constructor.
static const int defaultColor_
std::vector< char > & getAverageDataVector()
Get reference to vector containing averaged color data.
void setBitDepth(unsigned char bitDepth_arg)
Define color bit depth of encoded color information.
void setPointCount(unsigned int pointCount_arg)
Set amount of points within point cloud to be encoded and reserve memory.
std::vector< char > & getDifferentialDataVector()
Get reference to vector containing differential color data.
PointCloudPtr output_
Pointer to output point cloud dataset.
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