本例子以椭圆为例,具体代码参考自:《点云库PCL从入门到精通》,郭浩 主编
关于椭圆沿着3个方向的坐标值x,y,z都很好理解,主要是通过椭圆的参数方程来赋值。
对于一个PointXYZRGB类型的点point,point.x,point.y,point.z都可以可以按照椭圆的参数方程来一次赋值。程序中,z取值[-1,1],采样间隔:0.05,共有40个。每个椭圆上边根据角度angel的采样间隔:5.0来控制,所以每个椭圆用73个点表示,共计73*40=2920个点。
关于point.rgb的每个颜色分量赋值问题:
首先将r,g,b每个分量打包为rgb:
typedef unsigned char uint8_t; typedef unsigned int uint32_t;
(std::uint32_t)r << 16 :将r左移16位,转为uint32_t类型;代码中就是将255,15,15的二进制表示分别左移16位、8位、8位,最后三者按位进行或运算。然后将rgb(第2行)的uint32_t的地址通过reinterpret_cast强制转为float*,所以代码第3行中可知rgb数据类型是一个float类型的。
// pack r/g/b into rgb
1,std::uint8_t r = 255, g = 15, b = 15; // Example: Red color
2,std::uint32_t rgb = ((std::uint32_t)r << 16 | (std::uint32_t)g << 8 | (std::uint32_t)b);
3,p.rgb = *reinterpret_cast<float*>(&rgb);
最终将改点保存为pcd文件中,rgb的值:6715535,
它对应的2进制正好是:1111 1111 0000 1111 0000 1111。
关于rgb提取分量的方法就不用过多解释也很清楚了。
PointXYZRGB p;
// unpack rgb into r/g/b
std::uint32_t rgb = *reinterpret_cast<int*>(&p.rgb);
std::uint8_t r = (rgb >> 16) & 0x0000ff;
std::uint8_t g = (rgb >> 8) & 0x0000ff;
std::uint8_t b = (rgb) & 0x0000ff;
#include <iostream>
#include <pcl/common/common_headers.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
int main(int argc,char** argv)
{
// 自行创建一随机点云
pcl::PointCloud<pcl::PointXYZ>::Ptr basic_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr (new pcl::PointCloud<pcl::PointXYZRGB>);
std::cout << "Genarating example point clouds.\n\n";
// 以椭圆为边线沿z轴拉伸获取其点云,并赋予红绿蓝渐变色。
uint8_t r(255), g(15), b(15);
for (float z(-1.0); z <= 1.0; z += 0.05)
{
for (float angle(0.0); angle <= 360.0; angle += 5.0)
{
pcl::PointXYZ basic_point;
basic_point.x = 0.5 * cosf (pcl::deg2rad(angle));
basic_point.y = sinf (pcl::deg2rad(angle));
basic_point.z = z;
basic_cloud_ptr->points.push_back(basic_point);
pcl::PointXYZRGB point;
point.x = basic_point.x;
point.y = basic_point.y;
point.z = basic_point.z;
uint32_t rgb = (static_cast<uint32_t>(r) << 16 |
static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));
point.rgb = *reinterpret_cast<float*>(&rgb);
point_cloud_ptr->points.push_back (point);
}
if (z < 0.0)
{
r -= 12;
g += 12;
}
else
{
g -= 12;
b += 12;
}
}
//点云显示
......
return 0;
}
--------------------------------------------------------------------------------------有错误的地方请大家批评指正!