30 #include <OgreColourValue.h>
31 #include <OgreMatrix4.h>
49 value = std::min(value, 1.0
f);
50 value = std::max(value, 0.0
f);
52 float h = value * 5.0f + 1.0f;
60 color[0] = n, color[1] = 0, color[2] = 1;
62 color[0] = 0, color[1] = n, color[2] = 1;
64 color[0] = 0, color[1] = 1, color[2] = n;
66 color[0] = n, color[1] = 1, color[2] = 0;
68 color[0] = 1, color[1] = n, color[2] = 0;
84 const Ogre::Matrix4& ,
110 const uint32_t offset = cloud->fields[index].offset;
111 const uint8_t type = cloud->fields[index].datatype;
112 const uint32_t point_step = cloud->point_step;
113 const uint32_t num_points = cloud->width * cloud->height;
115 float min_intensity = 999999.0f;
116 float max_intensity = -999999.0f;
119 for (uint32_t i = 0; i < num_points; ++i)
121 float val = valueFromCloud<float>(cloud, offset, type, point_step, i);
122 min_intensity = std::min(val, min_intensity);
123 max_intensity = std::max(val, max_intensity);
126 min_intensity = std::max(-999999.0
f, min_intensity);
127 max_intensity = std::min(999999.0
f, max_intensity);
136 float diff_intensity = max_intensity - min_intensity;
137 if (diff_intensity == 0)
143 diff_intensity = 1e20;
150 for (uint32_t i = 0; i < num_points; ++i)
152 float val = valueFromCloud<float>(cloud, offset, type, point_step, i);
153 float value = 1.0 - (val - min_intensity) / diff_intensity;
163 for (uint32_t i = 0; i < num_points; ++i)
165 float val = valueFromCloud<float>(cloud, offset, type, point_step, i);
166 float normalized_intensity = (val - min_intensity) / diff_intensity;
167 normalized_intensity = std::min(1.0
f, std::max(0.0
f, normalized_intensity));
168 points_out[i].color.r =
169 max_color.r * normalized_intensity + min_color.r * (1.0f - normalized_intensity);
170 points_out[i].color.g =
171 max_color.g * normalized_intensity + min_color.g * (1.0f - normalized_intensity);
172 points_out[i].color.b =
173 max_color.b * normalized_intensity + min_color.b * (1.0f - normalized_intensity);
182 QList<Property*>& out_props)
188 "Select the channel to use to compute the intensity", parent_property,
193 "Whether to use a rainbow of colors or interpolate between two",
196 new BoolProperty(
"Invert Rainbow",
false,
"Whether to invert rainbow colors", parent_property,
201 "Color to assign the points with the minimum intensity. "
202 "Actual color is interpolated between this and Max Color.",
204 &IntensityPCTransformer::IntensityPCTransformer::needRetransform,
this);
208 "Color to assign the points with the maximum intensity. "
209 "Actual color is interpolated between this and Min Color.",
211 &IntensityPCTransformer::IntensityPCTransformer::needRetransform,
this);
215 "Whether to automatically compute the intensity min/max values.",
221 "Minimum possible intensity value, used to interpolate from Min Color to Max Color for a point.",
225 "Max Intensity", 4096,
226 "Maximum possible intensity value, used to interpolate from Min Color to Max Color for a point.",
246 for (
size_t i = 0; i < cloud->fields.size(); ++i)
248 channels.push_back(cloud->fields[i].name);
250 std::sort(channels.begin(), channels.end());
255 for (V_string::const_iterator it = channels.begin(); it != channels.end(); ++it)
257 const std::string& channel = *it;
303 if (xi == -1 || yi == -1 || zi == -1)
308 if (cloud->fields[xi].datatype == sensor_msgs::PointField::FLOAT32)
318 const Ogre::Matrix4& ,
330 const uint32_t xoff = cloud->fields[xi].offset;
331 const uint32_t yoff = cloud->fields[yi].offset;
332 const uint32_t zoff = cloud->fields[zi].offset;
333 const uint32_t point_step = cloud->point_step;
334 uint8_t
const* point_x = &cloud->data.front() + xoff;
335 uint8_t
const* point_y = &cloud->data.front() + yoff;
336 uint8_t
const* point_z = &cloud->data.front() + zoff;
337 for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end();
338 ++iter, point_x += point_step, point_y += point_step, point_z += point_step)
340 iter->position.x = *
reinterpret_cast<const float*
>(point_x);
341 iter->position.y = *
reinterpret_cast<const float*
>(point_y);
342 iter->position.z = *
reinterpret_cast<const float*
>(point_z);
356 if (cloud->fields[index].datatype == sensor_msgs::PointField::INT32 ||
357 cloud->fields[index].datatype == sensor_msgs::PointField::UINT32 ||
358 cloud->fields[index].datatype == sensor_msgs::PointField::FLOAT32)
368 const Ogre::Matrix4& ,
378 const int32_t index = std::max(rgb, rgba);
380 const uint32_t off = cloud->fields[index].offset;
381 uint8_t
const* rgb_ptr = &cloud->data.front() + off;
382 const uint32_t point_step = cloud->point_step;
386 for (
int i = 0; i < 256; ++i)
388 rgb_lut[i] = float(i) / 255.0f;
392 for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end();
393 ++iter, rgb_ptr += point_step)
395 uint32_t rgb = *
reinterpret_cast<const uint32_t*
>(rgb_ptr);
396 iter->color.r = rgb_lut[(rgb >> 16) & 0xff];
397 iter->color.g = rgb_lut[(rgb >> 8) & 0xff];
398 iter->color.b = rgb_lut[rgb & 0xff];
399 iter->color.a = 1.0f;
404 for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end();
405 ++iter, rgb_ptr += point_step)
407 uint32_t rgb = *
reinterpret_cast<const uint32_t*
>(rgb_ptr);
408 iter->color.r = rgb_lut[(rgb >> 16) & 0xff];
409 iter->color.g = rgb_lut[(rgb >> 8) & 0xff];
410 iter->color.b = rgb_lut[rgb & 0xff];
411 iter->color.a = rgb_lut[rgb >> 24];
420 const Ogre::Matrix4& ,
430 const int32_t index = std::max(rgb, rgba);
432 const uint32_t off = cloud->fields[index].offset;
433 uint8_t
const* rgb_ptr = &cloud->data.front() + off;
434 const uint32_t point_step = cloud->point_step;
438 for (
int i = 0; i < 256; ++i)
440 rgb_lut[i] = float(i) / 255.0f;
444 for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end();
445 ++iter, rgb_ptr += point_step)
447 uint32_t rgb = *
reinterpret_cast<const uint32_t*
>(rgb_ptr);
448 float r = rgb_lut[(rgb >> 16) & 0xff];
449 float g = rgb_lut[(rgb >> 8) & 0xff];
450 float b = rgb_lut[rgb & 0xff];
451 float mono = 0.2989 * r + 0.5870 * g + 0.1140 * b;
452 iter->color.r = iter->color.g = iter->color.b = mono;
453 iter->color.a = 1.0f;
458 for (V_PointCloudPoint::iterator iter = points_out.begin(); iter != points_out.end();
459 ++iter, rgb_ptr += point_step)
461 uint32_t rgb = *
reinterpret_cast<const uint32_t*
>(rgb_ptr);
462 float r = rgb_lut[(rgb >> 16) & 0xff];
463 float g = rgb_lut[(rgb >> 8) & 0xff];
464 float b = rgb_lut[rgb & 0xff];
465 float mono = 0.2989 * r + 0.5870 * g + 0.1140 * b;
466 iter->color.r = iter->color.g = iter->color.b = mono;
467 iter->color.a = rgb_lut[rgb >> 24];
479 if (ri == -1 || gi == -1 || bi == -1)
484 if (cloud->fields[ri].datatype == sensor_msgs::PointField::FLOAT32)
494 const Ogre::Matrix4& ,
506 const uint32_t roff = cloud->fields[ri].offset;
507 const uint32_t goff = cloud->fields[gi].offset;
508 const uint32_t boff = cloud->fields[bi].offset;
509 const uint32_t point_step = cloud->point_step;
510 const uint32_t num_points = cloud->width * cloud->height;
511 uint8_t
const* point = &cloud->data.front();
512 for (uint32_t i = 0; i < num_points; ++i, point += point_step)
514 float r = *
reinterpret_cast<const float*
>(point + roff);
515 float g = *
reinterpret_cast<const float*
>(point + goff);
516 float b = *
reinterpret_cast<const float*
>(point + boff);
517 points_out[i].color = Ogre::ColourValue(r, g, b);
535 const Ogre::Matrix4& ,
545 const uint32_t num_points = cloud->width * cloud->height;
546 for (uint32_t i = 0; i < num_points; ++i)
548 points_out[i].color = color;
556 QList<Property*>& out_props)
578 const Ogre::Matrix4& transform,
590 const uint32_t xoff = cloud->fields[xi].offset;
591 const uint32_t yoff = cloud->fields[yi].offset;
592 const uint32_t zoff = cloud->fields[zi].offset;
593 const uint32_t point_step = cloud->point_step;
594 const uint32_t num_points = cloud->width * cloud->height;
595 uint8_t
const* point = &cloud->data.front();
599 std::vector<float>
values;
600 values.reserve(num_points);
604 for (uint32_t i = 0; i < num_points; ++i, point += point_step)
609 pos.x = *
reinterpret_cast<const float*
>(point + xoff);
610 pos.y = *
reinterpret_cast<const float*
>(point + yoff);
611 pos.z = *
reinterpret_cast<const float*
>(point + zoff);
614 values.push_back(pos[axis]);
619 const uint32_t offsets[3] = {xoff, yoff, zoff};
620 const uint32_t off = offsets[axis];
621 for (uint32_t i = 0; i < num_points; ++i, point += point_step)
623 values.push_back(*
reinterpret_cast<const float*
>(point + off));
626 float min_value_current = 9999.0f;
627 float max_value_current = -9999.0f;
630 for (uint32_t i = 0; i < num_points; i++)
633 min_value_current = std::min(min_value_current, val);
634 max_value_current = std::max(max_value_current, val);
645 float range = max_value_current - min_value_current;
650 for (uint32_t i = 0; i < num_points; ++i)
652 float value = 1.0 - (
values[i] - min_value_current) / range;
661 QList<Property*>& out_props)
673 "Whether to automatically compute the value min/max values.", parent_property,
678 "Minimum value value, used to interpolate the color of a point.",
683 "Maximum value value, used to interpolate the color of a point.",
687 "Use Fixed Frame",
true,
688 "Whether to color the cloud based on its fixed frame position or its local frame position.",