从pcl-1.9以后,保存的pcd文件中rgb字段是以uint来存储,而之前的版本都是用float形式来存储
分别在pcl-1.7.2版本和pcl-1.9版本环境下执行如下代码生成pcd文件
#include
#include
using PointT = pcl::PointXYZRGB;
int main(int argc, char** argv)
{
pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
for (int i=0; i<10; i++)
{
PointT p;
p.x = i;
p.y = i;
p.z = i;
p.r = i;
p.g = i;
p.b = i;
cloud->points.push_back(p);
}
cloud->width = cloud->points.size();
cloud->height = 1;
pcl::io::savePCDFile("/home/cn/temp_1_7.pcd", *cloud);
//pcl::io::savePCDFile("/home/cn/temp_1_9.pcd", *cloud);
return 0;
}
结果如下
cat temp_1_9.pcd
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F U
COUNT 1 1 1 1
WIDTH 10
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 10
DATA ascii
0 0 0 4278190080
1 1 1 4278255873
2 2 2 4278321666
3 3 3 4278387459
4 4 4 4278453252
5 5 5 4278519045
6 6 6 4278584838
7 7 7 4278650631
8 8 8 4278716424
9 9 9 4278782217
cat temp_1_7.pcd
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 10
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 10
DATA ascii
0 0 0 0
1 1 1 9.219563e-41
2 2 2 1.8439126e-40
3 3 3 2.7658689e-40
4 4 4 3.6878252e-40
5 5 5 4.6097815e-40
6 6 6 5.5317378e-40
7 7 7 6.4536941e-40
8 8 8 7.3756504e-40
9 9 9 8.2976067e-40
从上述结果可以看出pcl-1.7.2保存的pcd类型为TYPE F F F F,而pcl-1.9保存的pcd类型为TYPE F F F U,因此可得pcl的新版本对保存的pcd文件的rgb字段使用的是uint类型,而不再是传统的float类型.为何要更改保存的类型?原因如下:
pcl::PointXYZRGB结构使用注意事项:
* Due to historical reasons (PCL was first developed as a ROS package), the
* RGB information is packed into an integer and casted to a float. This is
* something we wish to remove in the near future
由于pcl库一开始是作为一个ros库,因此需要将以整形封装的rgb信息强转成float类型(ros的点云信息都是以float32类型保存的)
pcl::savePCDFile()接口使用注意事项:
* Caution: PointCloud structures containing an RGB field have
* traditionally used packed float values to store RGB data. Storing a
* float as ASCII can introduce variations to the smallest bits, and
* thus significantly alter the data. This is a known issue, and the fix
* involves switching RGB data to be stored as a packed integer in
* future versions of PCL.
如果直接保存为float类型,将会使最小的几位数据发生变化
更改保存的类型的原因:在进行uint与float之间的转换时,会引起数据的微小变化,改为uint之后将不再需要进行这两种类型之间的转换
直接根据点云保存的类型切换系统的pcl环境,如果点云rgb字段保存为float类型,则直接将pcl版本切换成pcl-1.9之前的版本,否则将pcl版本切换成pcl-1.9版本
系统的pcl版本一旦确定就很少去改动它,因为有很多先前的项目都是基于这个版本开发的,一旦改动版本,可能会出现"牵一发而动全身"问题,因此推荐直接对pcd文件进行更改,以适应系统的pcl版本.
将rgb字段uint类型转换为float类型:
#include
#include
#include
#include
#include
using PointT = pcl::PointXYZRGB;
using namespace std;
int main(int argc, char** argv)
{
ifstream in_file("temp_1_9.pcd");
if (!in_file){
cout<<"couldnt open file !!!!!!"< line_datas;
line_datas.clear();
while (ss >> tmp_value){
line_datas.push_back(tmp_value);
}
if (line_datas.size() != 4){
cout<<"line "<(line_datas[3]);
uint8_t r = (raw_rgb >> 16) & 0x0000ff;
uint8_t g = (raw_rgb >> 8) & 0x0000ff;
uint8_t b = (raw_rgb) & 0x0000ff;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
float cha_rgb = *reinterpret_cast(&rgb);
out_file<
结果:
cat 1_9_to_1_7.pcd
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 10
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 10
DATA ascii
0 0 0 0
1 1 1 9.21942e-41
2 2 2 1.84388e-40
3 3 3 2.76583e-40
4 4 4 3.68777e-40
5 5 5 4.60971e-40
6 6 6 5.53165e-40
7 7 7 6.4536e-40
8 8 8 7.37554e-40
9 9 9 8.29748e-40
与temp_1_7.pcd内容一致,转换成功.
将rgb字段float类型转换为uint类型:
#include
#include
#include
#include
#include
using PointT = pcl::PointXYZRGB;
using namespace std;
int main(int argc, char** argv)
{
ifstream in_file("temp_1_7.pcd");
if (!in_file){
cout<<"couldnt open file !!!!!!"< line_datas;
line_datas.clear();
while (ss >> tmp_value){
line_datas.push_back(tmp_value);
}
if (line_datas.size() != 4){
cout<<"line "<(&line_datas[3]);
uint8_t r = (raw_rgb >> 16) & 0x0000ff;
uint8_t g = (raw_rgb >> 8) & 0x0000ff;
uint8_t b = (raw_rgb) & 0x0000ff;
// highest Byte is 0xff
uint32_t cha_rgb = ((uint32_t)(0xff)) << 24 | ((uint32_t)r) << 16 | ((uint32_t)g) << 8 | ((uint32_t)b);
out_file<
结果
cat 1_7_to_1_9.pcd
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F U
COUNT 1 1 1 1
WIDTH 10
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 10
DATA ascii
0 0 0 4278190080
1 1 1 4278255873
2 2 2 4278321666
3 3 3 4278387459
4 4 4 4278453252
5 5 5 4278519045
6 6 6 4278584838
7 7 7 4278650631
8 8 8 4278716424
9 9 9 4278782217
与temp_1_9.pcd文件内容一致,转换成功.