1、什么是点云

点云是一个数据集,数据集中的每个点代表一组X、Y、Z几何坐标和一个强度值,这个强度值根据物体表面反射率记录返回信号的强度。当这些点组合在一起时,就会形成一个点云,即空间中代表3D形状或对象的数据点集合。点云也可以自动上色,以实现更真实的可视化。

2、点云的获取

生成点云的数据可以通过多种方式采集, 其中包括全站仪、地面和机载激光扫描仪、无人机、移动测绘系统、快照图像,从手簿中采集到的视频,还有智能手机和生成表面和结构模型的CAD程序。

3、点云数据的解析

点云体量可以大到超过数百GB,这需要强大的软件来进行高效的处理、分析和数据导出。数据安全存储和共享对于成功的项目协作也是必不可少的。这就是基于云的解决方案发挥作用的地方,它提供了可视化的便捷访问,并以富有成效的方式与点云进行交互。

4、点云的应用

点云可用于多个方向,包括可视化、动画、渲染和CAD建模。在地理空间工作流中,利用点云交付的成果可包括地形和测深地图、数字高程模型、数字地形模型、3D CAD和BIM模型、点云、图像浏览器以及动画和虚拟现实等。

精准的地理空间数据可以高效地利用在以下方面:

  • 监测及竣工验收
  • 建筑物、厂房及民用基础设施的重建或翻修
  • 在外部环境不受干扰的情况下对犯罪现场进行司法调查,呈现的证据允许在法庭上使用
  • 快速实现事故重建,大大减少道路封闭的时间
  • 文化遗产的保护和修复以及更多可能的应用

因此,从最基本的意义上说,点云是用数字化的方式对物理世界的真实表达,它在诸多应用中起到的作用是无与伦比的。

5、点云数据的特点

  • 无序性:只是点而已,排序顺序不受影响
  • 近密远梳:扫码与视角不同导致的
  • 非结构化数据:直接CNN比较难
  • 要解决的任务就是如果对点云数据信息特征提取
1
2
3
4
5
a.无序性:点云数据是点的集合,点之间进行相互调换,其自身带有的位置信息也就会随之进行改变,调换后和未调换前一致。

b.近密远疏:拍摄的距离近一些表示的点云很多稠密,远部分的则表示的很稀疏。如上图座椅的点云数据图所示。

c.点云数据是文本形式的,处理起来麻烦,也就是非结构化。

6、点云数据结构

  • 点云存储格式:*.pts; *.asc ; *.dat; .stl ; [1] .imw;.xyz;.las。LAS格式文件已成为LiDAR数据的工业标准格式,LAS文件按每条扫描线排列方式存放数据,包括激光点的三维坐标、多次回波信息、强度信息、扫描角度、分类信息、飞行航带信息、飞行姿态信息、项目信息、GPS信息、数据点颜色信息等。

img

1
2
3
4
5
6
7
8
C–class(所属类)
F一flight(航线号)
T一time(GPS时间)
I一intensity(回波强度)
R一return(第几次回波)
N一number of return(回波次数)
A一scan angle(扫描角)
RGB一red green blue(RGB颜色值)
  • 点云的数据类型

(1)pcl::PointCloudpcl::PointXYZ
PointXYZ 成员:float x,y,z;表示了xyz3D信息,可以通过points[i].data[0]或points[i].x访问点X的坐标值
(2)pcl::PointCloudpcl::PointXYZI
PointXYZI成员:float x, y, z, intensity; 表示XYZ信息加上强度信息的类型。
(3)pcl::PointCloudpcl::PointXYZRGB
PointXYZRGB 成员:float x,y,z,rgb; 表示XYZ信息加上RGB信息,RGB存储为一个float。
(4)pcl::PointCloudpcl::PointXYZRGBA
PointXYZRGBA 成员:float x , y, z; uint32_t rgba; 表示XYZ信息加上RGBA信息,RGBA用32bit的int型存储的。
(5) PointXY 成员:float x,y;简单的二维x-y点结构
(6)Normal结构体:表示给定点所在样本曲面上的法线方向,以及对应曲率的测量值,用第四个元素来占位,兼容SSE和高效计算。

7、基于C#操作点云数据

7.1 基于VTK和PCL搭建点云数据操作环境

    需引用Kitware.mummy.Runtime.dll,Kitware.VTK.dll,PclCSharp.dll,PointCloudSharpDll.dll

7.2 点云数据操作的UI界面添加点云控件并初始化

private RenderWindowControl renderWindowControl;

        // 创建VTK渲染点云数据控件对象
        renderWindowControl = new RenderWindowControl();
        // 设置控件已填充方式添加到父容器中
        renderWindowControl.Dock = DockStyle.Fill;
        // 将创建的控件对象添加到父容器中
        pl_container.Controls.Add(renderWindowControl);

7.3 加载点云的PCD文件及编写对应的代码

  // 创建XZY点云对象
 private PointCloudXYZ cloud = new PointCloudXYZ();

// 创建一个文件资源对话框对象
var dialog = new OpenFileDialog();
// 设置对话框能打开的类型
dialog.Filter = "点云文件|*.pcd";
// 编写标题
dialog.Title = "请选择点云文件";
// 判断是否打开对话框
if (dialog.ShowDialog() == DialogResult.OK)
{
    // 获取选择的点云文件的路径
    var url = dialog.FileName;
    // 加载pcd文件,并存储到了cloud的PointCloudXYZPointer
    Io.loadPcdFile(url, cloud.PointCloudXYZPointer);
    // 把点云数据进行渲染到控件中进行显示
    var render = RenderCloudData(cloud);
    // 获取点云控件上面的渲染窗体对象
    var renderWindow = renderWindowControl.RenderWindow;
    // 将渲染器添加到Render并渲染
    renderWindow.AddRenderer(render);
    // 刷新填充控件的容器
    pl_container.Refresh();
}

7.4 点云对象转换为vtkRender

/// <summary>
/// 处理点云对象中点云并返回对应渲染对象
/// </summary>
/// <param name="cloud"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private vtkRenderer RenderCloudData(PointCloudXYZ cloud)
{
    // 创建存cloud中xyz数据点云对象
    var points = vtkPoints.New();
    // 把点云对象中的点依次放入点云数据对象中
    for (int i = 0; i < cloud.Size; i++)
    {
        points.InsertNextPoint(cloud.GetX(i), cloud.GetY(i), cloud.GetZ(i));
    }
    //  创建每个点的属性属性,这里代表颜色
    var pclColor = SetPclDataColor(cloud);
    // 创建多数据对象
    var polyData = vtkPolyData.New();
    // 把points对象设置到多数据对象中
    polyData.SetPoints(points);
    // 设置颜色到对应点
    polyData.GetPointData().SetScalars(pclColor);
    // 创建过滤器
    var glyphFilter = vtkVertexGlyphFilter.New();
    // 连接多数据对象管道
    glyphFilter.SetInputConnection(polyData.GetProducerPort());
    // 创建制图器
    var mapper = vtkPolyDataMapper.New();
    // 设置缩放显示比例
    mapper.SetScalarVisibility(1);
    // 连接过滤器对象的管道
    mapper.SetInputConnection(glyphFilter.GetOutputPort());
    // 创建制图的角色
    var actor = vtkActor.New();
    // 设置制图器到对应角色中
    actor.SetMapper(mapper);
    // 创建渲染器对象
    var render = vtkRenderer.New();
    // 把角色添加到渲染器中
    render.AddActor(actor);
    // 设置viewport
    render.SetViewport(0,0,1,1);
    // 设置背景渐变
    render.GradientBackgroundOn();
    // 设置渐变的前景和背景
    render.SetBackground(0.2, 0.6, 0.3);
    render.SetBackground2(0.9,0.9,0.9);

    // 返回创建渲染对象
    return render;
}

7.5 显示点云模型问题及给点云数据着色

        /// <summary>
        /// 给点云数据xyz几何点着色
        /// </summary>
        /// <param name="cloud"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private vtkUnsignedCharArray SetPclDataColor(PointCloudXYZ cloud)
        {
            var color = vtkUnsignedCharArray.New();
            // 求点云数据各个轴对应极值
            var minMax = new double[6];
            cloud.GetMinMaxXYZ(minMax);
            // 求Z轴的差值
            double z = minMax[5] - minMax[4];
            // 求Z轴的差值
            double y = minMax[3] - minMax[2];
            // 求Z轴的差值
            double x = minMax[1] - minMax[0];
            // 求中间值
            double zMedian = z / 2;
            double yMedian = y / 2;
            double xMedian = x / 2;
            // 设置颜色分组,因为是rgb需要分给三组
            color.SetNumberOfComponents(3);
            double r = 0;
            double g = 0;
            double b = 0;
            for (int i = 0; i < cloud.Size; i++)
            {
                if (cloud.GetZ(i) - minMax[4] > zMedian)
                {
                    // 判断r,g,b值不能超过255
                    r = (255 * ((cloud.GetZ(i) - minMax[4] - zMedian) / zMedian));
                    g = (255 * (1 - ((cloud.GetZ(i) - minMax[4] - zMedian) / zMedian)));
                    b = 0;
                    color.InsertNextTuple3(r, g, b);
                }
                else
                {
                    r = 0;
                    g = (255 * ((cloud.GetZ(i) - minMax[4] - zMedian) / zMedian));
                    b = (255 * (1 - ((cloud.GetZ(i) - minMax[4] - zMedian) / zMedian))); ;
                    color.InsertNextTuple3(r, g, b);
                }
            }

            return color;
        }

 

posted on 2025-06-14 10:19  江渔湖  阅读(467)  评论(0)    收藏  举报