Point Cloud Library (PCL)
1.15.1
Toggle main menu visibility
Loading...
Searching...
No Matches
pcl
io
impl
point_cloud_image_extractors.hpp
1
/*
2
* Software License Agreement (BSD License)
3
*
4
* Point Cloud Library (PCL) - www.pointclouds.org
5
* Copyright (c) 2013-, Open Perception, 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 the copyright holder(s) 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 <set>
41
#include <map>
42
#include <ctime>
43
#include <cstdlib>
44
45
#include <pcl/common/io.h>
46
#include <pcl/common/colors.h>
47
#include <pcl/common/point_tests.h>
// for pcl::isFinite
48
49
///////////////////////////////////////////////////////////////////////////////////////////
50
template
<
typename
Po
int
T>
bool
51
pcl::io::PointCloudImageExtractor<PointT>::extract
(
const
PointCloud
& cloud,
pcl::PCLImage
& img)
const
52
{
53
if
(!cloud.
isOrganized
() || cloud.
size
() != cloud.
width
* cloud.
height
)
54
return
(
false
);
55
56
bool
result = this->
extractImpl
(cloud, img);
57
58
if
(
paint_nans_with_black_
&& result)
59
{
60
std::size_t size = img.
encoding
==
"mono16"
? 2 : 3;
61
for
(std::size_t i = 0; i < cloud.
size
(); ++i)
62
if
(!
pcl::isFinite
(cloud[i])) {
63
std::fill_n(&img.
data
[i * size], size, 0);
64
}
65
}
66
67
return
(result);
68
}
69
70
///////////////////////////////////////////////////////////////////////////////////////////
71
template
<
typename
Po
int
T>
bool
72
pcl::io::PointCloudImageExtractorFromNormalField<PointT>::extractImpl
(
const
PointCloud& cloud,
pcl::PCLImage
& img)
const
73
{
74
std::vector<pcl::PCLPointField>
fields
;
75
int
field_x_idx =
pcl::getFieldIndex<PointT>
(
"normal_x"
,
fields
);
76
int
field_y_idx =
pcl::getFieldIndex<PointT>
(
"normal_y"
,
fields
);
77
int
field_z_idx =
pcl::getFieldIndex<PointT>
(
"normal_z"
,
fields
);
78
if
(field_x_idx == -1 || field_y_idx == -1 || field_z_idx == -1)
79
return
(
false
);
80
const
std::size_t offset_x =
fields
[field_x_idx].offset;
81
const
std::size_t offset_y =
fields
[field_y_idx].offset;
82
const
std::size_t offset_z =
fields
[field_z_idx].offset;
83
84
img.
encoding
=
"rgb8"
;
85
img.
width
= cloud.width;
86
img.
height
= cloud.height;
87
img.
step
= img.
width
*
sizeof
(
unsigned
char) * 3;
88
img.
data
.resize (img.
step
* img.
height
);
89
90
for
(std::size_t i = 0; i < cloud.size (); ++i)
91
{
92
float
x;
93
float
y;
94
float
z;
95
pcl::getFieldValue<PointT, float>
(cloud[i], offset_x, x);
96
pcl::getFieldValue<PointT, float>
(cloud[i], offset_y, y);
97
pcl::getFieldValue<PointT, float>
(cloud[i], offset_z, z);
98
img.
data
[i * 3 + 0] =
static_cast<
unsigned
char
>
((x + 1.0) * 127);
99
img.
data
[i * 3 + 1] =
static_cast<
unsigned
char
>
((y + 1.0) * 127);
100
img.
data
[i * 3 + 2] =
static_cast<
unsigned
char
>
((z + 1.0) * 127);
101
}
102
103
return
(
true
);
104
}
105
106
///////////////////////////////////////////////////////////////////////////////////////////
107
template
<
typename
Po
int
T>
bool
108
pcl::io::PointCloudImageExtractorFromRGBField<PointT>::extractImpl
(
const
PointCloud& cloud,
pcl::PCLImage
& img)
const
109
{
110
std::vector<pcl::PCLPointField>
fields
;
111
int
field_idx =
pcl::getFieldIndex<PointT>
(
"rgb"
,
fields
);
112
if
(field_idx == -1)
113
{
114
field_idx =
pcl::getFieldIndex<PointT>
(
"rgba"
,
fields
);
115
if
(field_idx == -1)
116
return
(
false
);
117
}
118
const
std::size_t offset =
fields
[field_idx].offset;
119
120
img.
encoding
=
"rgb8"
;
121
img.
width
= cloud.width;
122
img.
height
= cloud.height;
123
img.
step
= img.
width
*
sizeof
(
unsigned
char) * 3;
124
img.
data
.resize (img.
step
* img.
height
);
125
126
for
(std::size_t i = 0; i < cloud.size (); ++i)
127
{
128
std::uint32_t val;
129
pcl::getFieldValue<PointT, std::uint32_t>
(cloud[i], offset, val);
130
img.
data
[i * 3 + 0] = (val >> 16) & 0x0000ff;
131
img.
data
[i * 3 + 1] = (val >> 8) & 0x0000ff;
132
img.
data
[i * 3 + 2] = (val) & 0x0000ff;
133
}
134
135
return
(
true
);
136
}
137
138
///////////////////////////////////////////////////////////////////////////////////////////
139
template
<
typename
Po
int
T>
bool
140
pcl::io::PointCloudImageExtractorFromLabelField<PointT>::extractImpl
(
const
PointCloud& cloud,
pcl::PCLImage
& img)
const
141
{
142
std::vector<pcl::PCLPointField>
fields
;
143
int
field_idx =
pcl::getFieldIndex<PointT>
(
"label"
,
fields
);
144
if
(field_idx == -1)
145
return
(
false
);
146
const
std::size_t offset =
fields
[field_idx].offset;
147
148
switch
(color_mode_)
149
{
150
case
COLORS_MONO
:
151
{
152
img.
encoding
=
"mono16"
;
153
img.
width
= cloud.width;
154
img.
height
= cloud.height;
155
img.
step
= img.
width
*
sizeof
(
unsigned
short);
156
img.
data
.resize (img.
step
* img.
height
);
157
auto
* data =
reinterpret_cast<
unsigned
short
*
>
(img.
data
.data());
158
for
(std::size_t i = 0; i < cloud.size (); ++i)
159
{
160
std::uint32_t val;
161
pcl::getFieldValue<PointT, std::uint32_t>
(cloud[i], offset, val);
162
data[i] =
static_cast<
unsigned
short
>
(val);
163
}
164
break
;
165
}
166
case
COLORS_RGB_RANDOM
:
167
{
168
img.
encoding
=
"rgb8"
;
169
img.
width
= cloud.width;
170
img.
height
= cloud.height;
171
img.
step
= img.
width
*
sizeof
(
unsigned
char) * 3;
172
img.
data
.resize (img.
step
* img.
height
);
173
174
std::srand(std::time(
nullptr
));
175
std::map<std::uint32_t, std::size_t> colormap;
176
177
for
(std::size_t i = 0; i < cloud.size (); ++i)
178
{
179
std::uint32_t val;
180
pcl::getFieldValue<PointT, std::uint32_t>
(cloud[i], offset, val);
181
if
(colormap.count (val) == 0)
182
{
183
colormap[val] = i * 3;
184
img.
data
[i * 3 + 0] =
static_cast<
std::uint8_t
>
((std::rand () % 256));
185
img.
data
[i * 3 + 1] =
static_cast<
std::uint8_t
>
((std::rand () % 256));
186
img.
data
[i * 3 + 2] =
static_cast<
std::uint8_t
>
((std::rand () % 256));
187
}
188
else
189
{
190
memcpy (&img.
data
[i * 3], &img.
data
[colormap[val]], 3);
191
}
192
}
193
break
;
194
}
195
case
COLORS_RGB_GLASBEY
:
196
{
197
img.
encoding
=
"rgb8"
;
198
img.
width
= cloud.width;
199
img.
height
= cloud.height;
200
img.
step
= img.
width
*
sizeof
(
unsigned
char) * 3;
201
img.
data
.resize (img.
step
* img.
height
);
202
203
std::srand(std::time(
nullptr
));
204
std::set<std::uint32_t> labels;
205
std::map<std::uint32_t, std::size_t> colormap;
206
207
// First pass: find unique labels
208
for
(
const
auto
& point: cloud)
209
{
210
// If we need to paint NaN points with black do not waste colors on them
211
if
(
paint_nans_with_black_
&& !
pcl::isFinite
(point))
212
continue
;
213
std::uint32_t val;
214
pcl::getFieldValue<PointT, std::uint32_t>
(point, offset, val);
215
labels.insert (val);
216
}
217
218
// Assign Glasbey colors in ascending order of labels
219
// Note: the color LUT has a finite size (256 colors), therefore when
220
// there are more labels the colors will repeat
221
std::size_t color = 0;
222
for
(
const
std::uint32_t &label : labels)
223
{
224
colormap[label] = color %
GlasbeyLUT::size
();
225
++color;
226
}
227
228
// Second pass: copy colors from the LUT
229
for
(std::size_t i = 0; i < cloud.size (); ++i)
230
{
231
std::uint32_t val;
232
pcl::getFieldValue<PointT, std::uint32_t>
(cloud[i], offset, val);
233
memcpy (&img.
data
[i * 3],
GlasbeyLUT::data
() + colormap[val] * 3, 3);
234
}
235
236
break
;
237
}
238
}
239
240
return
(
true
);
241
}
242
243
///////////////////////////////////////////////////////////////////////////////////////////
244
template
<
typename
Po
int
T>
bool
245
pcl::io::PointCloudImageExtractorWithScaling<PointT>::extractImpl
(
const
PointCloud& cloud,
pcl::PCLImage
& img)
const
246
{
247
std::vector<pcl::PCLPointField>
fields
;
248
int
field_idx =
pcl::getFieldIndex<PointT>
(
field_name_
,
fields
);
249
if
(field_idx == -1)
250
return
(
false
);
251
const
std::size_t offset =
fields
[field_idx].offset;
252
253
img.
encoding
=
"mono16"
;
254
img.
width
= cloud.width;
255
img.
height
= cloud.height;
256
img.
step
= img.
width
*
sizeof
(
unsigned
short);
257
img.
data
.resize (img.
step
* img.
height
);
258
auto
* data =
reinterpret_cast<
unsigned
short
*
>
(img.
data
.data());
259
260
float
scaling_factor =
scaling_factor_
;
261
float
data_min = 0.0f;
262
if
(
scaling_method_
==
SCALING_FULL_RANGE
)
263
{
264
float
min = std::numeric_limits<float>::infinity();
265
float
max = -std::numeric_limits<float>::infinity();
266
for
(
const
auto
& point: cloud)
267
{
268
float
val;
269
pcl::getFieldValue<PointT, float>
(point, offset, val);
270
if
(val < min)
271
min = val;
272
if
(val > max)
273
max = val;
274
}
275
scaling_factor = min == max ? 0 : std::numeric_limits<unsigned short>::max() / (max - min);
276
data_min = min;
277
}
278
279
for
(std::size_t i = 0; i < cloud.size (); ++i)
280
{
281
float
val;
282
pcl::getFieldValue<PointT, float>
(cloud[i], offset, val);
283
if
(
scaling_method_
==
SCALING_NO
)
284
{
285
data[i] = val;
286
}
287
else
if
(
scaling_method_
==
SCALING_FULL_RANGE
)
288
{
289
data[i] = (val - data_min) * scaling_factor;
290
}
291
else
if
(
scaling_method_
==
SCALING_FIXED_FACTOR
)
292
{
293
data[i] = val * scaling_factor;
294
}
295
}
296
297
return
(
true
);
298
}
299
pcl::ColorLUT< pcl::LUT_GLASBEY >::size
static std::size_t size()
pcl::ColorLUT< pcl::LUT_GLASBEY >::data
static const unsigned char * data()
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition
point_cloud.h:399
pcl::PointCloud::isOrganized
bool isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
Definition
point_cloud.h:311
pcl::PointCloud::height
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition
point_cloud.h:401
pcl::PointCloud::size
std::size_t size() const
Definition
point_cloud.h:444
pcl::io::PointCloudImageExtractorFromLabelField::COLORS_RGB_GLASBEY
@ COLORS_RGB_GLASBEY
Fixed RGB colors from the Glasbey lookup table, assigned in the ascending order of label id.
Definition
point_cloud_image_extractors.h:275
pcl::io::PointCloudImageExtractorFromLabelField::COLORS_MONO
@ COLORS_MONO
Shades of gray (according to label id).
Definition
point_cloud_image_extractors.h:270
pcl::io::PointCloudImageExtractorFromLabelField::COLORS_RGB_RANDOM
@ COLORS_RGB_RANDOM
Randomly generated RGB colors.
Definition
point_cloud_image_extractors.h:272
pcl::io::PointCloudImageExtractorFromLabelField::extractImpl
bool extractImpl(const PointCloud &cloud, pcl::PCLImage &img) const override
Implementation of the extract() function, has to be implemented in deriving classes.
Definition
point_cloud_image_extractors.hpp:140
pcl::io::PointCloudImageExtractorFromNormalField::extractImpl
bool extractImpl(const PointCloud &cloud, pcl::PCLImage &img) const override
Implementation of the extract() function, has to be implemented in deriving classes.
Definition
point_cloud_image_extractors.hpp:72
pcl::io::PointCloudImageExtractorFromRGBField::extractImpl
bool extractImpl(const PointCloud &cloud, pcl::PCLImage &img) const override
Implementation of the extract() function, has to be implemented in deriving classes.
Definition
point_cloud_image_extractors.hpp:108
pcl::io::PointCloudImageExtractor::extractImpl
virtual bool extractImpl(const PointCloud &cloud, pcl::PCLImage &image) const =0
Implementation of the extract() function, has to be implemented in deriving classes.
pcl::io::PointCloudImageExtractor::extract
bool extract(const PointCloud &cloud, pcl::PCLImage &image) const
Obtain the image from the given cloud.
Definition
point_cloud_image_extractors.hpp:51
pcl::io::PointCloudImageExtractor::paint_nans_with_black_
bool paint_nans_with_black_
A flag that controls if image pixels corresponding to NaN (infinite) points should be painted black.
Definition
point_cloud_image_extractors.h:119
pcl::io::PointCloudImageExtractor::PointCloud
pcl::PointCloud< PointT > PointCloud
Definition
point_cloud_image_extractors.h:81
pcl::io::PointCloudImageExtractorWithScaling::scaling_factor_
float scaling_factor_
Definition
point_cloud_image_extractors.h:191
pcl::io::PointCloudImageExtractorWithScaling::extractImpl
bool extractImpl(const PointCloud &cloud, pcl::PCLImage &image) const override
Implementation of the extract() function, has to be implemented in deriving classes.
Definition
point_cloud_image_extractors.hpp:245
pcl::io::PointCloudImageExtractorWithScaling::field_name_
std::string field_name_
Definition
point_cloud_image_extractors.h:189
pcl::io::PointCloudImageExtractorWithScaling::scaling_method_
ScalingMethod scaling_method_
Definition
point_cloud_image_extractors.h:190
pcl::io::PointCloudImageExtractorWithScaling::SCALING_FIXED_FACTOR
@ SCALING_FIXED_FACTOR
Definition
point_cloud_image_extractors.h:148
pcl::io::PointCloudImageExtractorWithScaling::SCALING_FULL_RANGE
@ SCALING_FULL_RANGE
Definition
point_cloud_image_extractors.h:147
pcl::io::PointCloudImageExtractorWithScaling::SCALING_NO
@ SCALING_NO
Definition
point_cloud_image_extractors.h:146
pcl::fields
Definition
type_traits.h:60
pcl::getFieldIndex
int getFieldIndex(const pcl::PointCloud< PointT > &, const std::string &field_name, std::vector< pcl::PCLPointField > &fields)
Definition
io.hpp:52
pcl::isFinite
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
Definition
point_tests.h:55
pcl::getFieldValue
void getFieldValue(const PointT &pt, std::size_t field_offset, ValT &value)
Get the value at a specified field in a point.
Definition
type_traits.h:249
pcl::PCLImage
Definition
PCLImage.h:13
pcl::PCLImage::step
uindex_t step
Definition
PCLImage.h:21
pcl::PCLImage::height
uindex_t height
Definition
PCLImage.h:16
pcl::PCLImage::encoding
std::string encoding
Definition
PCLImage.h:18
pcl::PCLImage::data
std::vector< std::uint8_t > data
Definition
PCLImage.h:23
pcl::PCLImage::width
uindex_t width
Definition
PCLImage.h:17