Skip to content

Commit

Permalink
Fix default alpha values for and ASCII writer for point clouds
Browse files Browse the repository at this point in the history
This includes:
- Save RGB as integer for all point types.
- Change default alpha value to 255.
- Adjust tests to new alpha values.
- Print rgb values as ints in streaming operators.
  • Loading branch information
stefanbuettner authored and Stefan Buettner committed Dec 17, 2015
1 parent 14d7e10 commit 7530b36
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 29 deletions.
18 changes: 11 additions & 7 deletions common/include/pcl/impl/point_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ namespace pcl

inline RGB ()
{
r = g = b = a = 0;
r = g = b = 0;
a = 255;
}

friend std::ostream& operator << (std::ostream& os, const RGB& p);
Expand Down Expand Up @@ -614,7 +615,8 @@ namespace pcl
{
x = y = z = 0.0f;
data[3] = 1.0f;
r = g = b = a = 0;
r = g = b = 0;
a = 255;
}
inline PointXYZRGB (uint8_t _r, uint8_t _g, uint8_t _b)
{
Expand All @@ -623,7 +625,7 @@ namespace pcl
r = _r;
g = _g;
b = _b;
a = 0;
a = 255;
}

friend std::ostream& operator << (std::ostream& os, const PointXYZRGB& p);
Expand All @@ -646,7 +648,7 @@ namespace pcl
x = y = z = 0.0f;
data[3] = 1.0f;
r = g = b = 0;
a = 0;
a = 255;
label = 255;
}
inline PointXYZRGBL (uint8_t _r, uint8_t _g, uint8_t _b, uint32_t _label)
Expand All @@ -656,7 +658,7 @@ namespace pcl
r = _r;
g = _g;
b = _b;
a = 0;
a = 255;
label = _label;
}

Expand Down Expand Up @@ -934,7 +936,8 @@ namespace pcl
{
x = y = z = 0.0f;
data[3] = 1.0f;
r = g = b = a = 0;
r = g = b = 0;
a = 255;
normal_x = normal_y = normal_z = data_n[3] = 0.0f;
curvature = 0;
}
Expand Down Expand Up @@ -1587,7 +1590,8 @@ namespace pcl
x = y = z = 0.0f;
data[3] = 1.0f;
normal_x = normal_y = normal_z = data_n[3] = 0.0f;
rgba = 0;
r = g = b = 0;
a = 255;
radius = confidence = curvature = 0.0f;
}

Expand Down
21 changes: 14 additions & 7 deletions common/src/point_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ namespace pcl
std::ostream&
operator << (std::ostream& os, const PointXYZRGBL& p)
{
os << "(" << p.x << "," << p.y << "," << p.z << " - " << p.r << "," << p.g << "," << p.b << " - " << p.label << ")";
os << "(" << p.x << "," << p.y << "," << p.z << " - "
<< static_cast<int>(p.r) << ","
<< static_cast<int>(p.g) << ","
<< static_cast<int>(p.b) << " - "
<< p.label << ")";
return (os);
}

Expand Down Expand Up @@ -178,7 +182,11 @@ namespace pcl
std::ostream&
operator << (std::ostream& os, const PointXYZRGBNormal& p)
{
os << "(" << p.x << "," << p.y << "," << p.z << " - " << p.rgb << " - " << p.normal[0] << "," << p.normal[1] << "," << p.normal[2] << " - " << p.r << ", " << p.g << ", " << p.b << " - " << p.curvature << ")";
os << "(" << p.x << "," << p.y << "," << p.z << " - "<< p.rgb << " - " << p.normal[0] << "," << p.normal[1] << "," << p.normal[2] << " - "
<< static_cast<int>(p.r) << ", "
<< static_cast<int>(p.g) << ", "
<< static_cast<int>(p.b) << " - "
<< p.curvature << ")";
return (os);
}

Expand Down Expand Up @@ -408,14 +416,13 @@ namespace pcl
std::ostream&
operator << (std::ostream& os, const PointSurfel& p)
{
const unsigned char* rgba_ptr = reinterpret_cast<const unsigned char*>(&p.rgba);
os <<
"(" << p.x << "," << p.y << "," << p.z << " - " <<
p.normal_x << "," << p.normal_y << "," << p.normal_z << " - "
<< static_cast<int>(*rgba_ptr) << ","
<< static_cast<int>(*(rgba_ptr+1)) << ","
<< static_cast<int>(*(rgba_ptr+2)) << ","
<< static_cast<int>(*(rgba_ptr+3)) << " - " <<
<< static_cast<int>(p.r) << ","
<< static_cast<int>(p.g) << ","
<< static_cast<int>(p.b) << ","
<< static_cast<int>(p.a) << " - " <<
p.radius << " - " << p.confidence << " - " << p.curvature << ")";
return (os);
}
Expand Down
60 changes: 49 additions & 11 deletions io/include/pcl/io/impl/pcd_io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ pcl::PCDWriter::generateHeader (const pcl::PointCloud<PointT> &cloud, const int
// Add the regular dimension
field_names << " " << fields[i].name;
field_sizes << " " << pcl::getFieldSize (fields[i].datatype);
field_types << " " << pcl::getFieldType (fields[i].datatype);
if ("rgb" == fields[i].name)
field_types << " " << "U";
else
field_types << " " << pcl::getFieldType (fields[i].datatype);
int count = abs (static_cast<int> (fields[i].count));
if (count == 0) count = 1; // check for 0 counts (coming from older converter code)
field_counts << " " << count;
Expand Down Expand Up @@ -576,12 +579,30 @@ pcl::PCDWriter::writeASCII (const std::string &file_name, const pcl::PointCloud<
}
case pcl::PCLPointField::FLOAT32:
{
float value;
memcpy (&value, reinterpret_cast<const char*> (&cloud.points[i]) + fields[d].offset + c * sizeof (float), sizeof (float));
if (pcl_isnan (value))
stream << "nan";
/*
* Despite the float type, store the rgb field as uint32
* because several fully opaque color values are mapped to
* nan.
*/
if ("rgb" == fields[d].name)
{
uint32_t value;
memcpy (&value, reinterpret_cast<const char*> (&cloud.points[i]) + fields[d].offset + c * sizeof (float), sizeof (float));
if (pcl_isnan (value))
stream << "nan";
else
stream << boost::numeric_cast<uint32_t>(value);
break;
}
else
stream << boost::numeric_cast<float>(value);
{
float value;
memcpy (&value, reinterpret_cast<const char*> (&cloud.points[i]) + fields[d].offset + c * sizeof (float), sizeof (float));
if (pcl_isnan (value))
stream << "nan";
else
stream << boost::numeric_cast<float>(value);
}
break;
}
case pcl::PCLPointField::FLOAT64:
Expand Down Expand Up @@ -877,12 +898,29 @@ pcl::PCDWriter::writeASCII (const std::string &file_name,
}
case pcl::PCLPointField::FLOAT32:
{
float value;
memcpy (&value, reinterpret_cast<const char*> (&cloud.points[indices[i]]) + fields[d].offset + c * sizeof (float), sizeof (float));
if (pcl_isnan (value))
stream << "nan";
/*
* Despite the float type, store the rgb field as uint32
* because several fully opaque color values are mapped to
* nan.
*/
if ("rgb" == fields[i].name)
{
uint32_t value;
memcpy (&value, reinterpret_cast<const char*> (&cloud.points[indices[i]]) + fields[d].offset + c * sizeof (float), sizeof (float));
if (pcl_isnan (value))
stream << "nan";
else
stream << boost::numeric_cast<uint32_t>(value);
}
else
stream << boost::numeric_cast<float>(value);
{
float value;
memcpy (&value, reinterpret_cast<const char*> (&cloud.points[indices[i]]) + fields[d].offset + c * sizeof (float), sizeof (float));
if (pcl_isnan (value))
stream << "nan";
else
stream << boost::numeric_cast<float>(value);
}
break;
}
case pcl::PCLPointField::FLOAT64:
Expand Down
24 changes: 21 additions & 3 deletions io/src/pcd_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,11 +1105,21 @@ pcl::PCDWriter::generateHeaderASCII (const pcl::PCLPointCloud2 &cloud,
{
// Ignore invalid padded dimensions that are inherited from binary data
if (cloud.fields[d].name != "_")
stream << pcl::getFieldType (cloud.fields[d].datatype) << " ";
{
if (cloud.fields[d].name == "rgb")
stream << "U ";
else
stream << pcl::getFieldType (cloud.fields[d].datatype) << " ";
}
}
// Ignore invalid padded dimensions that are inherited from binary data
if (cloud.fields[cloud.fields.size () - 1].name != "_")
stream << pcl::getFieldType (cloud.fields[cloud.fields.size () - 1].datatype);
{
if (cloud.fields[cloud.fields.size () - 1].name == "rgb")
stream << "U";
else
stream << pcl::getFieldType (cloud.fields[cloud.fields.size () - 1].datatype);
}

// Remove trailing spaces
result = stream.str ();
Expand Down Expand Up @@ -1370,7 +1380,15 @@ pcl::PCDWriter::writeASCII (const std::string &file_name, const pcl::PCLPointClo
}
case pcl::PCLPointField::FLOAT32:
{
copyValueString<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type>(cloud, i, point_size, d, c, stream);
/*
* Despite the float type, store the rgb field as uint32
* because several fully opaque color values are mapped to
* nan.
*/
if ("rgb" == cloud.fields[d].name)
copyValueString<pcl::traits::asType<pcl::PCLPointField::UINT32>::type>(cloud, i, point_size, d, c, stream);
else
copyValueString<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type>(cloud, i, point_size, d, c, stream);
break;
}
case pcl::PCLPointField::FLOAT64:
Expand Down
2 changes: 1 addition & 1 deletion test/common/test_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ TEST (PCL, CopyIfFieldExists)
pcl::for_each_type<FieldList> (CopyIfFieldExists<PointXYZRGBNormal, float> (p, "rgb", is_rgb, rgb_val));
EXPECT_EQ (is_rgb, true);
int rgb = *reinterpret_cast<int*>(&rgb_val);
EXPECT_EQ (rgb, 8339710); // alpha is 0
EXPECT_EQ (rgb, 0xff7f40fe); // alpha is 255
pcl::for_each_type<FieldList> (CopyIfFieldExists<PointXYZRGBNormal, float> (p, "normal_x", is_normal_x, normal_x_val));
EXPECT_EQ (is_normal_x, true);
EXPECT_EQ (normal_x_val, 1.0);
Expand Down

0 comments on commit 7530b36

Please sign in to comment.