Skip to content

Commit

Permalink
Changed the Glasbey Color Lookup, such that label ids get consisten c…
Browse files Browse the repository at this point in the history
…olor.

This is especially important, if labels have a semantic meaning (class) (say 1=chair, 2=door, 3=floor, 4=wall ).
If a chair is missing in a pointcloud (label 1 is absent) than the colors of all objects would change.
Additionally, it is much faster, since we do not iterate through clouds multiple times as well as saving time on various map lo
  • Loading branch information
Markus Schoeler committed Feb 24, 2015
1 parent f529736 commit e3c4106
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -522,24 +522,27 @@ pcl::visualization::PointCloudColorHandlerLabelField<PointT>::getColor (vtkSmart
reinterpret_cast<vtkUnsignedCharArray*> (&(*scalars))->SetNumberOfTuples (nr_points);
unsigned char* colors = reinterpret_cast<vtkUnsignedCharArray*> (&(*scalars))->GetPointer (0);

std::set<uint32_t> labels;
std::map<uint32_t, pcl::RGB> colormap;

// First pass: find unique labels
for (vtkIdType i = 0; i < nr_points; ++i)
labels.insert (cloud_->points[i].label);

// Assign Glasbey colors in ascending order of labels
size_t color = 0;
for (std::set<uint32_t>::iterator iter = labels.begin (); iter != labels.end (); ++iter, ++color)
colormap[*iter] = GlasbeyLUT::at (color % GlasbeyLUT::size ());
std::map<uint32_t, pcl::RGB> colormap;
if (!static_mapping_)
{
std::set<uint32_t> labels;
// First pass: find unique labels
for (vtkIdType i = 0; i < nr_points; ++i)
labels.insert (cloud_->points[i].label);

// Assign Glasbey colors in ascending order of labels
size_t color = 0;
for (std::set<uint32_t>::iterator iter = labels.begin (); iter != labels.end (); ++iter, ++color)
colormap[*iter] = GlasbeyLUT::at (color % GlasbeyLUT::size ());
}

int j = 0;
for (vtkIdType cp = 0; cp < nr_points; ++cp)
{
if (pcl::isFinite (cloud_->points[cp]))
{
const pcl::RGB& color = colormap[cloud_->points[cp].label];
const pcl::RGB& color = static_mapping_ ? GlasbeyLUT::at (cloud_->points[cp].label % GlasbeyLUT::size ()) : colormap[cloud_->points[cp].label];
colors[j ] = color.r;
colors[j + 1] = color.g;
colors[j + 2] = color.b;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,17 +512,23 @@ namespace pcl
typedef boost::shared_ptr<PointCloudColorHandlerLabelField<PointT> > Ptr;
typedef boost::shared_ptr<const PointCloudColorHandlerLabelField<PointT> > ConstPtr;

/** \brief Constructor. */
PointCloudColorHandlerLabelField ()
/** \brief Constructor.
* \param[in] static_mapping Use a static colormapping from label_id to color (default false) */
PointCloudColorHandlerLabelField (const bool static_mapping = false)
: PointCloudColorHandler<PointT> ()
{
capable_ = false;
static_mapping_ = static_mapping;
}

/** \brief Constructor. */
PointCloudColorHandlerLabelField (const PointCloudConstPtr &cloud)
/** \brief Constructor.
* \param[in] static_mapping Use a static colormapping from label_id to color (default false) */
PointCloudColorHandlerLabelField (const PointCloudConstPtr &cloud,
const bool static_mapping = false)
: PointCloudColorHandler<PointT> (cloud)
{
setInputCloud (cloud);
static_mapping_ = static_mapping;
}

/** \brief Destructor. */
Expand Down Expand Up @@ -557,6 +563,7 @@ namespace pcl
using PointCloudColorHandler<PointT>::capable_;
using PointCloudColorHandler<PointT>::field_idx_;
using PointCloudColorHandler<PointT>::fields_;
bool static_mapping_;
};

//////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -906,8 +913,10 @@ namespace pcl
typedef boost::shared_ptr<PointCloudColorHandlerLabelField<PointCloud> > Ptr;
typedef boost::shared_ptr<const PointCloudColorHandlerLabelField<PointCloud> > ConstPtr;

/** \brief Constructor. */
PointCloudColorHandlerLabelField (const PointCloudConstPtr &cloud);
/** \brief Constructor.
* \param[in] static_mapping Use a static colormapping from label_id to color (default false) */
PointCloudColorHandlerLabelField (const PointCloudConstPtr &cloud,
const bool static_mapping = false);

/** \brief Empty destructor */
virtual ~PointCloudColorHandlerLabelField () {}
Expand All @@ -928,6 +937,8 @@ namespace pcl
/** \brief Get the name of the field used. */
virtual std::string
getFieldName () const { return ("label"); }
private:
bool static_mapping_;
};

}
Expand Down
38 changes: 20 additions & 18 deletions visualization/src/point_cloud_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,15 +584,16 @@ pcl::visualization::PointCloudColorHandlerRGBAField<pcl::PCLPointCloud2>::getCol
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2>::PointCloudColorHandlerLabelField (
const pcl::visualization::PointCloudColorHandler<pcl::PCLPointCloud2>::PointCloudConstPtr &cloud)
pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2>::PointCloudColorHandlerLabelField (const pcl::visualization::PointCloudColorHandler<pcl::PCLPointCloud2>::PointCloudConstPtr &cloud,
const bool static_mapping)
: pcl::visualization::PointCloudColorHandler<pcl::PCLPointCloud2>::PointCloudColorHandler (cloud)
{
field_idx_ = pcl::getFieldIndex (*cloud, "label");
if (field_idx_ != -1)
capable_ = true;
else
capable_ = false;
static_mapping_ = static_mapping;
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -615,22 +616,24 @@ pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2>::getCo
int point_offset = cloud_->fields[field_idx_].offset;
const int field_size = pcl::getFieldSize (cloud_->fields[field_idx_].datatype);

std::set<uint32_t> labels;
std::map<uint32_t, pcl::RGB> colormap;

// First pass: find unique labels
for (vtkIdType i = 0; i < nr_points; ++i, point_offset += cloud_->point_step)
std::map<uint32_t, pcl::RGB> colormap;
if (!static_mapping_)
{
uint32_t label;
memcpy (&label, &cloud_->data[point_offset], field_size);
labels.insert (label);
}

// Assign Glasbey colors in ascending order of labels
size_t color = 0;
for (std::set<uint32_t>::iterator iter = labels.begin (); iter != labels.end (); ++iter, ++color)
colormap[*iter] = GlasbeyLUT::at (color % GlasbeyLUT::size ());
std::set<uint32_t> labels;
// First pass: find unique labels
for (vtkIdType i = 0; i < nr_points; ++i, point_offset += cloud_->point_step)
{
uint32_t label;
memcpy (&label, &cloud_->data[point_offset], field_size);
labels.insert (label);
}

// Assign Glasbey colors in ascending order of labels
size_t color = 0;
for (std::set<uint32_t>::iterator iter = labels.begin (); iter != labels.end (); ++iter, ++color)
colormap[*iter] = GlasbeyLUT::at (color % GlasbeyLUT::size ());
}
// If XYZ present, check if the points are invalid
int x_idx = pcl::getFieldIndex (*cloud_, "x");
point_offset = cloud_->fields[field_idx_].offset;
Expand All @@ -653,8 +656,7 @@ pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2>::getCo

if (!pcl_isfinite (x_data) || !pcl_isfinite (y_data) || !pcl_isfinite (z_data))
continue;

const pcl::RGB& color = colormap[label];
const pcl::RGB& color = static_mapping_ ? GlasbeyLUT::at (label % GlasbeyLUT::size ()) : colormap[label];
colors[j ] = color.r;
colors[j + 1] = color.g;
colors[j + 2] = color.b;
Expand All @@ -669,7 +671,7 @@ pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2>::getCo
{
uint32_t label;
memcpy (&label, &cloud_->data[point_offset], field_size);

// const pcl::RGB& color = GlasbeyLUT::at (label % GlasbeyLUT::size ());
const pcl::RGB& color = colormap[label];
colors[j ] = color.r;
colors[j + 1] = color.g;
Expand Down
8 changes: 7 additions & 1 deletion visualization/tools/pcd_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ printHelp (int, char **argv)
print_info ("\n");
print_info (" -use_point_picking = enable the usage of picking points on screen (default "); print_value ("disabled"); print_info (")\n");
print_info ("\n");
print_info (" -optimal_label_colors = maps existing labels to the optimal sequential glasbey colors, label_ids will not be mapped to fixed colors (default "); print_value ("disabled"); print_info (")\n");
print_info ("\n");

print_info ("\n(Note: for multiple .pcd files, provide multiple -{fc,ps,opaque} parameters; they will be automatically assigned to the right file)\n");
}
Expand Down Expand Up @@ -277,6 +279,10 @@ main (int argc, char** argv)
if (use_pp)
print_highlight ("Point picking enabled.\n");

bool use_optimal_l_colors = pcl::console::find_switch (argc, argv, "-optimal_label_colors");
if (use_optimal_l_colors)
print_highlight ("Optimal glasbey colors are being assigned to existing labels.\nNote: No static mapping between label ids and colors\n");

// If VBOs are not enabled, then try to use immediate rendering
bool use_immediate_rendering = false;
if (!use_vbos)
Expand Down Expand Up @@ -602,7 +608,7 @@ main (int argc, char** argv)
else if (cloud->fields[f].name == "label")
{
label_idx = f + 1;
color_handler.reset (new pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2> (cloud));
color_handler.reset (new pcl::visualization::PointCloudColorHandlerLabelField<pcl::PCLPointCloud2> (cloud, !use_optimal_l_colors));
}
else
{
Expand Down

0 comments on commit e3c4106

Please sign in to comment.