pcl库学习记录1-生成PointXYZRGB类型的点云

本例子以椭圆为例,具体代码参考自:《点云库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;
}

--------------------------------------------------------------------------------------有错误的地方请大家批评指正!

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的示例代码,用于将无序点云转换为有序点云,并根据输入像素坐标切割生成新的点云。该示例使用了 PCL 中的 VoxelGrid 过滤器来对点云进行下采样,以减少计算量。 ```cpp #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/filters/voxel_grid.h> #include <pcl/kdtree/kdtree_flann.h> #include <pcl/features/normal_3d.h> #include <pcl/surface/gp3.h> #include <pcl/visualization/pcl_visualizer.h> typedef pcl::PointXYZRGB PointT; typedef pcl::PointCloud<PointT> PointCloud; int main(int argc, char** argv) { // 读取点云数据 PointCloud::Ptr cloud(new PointCloud); if (pcl::io::loadPCDFile<PointT>("input_cloud.pcd", *cloud) == -1) { std::cerr << "Could not read input cloud file." << std::endl; return -1; } // 下采样点云 pcl::VoxelGrid<PointT> vg; vg.setInputCloud(cloud); vg.setLeafSize(0.01f, 0.01f, 0.01f); PointCloud::Ptr cloud_filtered(new PointCloud); vg.filter(*cloud_filtered); // 计算法线 pcl::NormalEstimation<PointT, pcl::Normal> ne; ne.setInputCloud(cloud_filtered); pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>); ne.setSearchMethod(tree); pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>); ne.setRadiusSearch(0.03); ne.compute(*cloud_normals); // 合并点云和法线 pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); pcl::concatenateFields(*cloud_filtered, *cloud_normals, *cloud_with_normals); // 创建搜索树 pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>); tree2->setInputCloud(cloud_with_normals); // 定义并计算三角化对象 pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3; pcl::PolygonMesh triangles; gp3.setSearchRadius(0.025); gp3.setMu(2.5); gp3.setMaximumNearestNeighbors(100); gp3.setMaximumSurfaceAngle(M_PI / 4); gp3.setMinimumAngle(M_PI / 18); gp3.setMaximumAngle(2 * M_PI / 3); gp3.setNormalConsistency(false); gp3.setInputCloud(cloud_with_normals); gp3.setSearchMethod(tree2); gp3.reconstruct(triangles); // 可视化结果 pcl::visualization::PCLVisualizer viewer("Point Cloud Viewer"); viewer.setBackgroundColor(0, 0, 0); viewer.addPolygonMesh(triangles, "triangles"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "triangles"); viewer.addCoordinateSystem(0.1); viewer.initCameraParameters(); // 根据输入像素坐标切割生成新的点云 int pixel_x = 100; int pixel_y = 200; float fx = 525.0f; // 相机内参 fx float fy = 525.0f; // 相机内参 fy float cx = 319.5f; // 相机内参 cx float cy = 239.5f; // 相机内参 cy float depth = 1.0f; // 输入深度值 float x = (pixel_x - cx) * depth / fx; float y = (pixel_y - cy) * depth / fy; float z = depth; pcl::PointXYZRGB new_point; new_point.x = x; new_point.y = y; new_point.z = z; new_point.r = 255; new_point.g = 255; new_point.b = 255; PointCloud::Ptr new_cloud(new PointCloud); new_cloud->push_back(new_point); // 显示新的点云 pcl::visualization::PointCloudColorHandlerRGBField<PointT> rgb(new_cloud); viewer.addPointCloud<PointT>(new_cloud, rgb, "new_cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "new_cloud"); viewer.spin(); return 0; } ``` 在上面的代码中,我们首先读取了一个无序点云文件(`input_cloud.pcd`),然后使用 VoxelGrid 过滤器对点云进行下采样,计算法线,并将点云和法线合并到一个新的点云中。接下来,我们使用 GreedyProjectionTriangulation 对象计算三角化,并可视化结果。最后,我们根据给定的输入像素坐标生成一个新的点云,并将其添加到可视化窗口中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值