45 #include <pcl/common/colors.h>
46 #include <pcl/common/io.h>
47 #include <pcl/common/point_tests.h>
53 namespace visualization
59 if (!capable_ || !cloud_)
63 scalars->SetNumberOfComponents (3);
65 vtkIdType nr_points = cloud_->size ();
66 scalars->SetNumberOfTuples (nr_points);
69 unsigned char* colors =
new unsigned char[nr_points * 3];
72 for (vtkIdType cp = 0; cp < nr_points; ++cp)
74 colors[cp * 3 + 0] =
static_cast<unsigned char> (r_);
75 colors[cp * 3 + 1] =
static_cast<unsigned char> (g_);
76 colors[cp * 3 + 2] =
static_cast<unsigned char> (b_);
78 scalars->SetArray (colors, 3 * nr_points, 0, vtkUnsignedCharArray::VTK_DATA_ARRAY_DELETE);
86 if (!capable_ || !cloud_)
90 scalars->SetNumberOfComponents (3);
92 vtkIdType nr_points = cloud_->size ();
93 scalars->SetNumberOfTuples (nr_points);
96 unsigned char* colors =
new unsigned char[nr_points * 3];
100 int r_ =
static_cast<int> (
pcl_lrint (r * 255.0)),
101 g_ =
static_cast<int> (
pcl_lrint (g * 255.0)),
102 b_ =
static_cast<int> (
pcl_lrint (b * 255.0));
105 for (vtkIdType cp = 0; cp < nr_points; ++cp)
107 colors[cp * 3 + 0] =
static_cast<unsigned char> (r_);
108 colors[cp * 3 + 1] =
static_cast<unsigned char> (g_);
109 colors[cp * 3 + 2] =
static_cast<unsigned char> (b_);
111 scalars->SetArray (colors, 3 * nr_points, 0, vtkUnsignedCharArray::VTK_DATA_ARRAY_DELETE);
116 template <
typename Po
intT>
void
122 field_idx_ = pcl::getFieldIndex<PointT> (
"rgb", fields_);
123 if (field_idx_ != -1)
130 field_idx_ = pcl::getFieldIndex<PointT> (
"rgba", fields_);
131 if (field_idx_ != -1)
142 if (!capable_ || !cloud_)
146 std::vector<pcl::PCLPointField> fields;
148 rgba_index = pcl::getFieldIndex<PointT> (
"rgb", fields);
149 if (rgba_index == -1)
150 rgba_index = pcl::getFieldIndex<PointT> (
"rgba", fields);
152 int rgba_offset = fields[rgba_index].offset;
155 scalars->SetNumberOfComponents (3);
157 vtkIdType nr_points = cloud_->size ();
158 scalars->SetNumberOfTuples (nr_points);
159 unsigned char* colors = scalars->GetPointer (0);
163 for (std::size_t d = 0; d < fields_.size (); ++d)
164 if (fields_[d].name ==
"x")
165 x_idx =
static_cast<int> (d);
172 for (vtkIdType cp = 0; cp < nr_points; ++cp)
177 memcpy (&rgb, (
reinterpret_cast<const char *
> (&(*cloud_)[cp])) + rgba_offset,
sizeof (
pcl::RGB));
179 colors[j + 1] = rgb.g;
180 colors[j + 2] = rgb.b;
187 for (vtkIdType cp = 0; cp < nr_points; ++cp)
189 int idx =
static_cast<int> (cp) * 3;
190 memcpy (&rgb, (
reinterpret_cast<const char *
> (&(*cloud_)[cp])) + rgba_offset,
sizeof (
pcl::RGB));
191 colors[idx ] = rgb.r;
192 colors[idx + 1] = rgb.g;
193 colors[idx + 2] = rgb.b;
200 template <
typename Po
intT>
234 if (!capable_ || !cloud_)
238 scalars->SetNumberOfComponents (3);
240 vtkIdType nr_points = cloud_->size ();
241 scalars->SetNumberOfTuples (nr_points);
242 unsigned char* colors = scalars->GetPointer (0);
248 for (std::size_t d = 0; d < fields_.size (); ++d)
249 if (fields_[d].name ==
"x")
250 x_idx =
static_cast<int> (d);
255 for (vtkIdType cp = 0; cp < nr_points; ++cp)
263 float h = (*cloud_)[cp].h;
264 float v = (*cloud_)[cp].v;
265 float s = (*cloud_)[cp].s;
269 h = h < 0.0f ? h - (((int)h)/360 - 1)*360 : h - (((
int)h)/360)*360;
272 if (s > 1.0f) s = 1.0f;
273 if (s < 0.0f) s = 0.0f;
274 if (v > 1.0f) v = 1.0f;
275 if (v < 0.0f) v = 0.0f;
279 colors[idx] = colors[idx+1] = colors[idx+2] = v*255;
285 int i = std::floor (a);
287 float p = v * (1 - s);
288 float q = v * (1 - s * f);
289 float t = v * (1 - s * (1 - f));
294 colors[idx] = v*255; colors[idx+1] = t*255; colors[idx+2] = p*255;
break;
296 colors[idx] = q*255; colors[idx+1] = v*255; colors[idx+2] = p*255;
break;
298 colors[idx] = p*255; colors[idx+1] = v*255; colors[idx+2] = t*255;
break;
300 colors[idx] = p*255; colors[idx+1] = q*255; colors[idx+2] = v*255;
break;
302 colors[idx] = t*255; colors[idx+1] = p*255; colors[idx+2] = v*255;
break;
304 colors[idx] = v*255; colors[idx+1] = p*255; colors[idx+2] = q*255;
break;
313 for (vtkIdType cp = 0; cp < nr_points; ++cp)
315 float h = (*cloud_)[cp].h;
316 float v = (*cloud_)[cp].v;
317 float s = (*cloud_)[cp].s;
321 h = h < 0.0f ? h - (((int)h)/360 - 1)*360 : h - (((
int)h)/360)*360;
324 if (s > 1.0f) s = 1.0f;
325 if (s < 0.0f) s = 0.0f;
326 if (v > 1.0f) v = 1.0f;
327 if (v < 0.0f) v = 0.0f;
331 colors[idx] = colors[idx+1] = colors[idx+2] = v*255;
337 int i = std::floor (a);
339 float p = v * (1 - s);
340 float q = v * (1 - s * f);
341 float t = v * (1 - s * (1 - f));
346 colors[idx] = v*255; colors[idx+1] = t*255; colors[idx+2] = p*255;
break;
348 colors[idx] = q*255; colors[idx+1] = v*255; colors[idx+2] = p*255;
break;
350 colors[idx] = p*255; colors[idx+1] = v*255; colors[idx+2] = t*255;
break;
352 colors[idx] = p*255; colors[idx+1] = q*255; colors[idx+2] = v*255;
break;
354 colors[idx] = t*255; colors[idx+1] = p*255; colors[idx+2] = v*255;
break;
356 colors[idx] = v*255; colors[idx+1] = p*255; colors[idx+2] = q*255;
break;
365 template <
typename Po
intT>
void
371 field_idx_ = pcl::getFieldIndex<PointT> (
"rgba", fields_);
372 if (field_idx_ != -1)
382 if (!capable_ || !cloud_)
386 scalars->SetNumberOfComponents (4);
388 vtkIdType nr_points = cloud_->size ();
389 scalars->SetNumberOfTuples (nr_points);
390 unsigned char* colors = scalars->GetPointer (0);
394 for (std::size_t d = 0; d < fields_.size (); ++d)
395 if (fields_[d].name ==
"x")
396 x_idx =
static_cast<int> (d);
402 for (vtkIdType cp = 0; cp < nr_points; ++cp)
408 colors[j ] = (*cloud_)[cp].r;
409 colors[j + 1] = (*cloud_)[cp].g;
410 colors[j + 2] = (*cloud_)[cp].b;
411 colors[j + 3] = (*cloud_)[cp].a;
418 for (vtkIdType cp = 0; cp < nr_points; ++cp)
420 int idx =
static_cast<int> (cp) * 4;
421 colors[idx ] = (*cloud_)[cp].r;
422 colors[idx + 1] = (*cloud_)[cp].g;
423 colors[idx + 2] = (*cloud_)[cp].b;
424 colors[idx + 3] = (*cloud_)[cp].a;
431 template <
typename Po
intT>
void
435 field_idx_ = pcl::getFieldIndex<PointT> (
"label", fields_);
436 if (field_idx_ != -1)
447 if (!capable_ || !cloud_)
451 scalars->SetNumberOfComponents (3);
453 vtkIdType nr_points = cloud_->size ();
454 scalars->SetNumberOfTuples (nr_points);
455 unsigned char* colors = scalars->GetPointer (0);
458 std::map<std::uint32_t, pcl::RGB> colormap;
459 if (!static_mapping_)
461 std::set<std::uint32_t> labels;
463 for (vtkIdType i = 0; i < nr_points; ++i)
464 labels.insert ((*cloud_)[i].label);
467 std::size_t color = 0;
468 for (std::set<std::uint32_t>::iterator iter = labels.begin (); iter != labels.end (); ++iter, ++color)
473 for (vtkIdType cp = 0; cp < nr_points; ++cp)
478 colors[j ] = color.r;
479 colors[j + 1] = color.g;
480 colors[j + 2] = color.b;
495 return sizeof(
typename CloudT::PointType);
498 template <>
inline int
504 template <
typename CloudT>
inline const std::uint8_t*
getCloudData(
const CloudT& cloud)
506 return reinterpret_cast<const std::uint8_t*
>(cloud.data());
509 template <>
inline const std::uint8_t* getCloudData<pcl::PCLPointCloud2>(
const typename pcl::PCLPointCloud2& cloud) {
510 return cloud.
data.data();
516 const std::vector<pcl::PCLPointField>& fields)
519 std::find_if(fields.begin(), fields.end(), [&field_name](
const auto& field) {
520 return field.name == field_name;
522 if (result == fields.end()) {
530 template <
typename CloudT>
inline bool isXYZFiniteAt(
const CloudT& cloud,
int index)
543 if (x_field_idx == -1 || y_field_idx == -1 || z_field_idx == -1) {
544 throw std::out_of_range(
"isXYZFiniteAt(): input cloud missing at least one of x, y, z fields");
547 const auto position_x = index * cloud.
point_step + cloud.
fields[x_field_idx].offset;
548 const auto position_y = index * cloud.
point_step + cloud.
fields[y_field_idx].offset;
549 const auto position_z = index * cloud.
point_step + cloud.
fields[z_field_idx].offset;
550 if (cloud.
data.size () >= (position_x +
sizeof(
float)) &&
551 cloud.
data.size () >= (position_y +
sizeof(
float)) &&
552 cloud.
data.size () >= (position_z +
sizeof(
float))) {
553 const float x = *
reinterpret_cast<const float*
>(&cloud.
data[position_x]);
554 const float y = *
reinterpret_cast<const float*
>(&cloud.
data[position_y]);
555 const float z = *
reinterpret_cast<const float*
>(&cloud.
data[position_z]);
559 throw std::out_of_range(
"isXYZFiniteAt(): requested for index larger than number of points");
563 template <
typename Po
intT>
571 template <
typename Po
intT>
580 this->field_idx_ =
getFieldIndex(field_name_, this->fields_);
581 this->capable_ = this->field_idx_ != -1;
591 if (!this->capable_ || !this->cloud_) {
596 scalars->SetNumberOfComponents(1);
598 const vtkIdType nr_points = this->cloud_->width * this->cloud_->height;
599 scalars->SetNumberOfTuples(nr_points);
602 float* colors =
new float[nr_points];
605 int x_channel_idx = -1;
606 for (std::size_t channel_idx = 0; channel_idx < this->fields_.size(); ++channel_idx) {
607 if (this->fields_[channel_idx].name ==
"x") {
608 x_channel_idx =
static_cast<int>(channel_idx);
612 size_t point_offset = this->fields_[this->field_idx_].offset;
613 const int point_step = getPointStep<PointCloud>(*this->cloud_);
614 const std::uint8_t* p_data = getCloudData<PointCloud>(*this->cloud_);
615 const std::uint8_t field_type = this->fields_[this->field_idx_].datatype;
621 for (vtkIdType cp = 0; cp < nr_points; ++cp, point_offset += point_step) {
623 if (x_channel_idx != -1 && !
isXYZFiniteAt(*this->cloud_, cp)) {
628 const std::uint8_t* pt_data = &p_data[point_offset];
630 colors[pt_idx] = point_field_as<float>(pt_data, field_type);
637 scalars->SetArray(colors, pt_idx, 0, vtkFloatArray::VTK_DATA_ARRAY_DELETE);
static std::size_t size()
Get the number of colors in the lookup table.
static RGB at(std::size_t color_id)
Get a color from the lookup table with a given id.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
PointCloudColorHandlerGenericField(const PointCloudConstPtr &cloud, const std::string &field_name)
constructor
std::string getFieldName() const override
Get the name of the field used.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
PointCloudColorHandlerHSVField(const PointCloudConstPtr &cloud)
Constructor.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
int v_field_idx_
The field index for "V".
int s_field_idx_
The field index for "S".
Base Handler class for PointCloud colors.
bool capable_
True if this handler is capable of handling the input data, false otherwise.
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
typename PointCloud::ConstPtr PointCloudConstPtr
std::vector< pcl::PCLPointField > fields_
The list of fields available for this PointCloud.
int field_idx_
The index of the field holding the data that represents the color.
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Set the input cloud to be used.
vtkSmartPointer< vtkDataArray > getColor() const override
Obtain the actual color for the input dataset as a VTK data array.
float distance(const PointT &p1, const PointT &p2)
int getPointStep(const CloudT &)
PCL_EXPORTS void getRandomColors(double &r, double &g, double &b, double min=0.2, double max=2.8)
Get (good) random values for R/G/B.
const std::uint8_t * getCloudData(const CloudT &cloud)
bool isXYZFiniteAt(const CloudT &cloud, int index)
static int getFieldIndex(const std::string &field_name, const std::vector< pcl::PCLPointField > &fields)
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...
void getFields(const pcl::PointCloud< PointT > &, std::vector< pcl::PCLPointField > &fields)
constexpr bool isXYZFinite(const PointT &) noexcept
Defines all the PCL and non-PCL macros used.
std::vector<::pcl::PCLPointField > fields
std::vector< std::uint8_t > data
A point structure representing Euclidean xyz coordinates.
A point structure representing Euclidean xyz coordinates, and the RGB color.
A structure representing RGB color information.